在一个表中查找事件的开始和结束日期

时间:2016-06-16 17:42:28

标签: sql sql-server-2012

我有一个表,其中事件以不同的行存储起始和结束日期。现在,我想查询所有相应的开始日期和结束日期对,以创建报告。

CREATE TABLE EVENTS (
 Id INT IDENTITY(1,1) PRIMARY KEY,
 DateEntry datetime,
 IsStart bit,
 EventType varchar(12)
)

INSERT INTO EVENTS
VALUES
('2016-06-16', 1, 'EVENT A'),
('2016-06-16', 1, 'EVENT B'),
('2016-06-17', 0, 'EVENT A'),
('2016-06-18', 1, 'EVENT A'),
('2016-06-19', 0, 'EVENT A'),
('2016-06-20', 0, 'EVENT B'),
('2016-06-21', 1, 'EVENT C')


SELECT EventType, DateEntry as StartDate, EndDate = LEAD(DateEntry, 1) OVER ( PARTITION BY EventType ORDER BY DateEntry)
FROM Events
ORDER BY EventType, DateEntry

此查询返回:

| EventType | StartDate  | EndDate    |
=======================================
| EVENT A   | 2016-06-16 | 2016-06-17 |
| EVENT A   | 2016-06-17 | 2016-06-18 |
| EVENT A   | 2016-06-18 | 2016-06-19 |
| EVENT A   | 2016-06-19 | NULL       |
| EVENT B   | 2016-06-16 | 2016-06-20 |
| EVENT B   | 2016-06-20 | NULL       | 
| EVENT C   | 2016-06-21 | NULL       | 

我期待这个结果:

| EventType | StartDate  | EndDate    |
=======================================
| EVENT A   | 2016-06-16 | 2016-06-17 |
| EVENT A   | 2016-06-18 | 2016-06-19 |
| EVENT B   | 2016-06-16 | 2016-06-20 |
| EVENT C   | 2016-06-21 | NULL       |

我需要添加一个过滤器来查找开始日期并在其上应用LEAD函数,但是如果我添加一个WHERE子句,它将完全忽略所有EndDates。

使用内联查询我能够得到正确的结果,但我不确定这是否是最佳解决方案

SELECT * FROM (
SELECT EventType, IsStart, DateEntry as StartDate, EndDate = LAG(DateEntry, 1) OVER ( PARTITION BY EventType ORDER BY DateEntry DESC)
FROM Events) a
WHERE IsStart = 1

1 个答案:

答案 0 :(得分:1)

SELECT *
FROM
    #EVENTS s
    OUTER APPLY (
       SELECT TOP 1 DateEntry AS EndDateEntry
       FROM
          #EVENTS i
       WHERE
          i.EventType = s.EventType
          AND i.IsStart = 0
          AND i.DateEntry > s.DateEntry
       ORDER BY
          i.DateEntry ASC
    ) e
WHERE
    s.IsStart = 1