O que é uma instrução SQL para selecionar um item que tem vários atributos em uma lista de itens / atributo?
-
06-09-2019 - |
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?
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.