CTE 递归加入 table
CTE Recursively join table
我有一个 table 个 ID,每次更新该 ID 时都会更新状态代码和时间戳,例如:
ID STATUS TIMESTAMP
------------------------------------
12345 10 2020-08-01 11:00:01
12345 20 2020-08-01 11:01:24
12345 30 2020-08-01 11:07:42
我想将所有状态变化和时间排成一行,所以我最后得到:
ID STATUS TIMESTAMP STATUS TIMESTAMP STATUS TIMESTAMP
-----------------------------------------------------------------------------------------------------
12345 10 2020-08-01 11:00:01 20 2020-08-01 11:01:24 30 2020-08-01 11:07:42
我可以通过对每个状态进行连接来完成此操作,因此我的查询如下所示:
with T1 as
(SELECT distinct
id as 'ID',
Status as 'STATUS',
Timestamp as 'Time10'
from StatusHistory S
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
and Status = '10'),
T2 as
(SELECT distinct
id as 'ID',
Status as 'STATUS',
Timestamp as 'Time20'
from StatusHistory S
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
and Status = '20')
Select * from T1
join T2 on T1.ID = T2.ID
这行得通,但我必须对每个状态都这样做,并且大约有 12 个不同的状态代码。我已经阅读了几个进行草书连接的示例,并理解了这个概念,但实际上将它应用于我的查询时遇到了很多麻烦。本质上我想说的是递归位是 Status = Previous Status + 10
, 但是如何实现这个很麻烦。
我不明白如何获取最近的状态并向其添加 10。
您可以使用条件聚合:
select id,
max(case when seqnum = 1 then status end) as status_1,
max(case when seqnum = 1 then timestamp end) as timestamp_1,
max(case when seqnum = 2 then status end) as status_2,
max(case when seqnum = 2 then timestamp end) as timestamp_2,
max(case when seqnum = 3 then status end) as status_3,
max(case when seqnum = 3 then timestamp end) as timestamp_3
from (select sh.*,
row_number() over (partition by id order by timestamp) as seqnum
from StatusHistory sh
where TimeStamp > '2020-01-07 11:00' and
Timestamp < '2020-01-07 11:10'
) sh
group by id
Gordon Linoff 的解决方案非常适合我,但后来我了解了 PIVOT 函数,经过反复试验,发现以下给了我想要的 table 结果:
SELECT * FROM
(
SELECT
id,
status,
timestamp
FROM StatusHistory
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
) dat
PIVOT
(
MAX(Timestamp) FOR Status IN ([10], [20], [30], [40], [50], [60], [70], [80], [90], [100], [170])
) pvt
order by 10
这给了我这样的结果:
ID 10 20 30
12345 2020-01-08 11:00:01 2020-01-08 11:01:24 2020-01-08 11:07:42
我有一个 table 个 ID,每次更新该 ID 时都会更新状态代码和时间戳,例如:
ID STATUS TIMESTAMP
------------------------------------
12345 10 2020-08-01 11:00:01
12345 20 2020-08-01 11:01:24
12345 30 2020-08-01 11:07:42
我想将所有状态变化和时间排成一行,所以我最后得到:
ID STATUS TIMESTAMP STATUS TIMESTAMP STATUS TIMESTAMP
-----------------------------------------------------------------------------------------------------
12345 10 2020-08-01 11:00:01 20 2020-08-01 11:01:24 30 2020-08-01 11:07:42
我可以通过对每个状态进行连接来完成此操作,因此我的查询如下所示:
with T1 as
(SELECT distinct
id as 'ID',
Status as 'STATUS',
Timestamp as 'Time10'
from StatusHistory S
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
and Status = '10'),
T2 as
(SELECT distinct
id as 'ID',
Status as 'STATUS',
Timestamp as 'Time20'
from StatusHistory S
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
and Status = '20')
Select * from T1
join T2 on T1.ID = T2.ID
这行得通,但我必须对每个状态都这样做,并且大约有 12 个不同的状态代码。我已经阅读了几个进行草书连接的示例,并理解了这个概念,但实际上将它应用于我的查询时遇到了很多麻烦。本质上我想说的是递归位是 Status = Previous Status + 10
, 但是如何实现这个很麻烦。
我不明白如何获取最近的状态并向其添加 10。
您可以使用条件聚合:
select id,
max(case when seqnum = 1 then status end) as status_1,
max(case when seqnum = 1 then timestamp end) as timestamp_1,
max(case when seqnum = 2 then status end) as status_2,
max(case when seqnum = 2 then timestamp end) as timestamp_2,
max(case when seqnum = 3 then status end) as status_3,
max(case when seqnum = 3 then timestamp end) as timestamp_3
from (select sh.*,
row_number() over (partition by id order by timestamp) as seqnum
from StatusHistory sh
where TimeStamp > '2020-01-07 11:00' and
Timestamp < '2020-01-07 11:10'
) sh
group by id
Gordon Linoff 的解决方案非常适合我,但后来我了解了 PIVOT 函数,经过反复试验,发现以下给了我想要的 table 结果:
SELECT * FROM
(
SELECT
id,
status,
timestamp
FROM StatusHistory
where TimeStamp > '2020-01-07 11:00'
and Timestamp < '2020-01-07 11:10'
) dat
PIVOT
(
MAX(Timestamp) FOR Status IN ([10], [20], [30], [40], [50], [60], [70], [80], [90], [100], [170])
) pvt
order by 10
这给了我这样的结果:
ID 10 20 30
12345 2020-01-08 11:00:01 2020-01-08 11:01:24 2020-01-08 11:07:42