基于前一列值的列值

Column value based on previous column value

我在 Oracle 上有这样的结果集 table:

有没有办法添加一个新列,其值基于之前的 TEMREGIONAL 列:

311,1,1,0
430,2,0,1
329,3,0,1

我要的是根据TEMREGIONAL的值,如果是1,那么之后的所有行都是1到。

所以如果我有类似的东西:

311,1,0
430,2,0
329,3,1
334,4,0
323,5,0
324,6,0
326,7,0

结果应该是:

311,1,0,0
430,2,0,0
329,3,1,0
334,4,0,1
323,5,0,1
324,6,0,1
326,7,0,1

我想要的是添加一个新列,在第三列值为 1 的行之后,该新列中的所有行都应具有值 1。

有人可以帮助我吗?

示例数据

SQL> select * from test order by ord;

ID_ORGAO_INTELIGENCIA        ORD TERMREGIONAL
--------------------- ---------- ------------
                  311          1            0
                  430          2            0
                  329          3            1
                  334          4            0
                  323          5            0
                  324          6            0
                  326          7            0

7 rows selected.

这可能是一种选择:

SQL> with
  2  temp as
  3    -- find minimal ORD for which TERMREGIONAL = 1
  4    (select min(a.ord) min_ord
  5     from test a
  6     where a.termregional = 1
  7    )
  8  select t.id_orgao_inteligencia,
  9         t.ord,
 10         t.termregional,
 11         case when t.ord > m.min_ord then 1 else 0 end new_column
 12  from temp m cross join test t
 13  order by t.ord;

ID_ORGAO_INTELIGENCIA        ORD TERMREGIONAL NEW_COLUMN
--------------------- ---------- ------------ ----------
                  311          1            0          0
                  430          2            0          0
                  329          3            1          0
                  334          4            0          1
                  323          5            0          1
                  324          6            0          1
                  326          7            0          1

7 rows selected.

SQL>

您可以使用 ignore nulls 添加 lag 来查找前面的 1,将零变为 null。这可以一次完成。

with a(
  ID_ORGAO_INTELIGENCIA
  , ORD
  , TEMREGIONAL
) as (
select 311,1,0 from dual union all
select 430,2,0 from dual union all
select 329,3,1 from dual union all
select 334,4,0 from dual union all
select 323,5,0 from dual union all
select 324,6,0 from dual union all
select 326,7,0 from dual
)
select
  a.*
  , coalesce(
      lag(nullif(TEMREGIONAL, 0))
      ignore nulls
      over(order by ord asc)
    , 0) as prev
from a
ID_ORGAO_INTELIGENCIA | ORD | TEMREGIONAL | PREV
--------------------: | --: | ----------: | ---:
                  311 |   1 |           0 |    0
                  430 |   2 |           0 |    0
                  329 |   3 |           1 |    0
                  334 |   4 |           0 |    1
                  323 |   5 |           0 |    1
                  324 |   6 |           0 |    1
                  326 |   7 |           0 |    1

db<>fiddle here