最佳SQL查询,以获取所有父母都存在的常见子项

时间:2011-08-19 15:06:54

标签: sql-server-2005

我有两个表,Parent(#tableA)和Child(#tableB)

在下面给出的脚本中 我需要为这个例子'C3'只获得一条记录,这是P1,P2和P3的常见子代。

我只能想到下面这个方法。

Create table #tableA ( PkCol varchar(3) )
Create table #tableB ( FkCol varchar(3), FKChild varchar(10) )

Insert Into #tableA
Select 'P1' union
Select 'P2' union
Select 'P3' 

Insert Into #tableB
Select 'P1', 'C1' union
Select 'P1', 'C2' union
Select 'P1', 'C3' union
Select 'P2', 'C3' union
Select 'P2', 'C4' union
Select 'P2', 'C5' union
Select 'P3', 'C3' union
Select 'P3', 'C6' union
Select 'P3', 'C7' 

Select tb.FKChild from #tableA ta Inner Join #tableB tb on tb.FkCol = ta.PkCol
Group By tb.FKChild
Having Count(Distinct ta.PkCol) = (Select Count(*) from #tableA)

Drop table #tableA
Drop table #tableB

当实际的父表有接近1K的记录并且子表有接近200万条加上记录时,是否有更好的方法可以做到干净并且不会影响性能?

1 个答案:

答案 0 :(得分:0)

首先检查您的查询计划。 如果您非常确定,表格的比例与您描述的1k:2M相同,并且您的查询计划中还有其他内容,您可以按照此处的说明为连接添加提示:    http://msdn.microsoft.com/en-us/library/ms173815%28v=SQL.90%29.aspx

如果两个表都适合memmory,请尝试使用散列连接,如果不适合循环连接(基于您的查询):

Select tb.FKChild from #tableA ta Inner Loop Join #tableB tb on tb.FkCol = ta.PkCol
Group By tb.FKChild
Having Count(Distinct ta.PkCol) = (Select Count(*) from #tableA)

但请注意,如果您不确定数据比率,请保留查询计划以供sql server选择,因为如果您强制使用不正确的连接类型,它可能会影响您的性能。