Qu'est-ce qu'une instruction SQL pour sélectionner un élément qui a plusieurs attributs dans une liste élément / attribut?
-
06-09-2019 - |
Question
Dire que j'ai une table qui a des éléments et attributs répertoriés comme,
frog green
cat furry
frog nice
cat 4 legs
frog 4 legs
Dans la colonne articles que je veux sélectionner des objets uniques qui ont à la fois l'attribut vert et 4 pieds. Je me attends à revenir juste l'objet grenouille dans ce cas. Quelle est la requête la plus efficace pour ce faire?
La solution
select item.name
from item
where item.attribute in ('4 legs', 'green')
group by item.name
having count(distinct item.attribute) = 2
Autres conseils
La façon la plus efficace de le faire est avec une auto-jointure:
SELECT * FROM attributes a1
JOIN attributes a2 USING (item_name) -- e.g. frog
WHERE a1.value = 'green' AND a2.value = '4 legs';
Une autre solution que certaines personnes utilisent un truc avec GROUP BY:
SELECT item_name FROM attributes
WHERE value IN ('4 legs', 'green')
GROUP BY item_name
HAVING COUNT(*) = 2;
Mais le GROUP BY solution ne peut pas être aussi efficace que JOIN, selon la marque de SGBDR que vous utilisez. En outre une méthode peut évoluer mieux que le volume de votre table augmente.
select * from table où = chose 'grenouille'
rien ne vaut savoir exactement ce que vous voulez.
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
Vous pouvez également interroger chaque attribut séparément, puis les recouper ...
/*
-- 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'
créer deux tables, l'un des éléments et l'un des attributs.
Articles pourraient être le nom, intAttributeID, où intAttributeID est une référence clé étrangère à la table des attributs. De cette façon, vous pouvez faire une instruction select basée hors tout ce que vous aimez.
Mais peut-être cela peut vous aider:
SELECT *
FROM tbl t1
INNER JOIN tbl t2 ON t1.Name = t2.Name
WHERE t1.Attribute = 'green' AND t2.Attribute = '4 legs'
Hard parce que ce n'est pas un modèle normalisé. Il est un week-end.
Vous filtrez sur plusieurs, les lignes non connectées, de sorte que vous auriez à extraire chaque attribut à son tour puis correspondre les éléments.
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
Si possible, je redessiner. Ce n'est pas quelque chose que vous serez jamais en mesure d'interroger efficacement 12 valeurs en même temps (il faudra 12 joint)
S'il vous plaît lire cet article wikipedia http://en.wikipedia.org/wiki/Entity-Attribute-Value_model# downsides
Jamais vu une base de données encore qui a utilisé ce modèle qui n'a pas couru dans de sérieux problèmes de performance par la suite. Cette conception est élégante aux personnes non-base de données, mais est en fait généralement le signe d'une base de données mal conçue.