首页 > 解决方案 > 排除意义相同但值不同的行

问题描述

我有以下数据:

Time                    ID              Context                     Value
----------------------- --------------- ----------                  -----
2021-02-03 10:07:32.777 359586015047527 TwigStatus                  4
2021-02-03 10:07:32.777 359586015047527 SafeProtectDeviceConnected  False
2021-02-03 10:07:32.580 359586015047527 ConnectionLost              True

所有行都具有相同的语义。SafeProtectDeviceConnected由于第二行(上下文= ),我需要一个查询来排除它们

因此,使用上面的数据集,结果集将是:

Time                    ID              Context                     Value
----------------------- --------------- ----------                  -----

如果数据集是:

Time                    ID              Context                     Value
----------------------- --------------- ----------                  -----
2021-02-03 10:07:32.777 359586015047527 TwigStatus                  4
2021-02-03 10:07:32.580 359586015047527 ConnectionLost              True

我想要只有一排,不管是哪一排。

最后,如果数据集是:

Time                    ID              Context                     Value
----------------------- --------------- ----------                  -----
2021-02-03 10:07:32.580 359586015047527 ConnectionLost              True

我想退回这一行。

我试图在我的 SELECT 语句中向我的数据集添加新列:

row_number() over (partition by ID order by Time desc) AS row_num

和:

CASE WHEN Context = 'SafeProtectDeviceConnected' THEN 1 WHEN Context = 'TwigStatus' THEN 2 WHEN Context = 'ConnectionLost' THEN 3 END AS row_num2

但是我无法通过过滤子句来获得所需的结果。


编辑:业务逻辑是这样的:

这是最好的情况。

因为一切都可能出错并且为了保持与现有应用程序和工具的兼容性,我们可以在数据库中保存三个、两个或一个记录来告知设备处于脱机状态。

标签: sql-server

解决方案


我想这就是你想要的?

用于NOT EXISTS()获取ID不包含SafeProtectDeviceConnected. 用于ROW_NUMBER()每个 ID 仅获取一行

SELECT *
FROM
(
    SELECT *, rn = row_number() over (partition by T.ID order by T.Time)
    FROM   yourtable T
    WHERE  NOT EXISTS
    (
          SELECT *
          FROM   yourtable X
          WHERE  X.ID = T.ID
          AND    X.Context = 'SafeProtectDeviceConnected'
    )    
) D
WHERE D.rn = 1

推荐阅读