【发布时间】:2020-01-08 12:12:59
【问题描述】:
我有一个 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。
【问题讨论】:
-
SQL 查询具有固定数量的列。你知道你的结果集中的那些列是什么吗?
-
抱歉,我不确定我是否完全理解这个问题。我想要的结果中的列是 ID、Status 和 Timestamp,并且是 statushistory 表中的列。
-
“我想要的结果中的列是 ID、Status 和 Timestamp” 但是您的预期结果集中有 3 个
status列,而不是 1。有 2 (或更多)数据集中具有相同名称的列通常不是一个好主意。许多应用程序不处理它(很好)。如果您的预期输出 是 正确的,为什么要使用这种非规范化格式?如果某人在同一天有 10 个状态,那么您是否期望 21 列?状态数量的上限是多少?考虑到我们的样本是 7 分钟内 3 个,这是否意味着您可能需要 400 多列? -
啊,好吧,我明白了,时间戳只是一列,所以 ID 在上午 11 点达到状态 10,然后表格在上午 1:02 获得一个新行,状态为 20,然后在 11 点达到状态 30: 04am 等,直到它达到“完成”状态。我希望它水平显示的原因是为了从一个状态到下一个状态进行一些时间差分析,即从状态 10 到 30 或 10 到 50 等需要多长时间。
-
对所用时间的分析最好按行而不是按列。您可以使用
LEAD/LAG轻松引用下一个/上一个时间的值。
标签: sql sql-server common-table-expression recursive-query