使用条件 NULL 跟踪生产操作结果进度的 SQL 查询

问题描述 投票:0回答:1

我正在开发一个 SQL Server 数据库,需要跟踪生产操作结果的进展情况。尝试每个操作 (OP),直到成功(结果 = 1)。如果操作失败(结果 = 0),则会重试给定的次数,如果通过,则继续执行下一个操作。

操作存储在名为 Operations 的表中,如下所示:

id OP 结果
1 1 0
2 1 0
3 1 1
4 2 1
5 3 1
6 4 0
7 4 0
8 4 1
9 5 0
10 5 1

我想创建一个视图,以特定格式跨行显示每个操作的结果。如果操作失败,该行中的后续操作应显示为 NULL,直到操作成功。以下是 5 个操作所需的输出格式的示例:

OP 1 结果 OP 2 结果 OP 3 结果 OP 4 结果 OP 5 结果
0
0
1 1 1 0
1 1 1 0
1 1 1 1 0
1 1 1 1 1

我尝试使用窗口函数和条件聚合来构建查询来旋转数据,但我正在努力正确传播结果并在失败后处理后续操作的 NULL。

到目前为止我得到的最好结果显示在this fiddle中,但我无法弄清楚如何合并已经成功的操作的NULL值。

sql sql-server
1个回答
0
投票

这样的事情怎么样:

SELECT  CASE WHEN max(OP) > 1 THEN 1 ELSE MAX(CASE WHEN OP = 1 THEN Outcome END) END AS OP1
,   CASE WHEN max(OP) > 2 THEN 1 ELSE MAX(CASE WHEN OP = 2 THEN Outcome END) END AS OP2
,   CASE WHEN max(OP) > 3 THEN 1 ELSE MAX(CASE WHEN OP = 3 THEN Outcome END) END AS OP3
,   CASE WHEN max(OP) > 4 THEN 1 ELSE MAX(CASE WHEN OP = 4 THEN Outcome END) END AS OP4
,   CASE WHEN max(OP) > 5 THEN 1 ELSE MAX(CASE WHEN OP = 5 THEN Outcome END) END AS OP5
FROM    (
    SELECT  *
    ,   sum(flag) OVER(ORDER BY OP, Outcome rows BETWEEN unbounded preceding AND CURRENT row) AS counter
    
    FROM    (
        SELECT  *
        ,   CASE WHEN (lag(outcome) OVER(ORDER BY op,outcome) = outcome AND outcome = 1) OR (lag(outcome) OVER(ORDER BY op,outcome) <> outcome AND outcome = 0)
                THEN 0
                ELSE 1
            END AS flag
        FROM    (
            VALUES  (1, 0)
            ,   (1, 0)
            ,   (1, 1)
            ,   (2, 1)
            ,   (3, 1)
            ,   (4, 0)
            ,   (4, 0)
            ,   (4, 1)
            ,   (5, 0)
            ,   (5, 1)
        ) t (OP,Outcome)
        ) x
    ) x
GROUP BY x.counter
  1. 你需要的是创建“水平”,每当新的失败到来或新的成功时,它似乎都会增加,我称这个领域为

    flag

  2. 然后创建一个计数器来计算该标志的总和,这将创建实际级别。

  3. 最后,进行生成列的条件聚合。为了在操作完成后处理 1,我使用

    CASE WHEN max(OP) > 1 THEN 1
    构造。

输出:

OP1 OP2 OP3 OP4 OP5
0
0
1 1 1 0
1 1 1 0
1 1 1 1 0
1 1 1 1 1
© www.soinside.com 2019 - 2024. All rights reserved.