假设我有两个表定义如下:
Items
-----
Id (Primary Key)
ItemName
ItemsTags
-----
ItemId (Primary Key)
TagName (Primary Key)
并填写以下数据:
Items
-----
1, Item1
2, Item2
3, Item3
ItemsTags
--------
1, Tag1
1, Tag2
1, Tag3
2, Tag3
3, Tag4
3, Tag5
假设我想搜索分配了EITHER Tag1或Tag3的项目,则以下查询有效:
SELECT DISTINCT Items.Id
FROM Items INNER JOIN ItemsTags
ON Items.Id = ItemsTags.ItemId
WHERE ItemsTags.TagName = 'Tag1' OR ItemsTags.TagName = 'Tag3'
导致返回1和。
但是,如何修改该查询以便为我提供具有BOTH Tag1和Tag3的项目?显然,以下查询不起作用,因为对于任何给定的行,TagName不能同时为两个不同的值。
SELECT DISTINCT Items.Id
FROM Items INNER JOIN ItemsTags
ON Items.Id = ItemsTags.ItemId
WHERE ItemsTags.TagName = 'Tag1' AND ItemsTags.TagName = 'Tag3'
什么是正确的查询?在我的例子中,我希望只返回第1项。
答案 0 :(得分:2)
试试这个:
SELECT DISTINCT i.Id
FROM Items i
INNER JOIN ItemsTags it1 ON i.Id = it1.ItemId and it1.TagName='Tag1'
INNER JOIN ItemsTags it3 ON i.Id = it3.ItemId and it3.TagName='Tag3'
Here是一个SQL小提琴。
答案 1 :(得分:1)
使用exists子句:
SELECT
Items.Id
FROM
Items
Where
Exists (
Select top 1 1
FROM
ItemsTags
WHERE
ItemsTags.ItemId = Items.Id
and (ItemsTags.TagName= 'Tag1')
)
AND
Exists (
Select top 1 1
FROM
ItemsTags
WHERE
ItemsTags.ItemId = Items.Id
and (ItemsTags.TagName= 'Tag3')
)
答案 2 :(得分:1)
另一种方法:
SELECT DISTINCT Items.Id FROM Items
WHERE
Items.Id IN (SELECT ItemId FROM ItemsTags WHERE TagName = 'Tag1') AND
Items.Id IN (SELECT ItemId FROM ItemsTags WHERE TagName = 'Tag3')
答案 3 :(得分:1)
你也可以这样做。
SELECT items.ID
FROM items
INNER JOIN ItemsTags ON
Items.Id = ItemsTags.ItemId
WHERE ItemsTags.TagName IN ('Tag1','Tag3')
GROUP BY
items.ID
HAVING COUNT(*) = 2
答案 4 :(得分:0)
这样做的另一种可行方式只是为了说明在sql中执行任何操作的无数方法,这次采用了与其他方法截然不同的方法。
SELECT i.Id
FROM Items i
JOIN (
SELECT ItemId
FROM ItemsTags
WHERE TagName IN ('Tag1', 'Tag3')
GROUP BY ItemId
HAVING COUNT(*) > 1
) t ON t.ItemId = i.Id