我正在尝试在 SQL 中创建一个视图,该视图合并开始日期时间和最后日期时间,并在值列更改时进行拆分,因为知道日期差异的值不固定。例如我有一个表名称 Sensors:
传感器ID | 开始时间 | 时间结束 | 价值 |
---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 00:20:00.000 | 1 |
14033 | 2023-05-01 00:20:00.000 | 2023-05-01 03:00:00.000 | 1 |
14033 | 2023-05-01 03:00:00.000 | 2023-05-01 12:00:00.000 | 1 |
14033 | 2023-05-01 12:00:00.000 | 2023-05-01 20:00:00.000 | 0 |
14033 | 2023-05-01 20:00:00.000 | 2023-05-01 22:59:59.000 | 0 |
结果必须如下表所示:
传感器ID | 开始时间 | 时间结束 | 价值 |
---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 12:00:00.000 | 1 |
14033 | 2023-05-01 12:00:00.000 | 2023-05-01 22:59:59.000 | 0 |
基于此示例,这里是一些代码,受到 Itzik Ben-Gan 的启发,特殊岛屿解决方案是链接。
(我添加了 CTE 以便更好地理解)
CREATE VIEW dbo.vw_Sensors
AS
with CTE_Source AS
(
SELECT * ,
LAG(EndTime,1,NULL) OVER(PARTITION BY SensorID ORDER BY StartTime) as EndTime_prev,
LAG(Value,1,NULL) OVER(PARTITION BY SensorID ORDER BY StartTime) as Value_prev
FROM dbo.Sensors
)
,CTE_Source2 AS
(
SELECT * ,
CASE WHEN s.StartTime <> ISNULL(s.EndTime_prev,'19000101') THEN 1
WHEN s.Value <> ISNULL(s.Value_prev,-1) THEN 1
ELSE 0
END as IsGrp
FROM CTE_Source as s
)
,CTE_Source3 AS
(
SELECT * ,
SUM(s.isGrp) OVER(PARTITION BY s.SensorID ORDER BY StartTime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as sumGrp
FROM CTE_Source2 as s
)
SELECT s.SensorID,
MIN(s.StartTime) as StartTime,
MAX(s.EndTime) as EndTime,
MAX(s.Value) as Value
FROM CTE_Source3 as s
GROUP BY
s.SensorID,
s.sumGrp
GO
Run Code Online (Sandbox Code Playgroud)
输出:
传感器ID | 开始时间 | 时间结束 | 价值 |
---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 12:00:00.000 | 1 |
14033 | 2023-05-01 12:00:00.000 | 2023-05-01 22:59:59.000 | 0 |
在步骤 1(第一个)中,我们只计算和 的select
先前值EndTime
Value
传感器ID | 开始时间 | 时间结束 | 价值 | 结束时间_上一个 | 上一个值 |
---|---|---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 | 无效的 | 无效的 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 00:20:00.000 | 1 | 2023-05-01 00:05:00.000 | 0 |
14033 | 2023-05-01 00:20:00.000 | 2023-05-01 03:00:00.000 | 1 | 2023-05-01 00:20:00.000 | 1 |
StartTime
步骤2,如果和之间有差异,或者和 之间previous EndTime
有差异,那么我们将此行标记为Value
previous Value
1 = IsGrp
传感器ID | 开始时间 | 时间结束 | 价值 | 结束时间_上一个 | 上一个值 | 是Grp |
---|---|---|---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 | 无效的 | 无效的 | 1 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 00:20:00.000 | 1 | 2023-05-01 00:05:00.000 | 0 | 1 |
14033 | 2023-05-01 00:20:00.000 | 2023-05-01 03:00:00.000 | 1 | 2023-05-01 00:20:00.000 | 1 | 0 |
在步骤 3 中,我们应用SUM
这个新字段 (isGrp) 。
传感器ID | 开始时间 | 时间结束 | 价值 | 结束时间_上一个 | 上一个值 | 是Grp | 总和 |
---|---|---|---|---|---|---|---|
14033 | 2023-05-01 00:00:00.000 | 2023-05-01 00:05:00.000 | 0 | 无效的 | 无效的 | 1 | 1 |
14033 | 2023-05-01 00:05:00.000 | 2023-05-01 00:20:00.000 | 1 | 2023-05-01 00:05:00.000 | 0 | 1 | 2 |
14033 | 2023-05-01 00:20:00.000 | 2023-05-01 03:00:00.000 | 1 | 2023-05-01 00:20:00.000 | 1 | 0 | 2 |
14033 | 2023-05-01 03:00:00.000 | 2023-05-01 12:00:00.000 | 1 | 2023-05-01 03:00:00.000 | 1 | 0 | 2 |
最后一步/选择只是聚合这些信息以显示所需的输出
归档时间: |
|
查看次数: |
299 次 |
最近记录: |