Qu'est-ce qu'une instruction SQL pour sélectionner un élément qui a plusieurs attributs dans une liste élément / attribut?

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

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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top