O que é uma instrução SQL para selecionar um item que tem vários atributos em uma lista de itens / atributo?

StackOverflow https://stackoverflow.com/questions/927724

Pergunta

Say Eu tenho uma tabela que tem itens e atributos listados como,

frog    green
cat     furry
frog    nice
cat     4 legs
frog    4 legs

A partir da coluna itens eu quero selecionar objetos únicos que têm tanto o verde e 4 atributo pernas. Eu esperaria para voltar apenas o objeto sapo neste caso. O que é a consulta mais eficiente de fazer isso?

Foi útil?

Solução

select  item.name 
from    item 
where   item.attribute in ('4 legs', 'green') 
group by item.name 
having  count(distinct item.attribute) = 2

Outras dicas

A maneira mais eficiente de fazer isso é com um auto-associação:

SELECT * FROM attributes a1 
JOIN attributes a2 USING (item_name) -- e.g. frog
WHERE a1.value = 'green' AND a2.value = '4 legs';

Outra solução que algumas pessoas usam é um truque com GROUP BY:

SELECT item_name FROM attributes
WHERE value IN ('4 legs', 'green')
GROUP BY item_name
HAVING COUNT(*) = 2;

Mas o GROUP BY solução pode não ser tão eficiente quanto um JOIN, dependendo de qual marca de RDBMS que você usa. Também um método pode dimensionar melhor como o volume em sua tabela cresce.

SELECT * FROM tabela onde coisa = 'sapo'

batidas nada saber exatamente o que você quer.

select
    item, count(*)
from
    @temp
where
    attribute in ('4 legs','green')
group by
    item
having
    count(*) = 2 -- this "2" needs to be replaced with however many attributes you have

Você também pode consultar cada atributo separadamente, e depois cruzam-los ...

/*
-- create sample table...
create table #temp1
    (item varchar(max),
    attrib varchar(max))

-- populate sample table (SQL 08)...
insert #temp1
values ('frog', 'green'), ('cat', 'furry'), ('frog', 'nice'), ('cat', '4 legs'), ('frog', '4 legs')
*/


SELECT  item
FROM    #temp1
WHERE   attrib = 'green'
INTERSECT
SELECT  item
FROM    #temp1
WHERE   attrib = '4 legs'

criar duas tabelas, uma de itens e um dos atributos.
Itens pode ser o nome, intAttributeID, onde intAttributeID é uma referência de chave estrangeira para a tabela de atributos. Dessa forma, você pode fazer uma declaração de seleção baseado fora o que quer que você gosta.

Mas talvez isso pode ajudá-lo:

SELECT * 
FROM tbl t1
INNER JOIN tbl t2 ON t1.Name = t2.Name
WHERE t1.Attribute = 'green' AND t2.Attribute = '4 legs'

Difícil porque não é um modelo normalizado. É um fim de semana.

Você está filtrando através múltipla, linhas desconectadas, então você tem que extrair cada atributo de cada vez e, em seguida, combinar itens.

SELECT
   item
FROM
    (SELECT
        item
    FROM
        Mytable
    WHERE
        attribute = '4 legs') k1
    JOIN
    (SELECT
        item
    FROM
        Mytable
    WHERE
        attribute = 'green') k2 ON k1.item = k2.item

Se possível, gostaria de redesenhar. Isso não é algo que você nunca vai ser capaz de efetivamente consulta 12 valores ao mesmo tempo (que vai exigir 12 se junta a)

Por favor, leia este artigo wikipedia http://en.wikipedia.org/wiki/Entity-Attribute-Value_model# desvantagens

Nunca vi um banco de dados ainda que usou este modelo que não correr em problemas sérios de desempenho eventualmente. Este projeto tem um aspecto elegante para as pessoas não-banco de dados, mas na verdade é geralmente um sinal de um banco de dados mal projetado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top