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。

谢谢。

TSQL查询所有记录必须存在的位置才能返回记录

昨天有一个非常类似的问题:在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