根据复杂(?)条件

时间:2017-09-27 15:11:04

标签: sql sql-server date

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不在集合中,因为其日期与其他任何日期都不重叠。

1 个答案:

答案 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是此解决方案的实时链接。