日期:2014-05-18  浏览次数:20517 次

求助一个合并查询函数或存储过程的实现
有表A,其形式如下:
ID1     ID2
1         2
1         3
1         4
1         5
2         2
2         3
2         5
3         2
3         4
3         5
ID1和ID2共同构成了表A的主键,此时有需要查询得到ID2仅等于2,3,5时候的ID1,在此例中应该只有ID1=2的纪录被选出来。

我先前找到过一些合并函数的例子,但是都需要建立一个新的表或者视图用于存放一个表(视图)B:
表B
ID1       ID2
1           2,3,4,5
2           2,3,5
3           2,4,5
由于本身数据库比较大,光表格A就会有上万条数据,如果在每次查询的时候都建立表B或者每次查询都要进行一次遍历的话开销太大。

是否有什么方法,可以实现比较高效快速的实现方法?

我希望不用进行建立临时用的表B来实现,但是在查询时候的开销又太大。

或者能够在大幅度减少查询时间的情况下建立表B,并且定期对表B进行更新,但是定期更新的话问题又来了,如果刚刚在表A中添加新的纪录后马上有别人要进行查询,这时候的表B还没有来得及更新,查找到的结果是上次更新后的结果,而这并不是我所希望的。如果用触发器来控制更新表B是不是会太过于频繁?而且同时有人在添加表A数据又有新问题了。

实在比较麻烦,必须在实现功能的基础上得到最优化的性能。谢谢各位了!

------解决方案--------------------
----创建测试数据
declare @t table(ID1 int, ID2 int)
insert @t
select 1, 2 union all
select 1, 3 union all
select 1, 4 union all
select 1, 5 union all
select 2, 2 union all
select 2, 3 union all
select 2, 5 union all
select 3, 2 union all
select 3, 4 union all
select 3, 5

----查询
declare @idlist varchar(20)
set @idlist = '2,3,5 '
select DISTINCT ID1 from @t as a where not exists(select 1 from @t where
ID1 = a.ID1 and charindex( ', ' + rtrim(ID2) + ', ', ', ' + @idlist + ', ') = 0)

/*结果
ID1
2
*/
------解决方案--------------------
----下面修改过的,选出id2 刚好取值 2 3 5 (不多也不少)的id1值
----创建测试数据
declare @t table(ID1 int, ID2 int)
insert @t
select 1, 2 union all
select 1, 3 union all
select 1, 4 union all
select 1, 5 union all
select 2, 2 union all
select 2, 3 union all
select 2, 5 union all
select 3, 2 union all
select 3, 5 union all
select 4, 2 union all
select 4, 3 union all
select 4, 4 union all
select 4, 5
----查询
declare @idlist varchar(20)
set @idlist = '2,3,5 '
select DISTINCT a.ID1 from @t a join (select id1,count(*) id2count from (select distinct id1,id2 from @t) t group by id1) b on a.id1=b.id1 and b.id2count = len(replace(@idlist, ', ', ' '))
and not exists(select 1 from @t where ID1 = a.ID1 and charindex( ', ' + rtrim(ID2) + ', ', ', ' + @idlist + ', ') = 0)

/*结果
ID1
2
*/