查找阻止范围在表中的任何阻止范围内的所有记录

时间:2013-03-26 11:55:33

标签: tsql

我有一个表 TaggedData ,包含以下字段和数据

ID  GroupID  Tag    MyData
**  *******  ***    ******
1    Texas   AA01   Peanut Butter
2    Texas   AA15   Cereal
3    Ohio    AA05   Potato Chips
4    Texas   AA08   Bread

我有第二张 BlockedTags 表,如下所示:

ID  StartTag  EndTag
**  ********  ******
1     AA00     AA04 
2     AA15     AA15

如何从中选择返回与给定GroupId匹配的所有数据,但不包含任何阻止范围(包括)?对于GroupId是Texas的数据,我不想返回Cereal,因为它匹配第二个范围。它应该只返回面包。

我确实尝试过基于联接的查询,但我甚至不是那么接近。

由于

2 个答案:

答案 0 :(得分:1)

create table TaggedData (
    ID int,
    GroupID varchar(16),
    Tag char(4),
    MyData varchar(50))

create table BlockedTags (
    ID int,
    StartTag char(4),
    EndTag char(4)
)

insert into TaggedData(ID, GroupID, Tag, MyData)
values (1, 'Texas',   'AA01',   'Peanut Butter')
insert into TaggedData(ID, GroupID, Tag, MyData)
values (2, 'Texas' ,  'AA15',   'Cereal')
insert into TaggedData(ID, GroupID, Tag, MyData)
values (3, 'Ohio ',   'AA05',   'Potato Chips')
insert into TaggedData(ID, GroupID, Tag, MyData)
values (4, 'Texas',   'AA08',   'Bread')

insert into BlockedTags(ID, StartTag, EndTag)
values (1,     'AA00',     'AA04')
insert into BlockedTags(ID, StartTag, EndTag)
values (2,     'AA15',     'AA15')

select t.* from TaggedData t
left join BlockedTags b on t.Tag between b.StartTag and b.EndTag
where b.ID is null

返回:

ID          GroupID          Tag  MyData
----------- ---------------- ---- --------------------------------------------------
3           Ohio             AA05 Potato Chips
4           Texas            AA08 Bread

(2 row(s) affected)

因此,要匹配给定的GroupID,您可以更改查询:

select t.* from TaggedData t
left join BlockedTags b on t.Tag between b.StartTag and b.EndTag
where b.ID is null and t.GroupID=@GivenGroupID

答案 1 :(得分:0)

我更喜欢NOT EXISTS,因为它通常在大数据中提供更多的可读性,可用性和更好的性能(有几种情况可以获得更好的执行计划):

会是这样的:

SELECT * from TaggedData
WHERE GroupID=@GivenGroupID
AND NOT EXISTS(SELECT 1 FROM BlockedTags WHERE Tag BETWEEN StartTag ANDEndTag)