Sql 在同一列中的1之间计算0

Sql 在同一列中的1之间计算0,sql,oracle,Sql,Oracle,我有这样的数据 ID IND 1 0 2 0 3 1 4 0 5 1 6 0 7 0 我想在值1之前数零。因此,输出如下所示 ID IND OUT 1 0 0 2 0 0 3 1 2 4 0 0 5 1 1 6 0 0 7 0 2 没有pl/sql是否可能?我试图找出行号之间的差异,但未能实现。您可以将其视为一个间隙和孤岛问题。您可以通过“1”的个数或每行后面的个数来定义“孤岛”。然后使用

我有这样的数据

ID  IND
1   0
2   0
3   1
4   0
5   1
6   0
7   0
我想在值1之前数零。因此,输出如下所示

ID  IND  OUT
1   0    0
2   0    0
3   1    2
4   0    0
5   1    1
6   0    0
7   0    2

没有pl/sql是否可能?我试图找出行号之间的差异,但未能实现。

您可以将其视为一个间隙和孤岛问题。您可以通过“1”的个数或每行后面的个数来定义“孤岛”。然后使用窗口功能:

select t.*,
       (case when ind = 1 or row_number() over (order by id desc) = 1
             then sum(1 - ind) over (partition by grp)
             else 0
        end) as num_zeros
from (select t.*,
             sum(ind) over (order by id desc) as grp
      from t
     ) t;
如果
id
是连续的,没有间隙,则无需子查询即可执行此操作:

select t.*,
       (case when ind = 1 or row_number() over (order by id desc) = 1
             then id - coalesce(lag(case when ind = 1 then id end ignore nulls) over (order by id), min(id) over () - 1)
             else 0
        end)
from t;

我建议删除
case
条件,只对表达式使用
then
子句,这样所有行上都有值。

您可以将此视为间隙和孤岛问题。您可以通过“1”的个数或每行后面的个数来定义“孤岛”。然后使用窗口功能:

select t.*,
       (case when ind = 1 or row_number() over (order by id desc) = 1
             then sum(1 - ind) over (partition by grp)
             else 0
        end) as num_zeros
from (select t.*,
             sum(ind) over (order by id desc) as grp
      from t
     ) t;
如果
id
是连续的,没有间隙,则无需子查询即可执行此操作:

select t.*,
       (case when ind = 1 or row_number() over (order by id desc) = 1
             then id - coalesce(lag(case when ind = 1 then id end ignore nulls) over (order by id), min(id) over () - 1)
             else 0
        end)
from t;

我建议删除
case
条件,只对表达式使用
then
子句,因此值在所有行上。

Oracle 12.1中引入的
match\u recognize
子句可以快速解决此类“行模式识别”问题。由于对ID=0的“最后一行”进行了特殊处理,解决方案有点复杂,但在其他方面则很简单

通常,
with
子句不是解决方案的一部分;我包括它来测试查询。删除它并使用实际的表名和列名

with
  inputs (id, ind) as (
    select 1, 0 from dual union all
    select 2, 0 from dual union all
    select 3, 1 from dual union all
    select 4, 0 from dual union all
    select 5, 1 from dual union all
    select 6, 0 from dual union all
    select 7, 0 from dual
  )
select id, ind, out
from   inputs
match_recognize(
  order by id
  measures case classifier() when 'Z' then 0 
                             when 'O' then count(*) - 1
                             else          count(*)     end as out
  all rows per match
  pattern  ( Z* ( O | X ) )
  define   Z as ind = 0, O as ind != 0
);

        ID        IND        OUT
---------- ---------- ----------
         1          0          0
         2          0          0
         3          1          2
         4          0          0
         5          1          1
         6          0          0
         7          0          2

Oracle 12.1中引入的
match\u recognition
子句可以快速解决此类“行模式识别”问题。由于对ID=0的“最后一行”进行了特殊处理,解决方案有点复杂,但在其他方面则很简单

通常,
with
子句不是解决方案的一部分;我包括它来测试查询。删除它并使用实际的表名和列名

with
  inputs (id, ind) as (
    select 1, 0 from dual union all
    select 2, 0 from dual union all
    select 3, 1 from dual union all
    select 4, 0 from dual union all
    select 5, 1 from dual union all
    select 6, 0 from dual union all
    select 7, 0 from dual
  )
select id, ind, out
from   inputs
match_recognize(
  order by id
  measures case classifier() when 'Z' then 0 
                             when 'O' then count(*) - 1
                             else          count(*)     end as out
  all rows per match
  pattern  ( Z* ( O | X ) )
  define   Z as ind = 0, O as ind != 0
);

        ID        IND        OUT
---------- ---------- ----------
         1          0          0
         2          0          0
         3          1          2
         4          0          0
         5          1          1
         6          0          0
         7          0          2

在ID=7下显示的2没有意义。您仅在零序列结束(附加到具有非零IND的ID)后显示计数,为什么输出的最后一行中的计数不同?@mathguy这是因为边缘情况,在结束之前有两个零,需要更改considered@user14999956 . . . “为什么不把计数放在所有行上呢?”戈登·林诺夫,怎么做?我没有单独的值来进行分区和计数。您在OUT下面显示的ID=7的2没有意义。您仅在零序列结束(附加到具有非零IND的ID)后显示计数,为什么输出的最后一行中的计数不同?@mathguy这是因为边缘情况,在结束之前有两个零,需要更改considered@user14999956 . . . “为什么不把计数放在所有行上呢?”戈登·林诺夫,怎么做?这两种解决方案都忽略了一个特殊要求,即如果最后一行的IND=0,则该行的输出必须显示该组的零计数。看看我对OP的问题和他的答案。此外,第二个查询不计算零,它计算组中的所有行(因此,除了修复“最后一行的IND=0”问题外,还必须修复计数-减去1)。这两种解决方案都忽略了一个特殊要求,即如果最后一行的IND=0,则该行的输出必须显示该组的零计数。看看我对OP的问题和他的答案。此外,第二个查询不计算零,它计算组中的所有行(因此,除了修复“最后一行的IND=0”问题外,还必须修复计数-减去1)。