Что такое инструкция SQL для выбора элемента, который имеет несколько атрибутов в списке элементов / атрибутов?

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

Вопрос

Допустим, у меня есть таблица, в которой элементы и атрибуты перечислены следующим образом,

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

В столбце элементы я хочу выбрать уникальные объекты, которые имеют атрибут green и 4 legs.В этом случае я бы ожидал получить обратно только объект frog.Какой запрос наиболее эффективен для этого?

Это было полезно?

Решение

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

Другие советы

Самый эффективный способ сделать это - с помощью самосоединения:

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

Другое решение, которое используют некоторые люди, - это трюк с GROUP BY:

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

Но решение GROUP BY может быть не таким эффективным, как JOIN, в зависимости от того, какую марку СУБД вы используете.Кроме того, один из методов может лучше масштабироваться по мере увеличения объема вашей таблицы.

выберите * из таблицы, где thing='лягушка'

нет ничего лучше, чем точно знать, чего ты хочешь.

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

Кроме того, можно запросить каждый атрибут отдельно, а затем пересекают их ...

/*
-- 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'

создайте две таблицы, одну из элементов и одну из атрибутов.
Элементами могут быть name, intAttributeID, где intAttributeID - это ссылка на внешний ключ таблицы атрибутов.Таким образом, вы можете выполнить оператор select на основе всего, что вас волнует.

Но, может быть, это поможет вам:

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

Сложно, потому что это не нормализованная модель. Сегодня выходные.

Вы фильтруете по нескольким несвязанным строкам, поэтому вам придется извлекать каждый атрибут по очереди, а затем сопоставлять элементы.

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

Если возможно, я бы переделал дизайн.Это не то, к чему вы когда-либо сможете эффективно запрашивать 12 значений одновременно (для этого потребуется 12 объединений)

Пожалуйста, прочтите эту статью в Википедии http://en.wikipedia.org/wiki/Entity-Attribute-Value_model#Downsides

Никогда еще не видел базы данных, использующей эту модель, которая в конечном итоге не столкнулась бы с серьезными проблемами производительности.Такой дизайн выглядит элегантно для людей, не имеющих отношения к базам данных, но на самом деле обычно является признаком плохо спроектированной базы данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top