fileid custid dept1 dept2 date1 date2 date3
123 456 2 4 1/1/04 1/1/05 1/1/06
777 456 2 4 NULL 5/30/05 1/1/07
111 456 2 4 12/2/06 NULL 3/3/07
200 456 2 6 1/1/04 2/1/04 3/1/04
444 456 2 8 2/1/07 4/1/07 6/1/07
500 456 2 8 3/1/07 3/15/07 4/2/07
我尝试编写一些SQL,它会将上面的前3条记录拉出来,并根据custid,dept1和dept2相同以及日期重叠的事实将它们显示为'set',即fileid 123中的任何日期早于fileid 777和fileid 111中的最早日期。它不会拉第4条记录,因为dept2不同。并且它将拉出记录5和6并将它们显示为单独的集合,因为custid,dept1,dept2匹配和fileid 500的日期在'fileid 444'的日期内。用这个撞到我的头撞墙。有人可以帮忙吗?
以下是匹配的custiid,dept1和dept2不在同一组中的多行的示例:
fileid custid dept1 dept2 date1 date2 date3
123 456 2 4 1/1/04 1/1/05 1/1/06
777 456 2 4 NULL 5/30/05 1/1/07
111 456 2 4 12/2/06 NULL 3/3/07
666 456 2 4 1/1/08 3/1/08 5/1/08
fileid 666不在集合中,因为其日期与其他任何日期都不重叠。
答案 0 :(得分:2)
我认为该查询可以满足您的需求。但我不得不说这不是最干净的答案。我也得到了3个查询的结论,但它可以用一个查询完成,但这会增加复杂性。在第一个查询中,我发现第二个i中的重复项列出了它们,在第三个中我设置了你想要的规则。
SELECT * INTO #temp FROM (Select custID,dept1,dept2 FROM @table
Group By custID,dept1,dept2
HAVING COUNT(custID) > 1) AS p
SELECT * INTO #temp2 FROM (Select ROW_NUMBER() OVER(PARTITION BY custID,dept1,dept2 Order By CustID ) as RN,*
FROM @table
Where custID IN (Select custID FROM #temp) AND dept1 IN (Select dept1 FROM #temp) AND dept2 IN (Select dept2 FROM #temp)
) AS x
Select * FROM @table Where fileID IN (
Select t1.fileID FROM #temp2 t1
INNER JOIN #temp2 t2 ON t1.RN = t2.RN-1 AND (
COALESCE(t2.date1,t2.date2) BETWEEN COALESCE(t1.date1,t1.date2) AND COALESCE(t1.date3,t1.date2)
OR
COALESCE(t2.date3,t2.date2) BETWEEN COALESCE(t1.date1,t1.date2) AND COALESCE(t1.date3,t1.date2)
)
AND t2.custID = t1.custID AND t2.dept1 = t1.dept1 AND t2.dept2 = t1.dept2)
OR
fileID IN (
Select t2.fileID FROM #temp2 t1
INNER JOIN #temp2 t2 ON t1.RN = t2.RN-1 AND (
COALESCE(t2.date1,t2.date2) BETWEEN COALESCE(t1.date1,t1.date2) AND COALESCE(t1.date3,t1.date2)
OR
COALESCE(t2.date3,t2.date2) BETWEEN COALESCE(t1.date1,t1.date2) AND COALESCE(t1.date3,t1.date2)
)
AND t2.custID = t1.custID AND t2.dept1 = t1.dept1 AND t2.dept2 = t1.dept2)
Here是此解决方案的实时链接。