TSQL查询所有记录必须存在的位置才能返回记录
本文关键字:记录 位置 返回 存在 查询 TSQL | 更新日期: 2023-09-27 17:58:47
我甚至不知道该怎么问这个问题。
我有一张标签表:
TagId Tag
----- -----
1 Fruit
2 Meat
3 Grain
我有一张事件表:
EventId Event
------- -----------
1 Eating Food
2 Buying Food
我需要做的是只带回具有所有选定标签的事件
如果选择了三个标记,则只显示具有这三个标记的事件。
例如:
映射表
EventId TagId
------- -----
1 1
1 3
2 1
如果我写这样一个查询:
select * from MapTable where where tagId in (1,3)
这将返回"吃食物和买食物"。
但我需要做的是带回同时具有标签1和3的事件。这意味着,在这种情况下,我会返回的唯一事件将是Eating Food,因为它有两个选定的标签。
我想知道这是否可以在TSQL中完成,或者我是否必须使用业务层将其转换为对象以返回GUI。
谢谢。
昨天有一个非常类似的问题:在SQL Server 中查询对话中用户的精确匹配
基本上你可以这样做:
DECLARE @NumTags INT = 2
SELECT EventID
FROM EventTag
GROUP BY EventID
HAVING
Sum(CASE WHEN TagID IN (1, 3) THEN 1 ELSE 0 END) >= @NumTags
因此,这将找到两个标签都存在的所有事件(这允许这两个标签与任何其他标签一起存在的实例)
这里有一个解决方案,当您不知道之前的标签时。
将标签加载到一个表变量中,并获得总计数:
select @iCount = COUNT(*) from @Tags;
然后编写您的普通查询,并将这些结果放入一个表变量中:
insert into @EventTags(IsSet, EventId)
select distinct CASE WHEN TagID IN (select ID from @Tags) THEN 1 ELSE 0 END,
e.EventId
from Event_Tag e
inner join @Tags t on t.ID = e.TagId
然后只返回具有所有匹配标记的事件,而不仅仅是选择中的那些,而是所有您这样做的:
select *
from Event_Tag e
inner join @Tags t on t.ID = e.TagId
where e.EventId in
( select EventId
from @EventTags
group by EventId
having count(EventId) = @iCount
)
只带回所有标记都关联的标记。
再次感谢大家的想法!非常感谢所有的反馈!
可能有更好的编写方法,但这将为您提供您想要的内容:
select *
from event e
where exists(select * from maptable where eventid = e.eventid and tagid = 1) and exists(select * from maptable where eventid = e.eventid and tagid = 3)
您将需要内部连接这两个表,如下
SELECT * FROM Events INNER JOIN MapTable ON MapTable.EventId=Events.EventID WHERE MapTable.TagID=1 AND MapTable.TagID=3