我正在开发一个SQL Server数据库,我需要跟踪生产操作结果的进展.每次操作(OP)都要try ,直到成功为止(outcome = 1).如果一个操作失败(outcome = 0),它将重试给定的次数,如果它通过,然后我们继续进行下一个操作.

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

id OP Outcome
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 Outcome OP 2 Outcome OP 3 Outcome OP 4 Outcome OP 5 Outcome
0 NULL NULL NULL NULL
0 NULL NULL NULL NULL
1 1 1 0 NULL
1 1 1 0 NULL
1 1 1 1 0
1 1 1 1 1

我try 使用窗口函数和条件聚合来构建查询,以透视数据,但我在正确传播结果和处理失败后的后续操作中遇到了困难.

到目前为止,我得到的最好结果是this fiddle,但我不能确定如何合并已经成功的操作的NULL值.

推荐答案

每个零都是一个逻辑组的结尾(结尾处隐含零).把零按相反的顺序数出来.polymer 比我最初认为的要复杂一些,但它起作用了:

with dataX as (
    select *,
        -count(case when outcome = 0 then 1 end) over (order by id desc) as grp
    from ops
)
select
    grp,
    case when max(op) > 1 then 1 else max(case when op = 1 then outcome end) end as op1outcome,
    case when max(op) > 2 then 1 else max(case when op = 2 then outcome end) end as op2outcome,
    case when max(op) > 3 then 1 else max(case when op = 3 then outcome end) end as op3outcome,
    case when max(op) > 4 then 1 else max(case when op = 4 then outcome end) end as op4outcome,
    case when max(op) > 5 then 1 else max(case when op = 5 then outcome end) end as op5outcome
from dataX
group by grp;

OP意识到我第一次try 的一个变化将成功地通过分析max()产生相同的结果.我已经意识到,如果不用聚合包装一些裸列(或者像OP那样添加到group by中),该查询就不会运行.这里的版本避免了这一点,支持聚合和case表达式.如果操作可以跳过,第二种方法可能会有一个优势,但我认为另一个目的是避免使用select distinct,并产生一个更简单的查询计划.

Sql相关问答推荐

SQL Google Sheets:UNIQUE/DISTINCT和编码查询函数

Select /过滤postgr中的树 struct

按每天的最大值分组

Access VBA SQL命令INSERT FOR MULTIME VALUE

如何在SQL Server中统计按备注分组的记录数

SQL计数条目大于日期,包括交叉表中的零

如何根据行状态设置正确的标志

将一个数组反嵌套到另外两个数组SQL中(Athena/presto)

根据时间、状态和相关行在PostgreSQL中的存在来删除行

提取连续时间戳范围的SQL

确定小数中使用的精度位数

复制行并根据 Oracle SQL 中其他表的值更改值

SQL ORACLE - 查找连续天数

如何在sparksql查询中使用日期值?

根据开始时间和结束时间计算has_impact字段

在 postgresql 中保存带有时间戳的几何类型数据

如何使用子查询锁定此查询中的选定行?

使用一组值进行分组和计数

从不同的表中 Select 包含单词列表的记录

SQL中所有先前日期的累计总和