Запрос структуры «многие ко многим» для подмножества соединенных строк - PullRequest
1 голос
/ 21 января 2011

У меня есть простая структура «многие ко многим»:

Таблица 1: ITEM Столбцы: ITEM_ID, ITEM_NAME

Таблица 2: Attribute Столбцы: ATTRIBUTE_ID, ATTRIBUTE_NAME

Таблица 3: ITEM_ATTRIBUTE ITEM_ID, ATTRIBUTE_ID

Я хочу, чтобы «получить все элементы, которые имеют следующие атрибуты x».X может быть любым количеством атрибутов.

Лучшее, что я придумал, заключается в следующем, но я считаю, что должен быть лучший способ с использованием объединений и / или предложений «где выбрать в» ...но я не могу думать об этом.

SELECT * FROM Item
WHERE Item.ITEM_ID IN
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =1)
and Item.ITEM_ID in
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =3);

Я бы предпочел не добавлять дополнительный "ITEM_ID в (...) для каждого атрибута в списке .. особенно если список атрибутов20+ длиннее

1 Ответ

0 голосов
/ 18 ноября 2011

Я бы предложил заполнить временную таблицу теми атрибутами, которые вы хотели бы указать. Как только вы получите эту таблицу, запрос станет намного чище и проще в обслуживании.

DECLARE @Item TABLE (
    Item_Id INT,
    Item_Name VARCHAR(50)
)

DECLARE @Attribute TABLE (
    Attribute_Id INT,
    Attribute_Name VARCHAR(50)
)

DECLARE @Item_Attribute TABLE (
    Item_Id INT,
    Attribute_Id INT
)

INSERT INTO @Item VALUES (1, 'Widget')
INSERT INTO @Item VALUES (2, 'Woozle')

INSERT INTO @Attribute VALUES (1, 'foo')
INSERT INTO @Attribute VALUES (2, 'bar')
INSERT INTO @Attribute VALUES (3, 'baz')
INSERT INTO @Attribute VALUES (4, 'qux')

INSERT INTO @Item_Attribute VALUES (1, 1)
INSERT INTO @Item_Attribute VALUES (1, 2)
INSERT INTO @Item_Attribute VALUES (1, 3)
INSERT INTO @Item_Attribute VALUES (2, 1)
INSERT INTO @Item_Attribute VALUES (2, 4)

DECLARE @Required_Attribute TABLE (
    Attribute_Id INT
)

INSERT INTO @Required_Attribute VALUES (1)
INSERT INTO @Required_Attribute VALUES (2)

SELECT *
FROM @Item i
WHERE NOT EXISTS (
    SELECT 1
    FROM 
        @Required_Attribute ra 
        LEFT JOIN @Item_Attribute missingAttribute
            ON ra.Attribute_Id = missingAttribute.Attribute_Id
            AND missingAttribute.Item_Id = i.Item_Id
    WHERE
        missingAttribute.Attribute_Id IS NULL
)
...