我有3张桌子:
Foods
表存储所有食品,Tags
表存储所有标签,FoodTagRelation
存储食品和标签之间的关系。我想写一个查询来选择所有正好有2个标签的食物specified Ids
(请阅读我在底部写的SQL )
Foods Table
Id | FoodItem
----------------------
1 | Mango
2 | Custard
3 | Pizza
Tags Table
Id | TagName
----------------------
1 | Fruit
2 | Cold
3 | Hot
4 | Veg
FoodTagRelation
Id | FoodId | TagId
----------------------
1 | 1 | 1
2 | 1 | 4
3 | 2 | 1
4 | 2 | 2
5 | 2 | 4
现在我要选择所有食物上只有两个标签:例如选择所有同时包含两个标签的食物:Fruit
和Cold
。
我尝试了此查询,但它会返回标记为Fruit
或 Cold
的所有食物。
select * from Foods
inner join FoodTagRelation
on
Foods.Id=FoodTagRelation.FoodId
where
tagid in ('1','2')
如何重新编写此查询以仅返回 BOTH 标记的食物?
答案 0 :(得分:3)
有关更通用的答案,可让您更改要搜索的标记:
DECLARE @Search_Tags TABLE (TagId INT)
INSERT INTO @Search_Tags (TagId) VALUES (1), (2)
SELECT
F.Id,
F.FoodItem
FROM
Foods F
INNER JOIN FoodTagRelation FTR ON
FTR.FoodId = F.Id
INNER JOIN @Search_Tags ST ON
ST.TagId = FTR.TagId
GROUP BY
F.Id,
F.FoodItem
HAVING
COUNT(*) = (SELECT COUNT(*) FROM @Search_Tags)
答案 1 :(得分:1)
SELECT
F.id,
F.FoodItem
FROM
Foods F
INNER JOIN FoodTagRelation FTR
ON F.Id = FTR.FoodId
WHERE
FTR.tagid in('1','2')
GROUP BY
F.id,
F.FoodItem
HAVING
count(Distinct FTR.tagid) > 1
功能:使用count distinct,以防止FoodTagRelation表中给定FoodID的重复tagid问题。 (如果您不认为重复是一个问题,那么您可以删除'distinct'关键字)。其次,我保留了你的WHERE子句,因为这样你就可以查找特定的标签,而不只是任何两个。最后,我列出了你的字段,因为为了使用group by子句这是必要的(反过来,为了使用HAVING子句,这是必要的。)
答案 2 :(得分:0)
在FoodID上进行分组并使用count(tagID)= 2
select *
from foods as f inner join foodtagrelation as ftr on f.id=ftr.foodid
where (ftr.tagid = 1 or ftr.tagid = 2)
group by f.foodid
having count(*) = 2
答案 3 :(得分:0)
当你说“选择所有完全 2个标签的食物”时,如果食物有3个标签,其中包括Fruit and Cold和其他一些标签。这算了吗?
无论如何,这里是查询同时发现水果和冷的食物。
SELECT *
FROM Foods f
INNER JOIN FoodTagRelation ft1
ON f.Id=ft1.FoodId
INNER JOIN FoodTagRelation ft2
ON f.Id=ft2.FoodId
WHERE
ft1.tagid = 1 AND ft2.tagid = 2
答案 4 :(得分:-1)
SELECT * from Foods where FoodId in (
select FoodID from FoodTagRelation where TagId in (1,2)
group by FoodId having count(*)=2
)
注意更新我的SQL,因为Rusi似乎只关心Foods与TagId为(1或2)的标签