查询连接行的子集的多对多结构

时间:2011-01-20 22:55:53

标签: sql query-optimization

我有一个简单的多对多db结构:

表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(...).. esp如果属性列表长度超过20个

1 个答案:

答案 0 :(得分:0)

我建议使用您想要的属性填充临时表。一旦有了这个表,查询就会变得更加清晰和可维护。

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
)