[Cascavel-pm] agrupamento e seleção em DBI

Luis Motta Campos luismottacampos em yahoo.co.uk
Sexta Fevereiro 8 01:13:50 PST 2008


Rodrigo Fernandes wrote:
> --- Luis Motta Campos wrote:
> 
>> O que, exatamente, você está tentando fazer?
> 
> Ok, vou começar novamente, e que Apolo me ajude.
> 
> Tenho uma Tabela (ver abaixo), e desejo selecionar uma linha se e 
> somente se ela satisfaz simultanemante as seguintes condições:
> 
> (i) t ocorre em pelo menos outra linha (isto eu já faço, com o Código
>  1 (ver abaixo)). (ii) id_d = 10 ou id_d = 11 (isto eu faço com o 
> Código 2 (ver abaixo)).
> 
> Estou começando a pensar que não é possível satisfazer estas duas 
> condições em um único SELECT (mesmo que haja sub SELECTs embutidos). 
> Se for assim, tudo bem. Crio uma segunda tabela com o resultado de 
> (i) e, sobre esta, aplico (ii).
> 
> Ou seja, sendo o mais claro que consigo, gostaria de unir Código 1 e 
> Código 2 em um único SELECT

Quer dizer, mesmo que uma das referências do termo não esteja num dos
documentos citados (id_d IN (10, 11)), você conta este termo como
"duplicado" e quer que ele apareça, certo?

> Legenda (Não importa muito, mas...) id_d -> "identificação do
> documento" tficf_t -> "frequencia do termo e frequencia inversa da
> coleção de t" t -> "termo"

Claro que importa! Agora, eu sei do que a gente está falando, e o meu 
modelo fica mais claro e mais organizado: eu posso falar a mesma 
"linguagem" que você, e isso ajuda a "descomplicar" o modelo.

> Código 1
> 
> SELECT t, tficf_t, id_d FROM user WHERE t IN ( SELECT t FROM user 
> GROUP BY t HAVING COUNT(*) > 1 )
> 
> 
> Código 2 SELECT * FROM user WHERE id_d IN (10,11)

O que eu acho que você quer é

SELECT *
FROM (
     SELECT t       AS term
          , tficf_t AS inverse_frequency_of_t
          , id_d    AS document_id
     FROM user
     WHERE t IN (
         SELECT t
         FROM user
         GROUP BY t
         HAVING COUNT(*) > 1
     )
) AS duplicated_terms
WHERE document_id IN ( 10, 11 )

Outra forma de resolver o mesmo problema é

CREATE TEMPORARY TABLE duplicated_terms AS
     SELECT t       AS term
          , tficf_t AS inverse_frequency_of_t
          , id_d    AS document_id
     FROM user
     WHERE t IN (
         SELECT t
         FROM user
         GROUP BY t
         HAVING COUNT(*) > 1
     )
;

SELECT *
FROM duplicated_terms
WHERE document_id IN ( 10, 11 );

Eu acho esta segunda forma mais eficiente, já que você pode "reusar" o 
query que cria a TEMPORARY TABLE quantas vezes conseguir, desde que 
mantenha a conexão aberta.

Existem mais formas de fazer, mas todas elas são mais complicadas e 
difícieis de implementar. Se estas ajudarem, bem. Se não, volte a 
perguntar e eu vou continuar mandando SQL ;)

Putamplexos!
-- 
Luis Motta Campos (a.k.a. Monsieur Champs) is a software engineer,
Perl fanatic evangelist, and amateur {cook, photographer}


Mais detalhes sobre a lista de discussão Cascavel-pm