如何在SQL中编写此逻辑

时间:2019-03-26 09:17:33

标签: sql sql-server

有一个包含3列的表,并且每2分钟生成一条新记录。

ID:按顺序(按时间顺序以及日期和时间戳记)为每个记录生成一个ID

时间:日期和时间戳(每2分钟精确运行一次)

标志:0或1(1表示好,0表示差)

我想写一个条件来检查标志是否为0或1 最后8分钟,4分钟之前和4分钟之后,8分钟之后

原始表:

MONITORID   CREATEDATETIME    Flag
209263      26/3/2019 16:56     1
209262      26/3/2019 16:54     1
209261      26/3/2019 16:52     1
209260      26/3/2019 16:50     1
209259      26/3/2019 16:48     1
209258      26/3/2019 16:46     1
209257      26/3/2019 16:44     1
209256      26/3/2019 16:42     1
209255      26/3/2019 16:40     1
209254      26/3/2019 16:38     1
209253      26/3/2019 16:36     1
209252      26/3/2019 16:34     1
209251      26/3/2019 16:32     1
209250      26/3/2019 16:30     1
209249      26/3/2019 16:28     1
209248      26/3/2019 16:26     1
209247      26/3/2019 16:24     1
209246      26/3/2019 16:22     1
209245      26/3/2019 16:20     1
209244      26/3/2019 16:18     1

最终结果应如下:

MONITORID   CREATEDATETIME    Flag  Flag_+4_-4  Flag_+0_-8
209263      26/3/2019 16:56     1       3           5
209262      26/3/2019 16:54     1       4           5
209261      26/3/2019 16:52     1       5           5
209260      26/3/2019 16:50     1       5           5
209259      26/3/2019 16:48     1       5           5
209258      26/3/2019 16:46     1       5           5
209257      26/3/2019 16:44     1       5           5
209256      26/3/2019 16:42     1       5           5
209255      26/3/2019 16:40     1       5           5
209254      26/3/2019 16:38     1       5           5
209253      26/3/2019 16:36     1       5           5
209252      26/3/2019 16:34     1       5           5
209251      26/3/2019 16:32     1       5           5
209250      26/3/2019 16:30     1       5           5
209249      26/3/2019 16:28     1       5           5
209248      26/3/2019 16:26     1       5           5
209247      26/3/2019 16:24     1       5           4
209246      26/3/2019 16:22     1       5           3
209245      26/3/2019 16:20     1       4           2
209244      26/3/2019 16:18     1       3           1

我们采用此逻辑的原因是在过去8分钟内查看一切是否良好。然后将其汇总到每日水平,以显示整天效果是否良好。

我们非常感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

这就是您所追求的。这使用条件聚合,并且ROWS BETWEEN子句计算Flag在定义的“范围”中具有值1的次数。但是,这要求,每两分钟间隔一次。如果不是,则 不会如您所愿:

WITH VTE AS(
    SELECT V.MONITORID,
           CONVERT(smalldatetime,V.CREATEDATETIME,103) AS CREATEDATETIME,
           Flag
    FROM (VALUES (209263,'26/3/2019 16:56',1),
                 (209262,'26/3/2019 16:54',1),
                 (209261,'26/3/2019 16:52',1),
                 (209260,'26/3/2019 16:50',1),
                 (209259,'26/3/2019 16:48',1),
                 (209258,'26/3/2019 16:46',1),
                 (209257,'26/3/2019 16:44',1),
                 (209256,'26/3/2019 16:42',1),
                 (209255,'26/3/2019 16:40',1),
                 (209254,'26/3/2019 16:38',1),
                 (209253,'26/3/2019 16:36',1),
                 (209252,'26/3/2019 16:34',1),
                 (209251,'26/3/2019 16:32',1),
                 (209250,'26/3/2019 16:30',1),
                 (209249,'26/3/2019 16:28',1),
                 (209248,'26/3/2019 16:26',1),
                 (209247,'26/3/2019 16:24',1),
                 (209246,'26/3/2019 16:22',1),
                 (209245,'26/3/2019 16:20',1),
                 (209244,'26/3/2019 16:18',1)) V(MONITORID, CREATEDATETIME, Flag))
SELECT V.MONITORID,
       V.CREATEDATETIME,
       V.Flag,
       COUNT(CASE V.Flag WHEN 1 THEN 1 END) OVER (ORDER BY V.CREATEDATETIME
                                                  ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) AS [Flag-4+4],
       COUNT(CASE V.Flag WHEN 1 THEN 1 END) OVER (ORDER BY V.CREATEDATETIME
                                                  ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS [Flag-8+0]
FROM VTE V
ORDER BY V.CREATEDATETIME DESC;