查找重叠日期和返回重叠记录

时间:2017-07-06 16:10:49

标签: sql tsql date-range

我需要的是返回所有可能相互重叠的记录。

<span>
  <input type="radio"><label attr="custom">Option 1</label></span>
<span>
<span>
  <input type="radio"><label attr="custom">Option 2</label></span>
<span>
<span>
  <input type="radio"><label attr="custom">Option 3</label></span>
<span>

我的结果如下:

-- Create Temp Table
CREATE TABLE #Overlap

(SubType varchar(50), 
Cause varchar(9),
CircuitID varchar(100),
BegDate date,
EndDate date,
AmtSought decimal(11,2),
Remarks varchar(max))

--Insert records

INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-12-01','2016-12-31',354.41,'Rec 1')
INSERT INTO #Overlap VALUES('Original','201500009','36/VCID/826061/IP/NUVX','2016-08-11','2016-08-12',200.50,'Rec 2')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-11-15','2016-12-14',100.25,'Rec 3')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-12-16','2017-01-15',300.75,'Rec 4')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2017-01-01','2017-01-01',500.00,'Rec 5')
INSERT INTO #Overlap VALUES('Original','201500009','36/VCID/826061/IP/NUVX','2016-07-01','2016-07-31',100.50,'Rec 6')

我从我看过的示例代码中尝试了这个,但它没有返回所需的结果。

SubType   Cause     CircuitID                  BegDate    EndDate    AmtSought Remarks
------------------- -------------------------- ---------- ---------- --------- --------
Original  201500018 36/KQ--/831670/IP /NUVX/   2016-11-15 2016-12-14 100.25    Rec 3
Original  201500018 36/KQ--/831670/IP /NUVX/   2016-12-01 2016-12-31 354.41    Rec 1
Original  201500018 36/KQ--/831670/IP /NUVX/   2016-12-16 2017-01-15 300.75    Rec 4
Original  201500018 36/KQ--/831670/IP /NUVX/   2017-01-01 2017-01-01 500.00    Rec 5

2 个答案:

答案 0 :(得分:2)

假设您的#Overlap表有主键(或唯一键)TableId

您可以使用以下查询

SELECT * FROM #Overlap o
WHERE EXISTS
(
    SELECT 1 FROM #Overlap o2
    WHERE o2.SubType = o.SubType
    AND o2.Cause = o.Cause
    AND o2.CircuitID = o.CircuitID
    AND (
            o2.BegDate BETWEEN o.BegDate AND o.EndDate
            OR o2.EndDate BETWEEN o.BegDate AND o.EndDate
            OR o.BegDate BETWEEN o2.BegDate AND o2.EndDate
            OR o.EndDate BETWEEN o2.BegDate AND o2.EndDate
        )
    AND o2.TableId != o.TableId
)
ORDER BY o.SubType, o.Cause, o.BegDate

演示链接:http://rextester.com/KBFX30109

作为@HABO建议,您还可以用来检查重叠

    AND o2.BegDate <= o.EndDate 
    AND o.BegDate <= o2.EndDate 

答案 1 :(得分:2)

您需要检查开始重叠和结束重叠。如果startdate始终小于endDate,则可以使用以下查询。如果您有一些主键,则不需要CTE:

; WITH CTE AS
(
    SELECT *,
    ROW_NUMBER() OVER(
            PARTITION BY (SELECT NULL)
            ORDER BY (SELECT NULL)
    ) AS pk FROM #Overlap
)
SELECT a.*, b.pk, b.BegDate, b.endDate FROM CTE a
CROSS JOIN CTE b 
WHERE -- Simplify by adding PK
(a.pk <> b.pk)
AND (CASE WHEN (a.BegDate > b.BegDate) THEN a.BegDate ELSE b.BegDate END)
 <= (CASE WHEN (a.endDate < b.endDate) THEN a.endDate ELSE b.endDate END)