SQL查询所有记录必须存在以返回记录

时间:2011-06-09 00:33:58

标签: c# tsql select join

我甚至不确定如何提出这个问题。

我有一张标签表:

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。

感谢。

4 个答案:

答案 0 :(得分:4)

昨天有一个非常相似的问题:Query for exact match of users in a conversation in 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

所以这将找到两个标签都存在的所有事件(这允许这两个标签与任何其他标签一起存在的实例)

答案 1 :(得分:1)

这是一个解决方案,供您在事先知道标签时使用。

将标记加载到表变量中并获取总计数:

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
              )

仅返回包含所有标记的标记。

再次感谢大家的想法!非常感谢所有的反馈!

答案 2 :(得分:0)

您需要内连接两个表,如下所示

SELECT * FROM Events INNER JOIN MapTable ON MapTable.EventId=Events.EventID WHERE MapTable.TagID=1 AND MapTable.TagID=3

答案 3 :(得分:0)

可能有更好的方式来编写它,但这会给你你想要的东西:

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)