【发布时间】:2021-02-02 10:38:04
【问题描述】:
我有一个包含以下数据的表格:
VehicleID Time ContextID Value
--------------- ----------------------- -------------------------- -----
359586015047188 2021-02-01 07:27:14.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 07:53:38.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 07:53:47.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 10:24:20.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 10:26:46.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 10:26:55.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 10:43:53.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 10:46:01.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 10:46:09.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 11:02:16.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 14:39:41.777 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 14:39:42.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 14:55:48.777 SafeProtectDeviceConnected False
359586015047188 2021-02-02 07:52:12.777 SafeProtectDeviceConnected True
359586015047188 2021-02-02 07:52:12.777 SafeProtectProtectionLevel 5
359586015047188 2021-02-02 07:52:32.777 SafeProtectDeviceConnected False
359586015047188 2021-02-02 07:53:57.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-02 07:54:10.777 SafeProtectDeviceConnected True
如您所见,数据是及时插入的。但有时,时间是不正确的。我需要一个查询来修复它。
如果数据是一致的,我总是会有一行 ContextID 的值是 SafeProtectDeviceConnected 并且 Value 的值是 True 后跟一行 ContextID 的值 SafeProtectProtectionLevel 无论 Value 的值是什么列。
我发现我可以使用 LAG 分析函数来访问前一行的值,并且我还可以将一个或多个 CASE 放入 order by clause
那么在前一个结果集上应用修复查询后的正确结果将是:
VehicleID Time ContextID Value
--------------- ----------------------- -------------------------- -----
359586015047188 2021-02-01 07:27:14.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 07:53:47.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 07:53:38.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 10:24:20.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 10:26:55.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 10:26:46.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 10:43:53.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 10:46:09.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 10:46:01.000 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 11:02:16.777 SafeProtectDeviceConnected False
359586015047188 2021-02-01 14:39:42.777 SafeProtectDeviceConnected True
359586015047188 2021-02-01 14:39:41.777 SafeProtectProtectionLevel 5
359586015047188 2021-02-01 14:55:48.777 SafeProtectDeviceConnected False
359586015047188 2021-02-02 07:52:12.777 SafeProtectDeviceConnected True
359586015047188 2021-02-02 07:52:12.777 SafeProtectProtectionLevel 5
359586015047188 2021-02-02 07:52:32.777 SafeProtectDeviceConnected False
359586015047188 2021-02-02 07:54:10.777 SafeProtectDeviceConnected True
359586015047188 2021-02-02 07:53:57.000 SafeProtectProtectionLevel 5
基本上,如果我们查看上面重新排序的结果集,特别是从上到下的 Value 列,我们应该有一个 True 值,后跟一个或多个带有数值的行,然后是一个 False 值
到目前为止我尝试过的是使用ORDER BY t.VehiculeID, /*dbo.ContextDetail.Time*/ CASE WHEN t.ContextID='SafeProtectDeviceConnected' AND t.Value='True' THEN 1 END, CASE WHEN t.ContextID='SafeProtectProtectionLevel' THEN 2 END, CASE WHEN t.ContextID='SafeProtectDeviceConnected' AND t.Value='False' THEN 3 END
但它给了我(显然)所有False 行,然后是所有numeric rows,然后是剩余的True 值。
这个问题是缝隙和孤岛问题吗?
解决这个问题的正确方法是什么?
【问题讨论】:
-
试试这个:ORDER BY VehicleID, CAST(CONVERT(NVARCHAR(8), [Time], 112) AS BIGINT)*10000 + DATEPART(HOUR, [Time])* 100 + DATEPART(MINUTE , [Time]), CASE WHEN ContextID = 'SafeProtectDeviceConnected' AND [Value] = 'False' THEN 1 WHEN ContextID = 'SafeProtectDeviceConnected' AND [Value] = 'True' THEN 2 ELSE 3 END
-
@Tyron78 这似乎可行,但我想了解原因。
-
我添加了我的查询作为答案和一个小解释 - 请检查。如有其他问题,请随时提问。
标签: sql-server gaps-and-islands