查找具有两个或更多关系的行

时间:2011-09-06 18:52:49

标签: sql sql-server

我有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

现在我要选择所有食物上只有两个标签:例如选择所有同时包含两个标签的食物:FruitCold

我尝试了此查询,但它会返回标记为Fruit Cold的所有食物。

select * from Foods
 inner join FoodTagRelation
 on
 Foods.Id=FoodTagRelation.FoodId
 where
 tagid in ('1','2')

如何重新编写此查询以仅返回 BOTH 标记的食物?

5 个答案:

答案 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)的标签