【发布时间】:2021-06-13 13:59:20
【问题描述】:
这是我的示例数据:
declare @Test table (SiteIdentifier int, SysTm datetime2(0), Signalet varchar(21));
insert into @Test (SiteIdentifier, SysTm, Signalet)
values
(587451, '2021-02-28 20:12:03', 'Joined'),
(587451, '2021-03-01 00:00:00', 'Left'),
(587451, '2021-03-04 07:12:17', 'Joined'),
(587451, '2021-03-05 02:13:03', 'Left'),
(587451, '2021-03-05 02:13:03', 'Left'),
(587451, '2021-03-05 07:13:00', 'Joined'),
(587451, '2021-03-08 01:04:07', 'Joined');
这是一个几乎解决了我的问题的查询:
with cte as (
select *
, row_number() over (partition by SiteIdentifier, Signalet order by SysTm) rn
from @Test
)
select C1.SiteIdentifier, C1.SysTm, coalesce(C2.SysTm, C3.SysTm), datediff(hour, C1.SysTm, coalesce(C2.SysTm, C3.SysTm))
from cte C1
left join cte C2 on C2.SiteIdentifier = C1.SiteIdentifier and C2.Signalet = 'Joined' and C2.rn = C1.rn and C2.SysTm > C1.SysTm
left join cte C3 on C3.SiteIdentifier = C1.SiteIdentifier and C3.Signalet = 'Joined' and C3.rn = C1.rn + 1 and C3.SysTm > C1.SysTm and C2.rn is null
where C1.Signalet = 'Left'
order by C1.SysTm asc;
只要Signalet 在Left、Joined、Left、Joined 等SiteIdentifier 之间交替,它就可以工作。
但是,在实时数据中,有时Joined(或Left)可能在几毫秒内出现两次 - 如示例数据所示。因此,当Joined 或Left 连续多次出现时,应忽略除第一条记录之外的所有记录。如果是Joined,第一条记录也应该如此,因为序列必须始终以Left 开头。
然后我需要计算Left 和下面的Joined 记录之间的时间差。
(587451, '2021-02-28 20:12:03', 'Joined'),<-- Skipped
(587451, '2021-03-01 00:00:00', 'Left'),<-- Used
(587451, '2021-03-04 07:12:17', 'Joined'),<-- Used
(587451, '2021-03-05 02:13:03', 'Left'),<-- Skipped
(587451, '2021-03-05 02:13:03', 'Left'),<-- Used
(587451, '2021-03-05 07:13:00', 'Joined'),<-- Skipped
(587451, '2021-03-08 01:04:07', 'Joined');<-- Used
以上示例数据的结果应如下所示:
ID Left Joined Hours
587451 '2021-03-01 00:00:00' '2021-03-04 07:12:17' 79
587451 '2021-03-05 02:13:03' '2021-03-05 07:13:00' 5
忽略第一个Joined(上面的查询确实如此),因为它前面没有Left。但是,我的查询无法产生这个结果,因为时间有两个相等的Signalet 一个接一个,而不是交替出现。
更新数据/问题:
这是来自 live 表的 actual 数据,它返回 NULL:
ID
15220 '2021-03-13 23:19:57.243' Left
15220 '2021-03-15 05:54:01.027' Joined
15220 '2021-03-15 23:29:44.043' Left
15220 '2021-03-16 05:30:27.790' Joined
使用上面更新的查询返回:
15220 '2021-03-13 23:19:57.243' NULL NULL
15220 '2021-03-15 23:29:44.043' NULL NULL
它注册了正确的行,但它无法“找到”joined 和 Hours
说明:
我试图在hours 中获得difference,在Left 信号和Joined 信号之间(所有信号都在同一个表中,因此是CTE)。需要考虑的是,第一个信号可以是Joined,也可以是两个Left,也可以是两个Joined一个接一个的信号。如果第一个信号是Joined,则忽略它并移动到Left的第一个出现处,当有两个Joined或两个Left紧接在另一个之后,只使用两者中的第一个,忽略最后一个。
【问题讨论】:
-
我不明白这里的问题,你似乎并没有真正问一个。一个问题本身就应该是完整的,看来您之前的问题需要在这里阅读,以便我们尝试回答这个问题。 Edit这个问题给我们这个问题的所有细节。
-
如果您能解释一下您要完成的工作,那将非常有帮助。它似乎埋在某个地方,但真的很难弄清楚你在做什么。
-
我编辑了问题并添加了一个解释部分,试图逐步解释我想要完成的工作。
标签: sql sql-server tsql common-table-expression