我需要一些帮助,我认为应该是一个相当简单的自联接查询。它只需要将匹配的开始时间和结束时间从两个记录组合成一个记录
说我在表格中有以下内容
Time Event
08:00 Start
09:00 Stop
10:30 Start
10:45 Stop
11:00 Start
11:15 Start
12:00 Stop
12:30 Stop
我想要一个像这样的视图
StartTime Stoptime
08:00 09:00
10:30 10:45
11:00
11:15 12:00
12:30
请注意,它应该找到最接近的匹配开始或结束时间。如果由于某种原因没有匹配事件,则应将其留空。
谢谢,
答案 0 :(得分:4)
声明: 我会认真考虑不同的桌面设计。加入日期或时间永远不是一个好主意。如果您有一个正在启动的事件的ID,您可以轻松地LEFT JOIN以尝试找到该事件的匹配结束。
对于SQL Server,请尝试:
DECLARE @Events table (EventTime char(5), EventType varchar(5))
INSERT INTO @Events VALUES ('08:00','Start')
INSERT INTO @Events VALUES ('09:00','Stop')
INSERT INTO @Events VALUES ('10:30','Start')
INSERT INTO @Events VALUES ('10:45','Stop')
INSERT INTO @Events VALUES ('11:00','Start')
INSERT INTO @Events VALUES ('11:15','Start')
INSERT INTO @Events VALUES ('12:00','Stop')
INSERT INTO @Events VALUES ('12:30','Stop')
SELECT
dt.StartTime, dt.StopTime
FROM (SELECT
p.EventTime AS StartTime,CASE WHEN c.EventType!='Stop' THEN NULL ELSE c.EventTime END AS StopTime
,p.EventTime AS SortBy
FROM @Events p
INNER JOIN @Events c ON p.EventTime<c.EventTime
WHERE p.EventType='Start'
AND c.EventTime=(SELECT MIN(EventTime) FROM @Events WHERE EventTime>p.EventTime)
UNION
SELECT
NULL AS StartTime,p.EventTime
,p.EventTime AS SortBy
FROM @Events p
INNER JOIN @Events c ON p.EventTime>c.EventTime
WHERE p.EventType='STOP'
AND c.EventTime=(SELECT MAX(EventTime) FROM @Events WHERE EventTime<p.EventTime)
AND c.EventType='Stop'
) dt
ORDER BY dt.SortBy
输出:
StartTime StopTime
--------- --------
08:00 09:00
10:30 10:45
11:00 NULL
11:15 12:00
NULL 12:30
(5 row(s) affected)
答案 1 :(得分:0)
我猜你使用 SQL 标签来表示 sql-server 。但是,如果未来的求职者对Oracle解决方案感兴趣,可以使用分析LEAD()
和LAG()
函数解决此问题......
SQL> select * from (
2 select case when event = 'Start' then t else null end as start_t
3 , case when next_event = 'Stop' then next_t
4 when event = 'Stop' and prev_event = 'Stop' then next_t
5 else null end as stop_t
6 from (
7 select event
8 , t
9 , lead (t) over (order by t) as next_t
10 , lead (event) over (order by t) as next_event
11 , lag (event) over (order by t) as prev_event
12 from t23
13 order by t )
14 )
15 where start_t is not null
16 or stop_t is not null
17 /
START STOP_
----- -----
08:00 09:00
10:30 10:45
11:00
11:15 12:00
12:30
SQL>