oracle - 按序列号分组的问题

标签 oracle plsql oracle11g

我基本上是在 sql 之后执行以下操作。我正在寻找与 B 列更改时相关的一组连续数字,但保持列 ID 按顺序排列 我尝试过 Dense Rank,但它总是抛出 ID 列的序列,这弄乱了我所追求的内容。有什么想法吗?

ID||A||B
01||T||1
02||T||1
03||T||0
04||T||0
05||T||1
06||T||1
07||T||1
08||T||0
09||T||1
10||T||1
11||T||0

进入

ID||A||B||C
01||T||1||1
02||T||1||1
03||T||0||2
04||T||0||3
05||T||1||4
06||T||1||4
07||T||1||4
08||T||0||5
09||T||1||6
10||T||1||6
11||T||0||7

最佳答案

--#3: Running total of value changes
select id, a, b
    ,sum(has_changed) over (partition by A order by id
        rows between unbounded preceding and current row) c
from
(
    --#2: Find rows where the value changed.
    select id, a, b
        ,case
            when b = lag(b) over (partition by A order by id) then 0
            else 1
        end has_changed    
    from
    (
        --#1: Test data
        select '01' ID, 'T' A, 1 B from dual union all
        select '02' ID, 'T' A, 1 B from dual union all
        select '03' ID, 'T' A, 0 B from dual union all
        select '04' ID, 'T' A, 0 B from dual union all
        select '05' ID, 'T' A, 1 B from dual union all
        select '06' ID, 'T' A, 1 B from dual union all
        select '07' ID, 'T' A, 1 B from dual union all
        select '08' ID, 'T' A, 0 B from dual union all
        select '09' ID, 'T' A, 1 B from dual union all
        select '10' ID, 'T' A, 1 B from dual union all
        select '11' ID, 'T' A, 0 B from dual
    ) test_data
)
order by id;

结果:

ID  A   B   C
01  T   1   1
02  T   1   1
03  T   0   2
04  T   0   2
05  T   1   3
06  T   1   3
07  T   1   3
08  T   0   4
09  T   1   5
10  T   1   5
11  T   0   6

不完全相同,尽管我认为你的示例有一个额外的增量,正如 @Adam Hawkes 指出的那样。


更新

这将产生您预期的结果:

--#3: Running total of value changes, or where the value is 0
select id, a, b
    ,sum(has_changed_or_0) over (partition by A order by id
        rows between unbounded preceding and current row) c
from
(
    --#2: Find rows where the value changed, or where value is 0
    select id, a, b
        ,case
            when b = 0 then 1
            when b = lag(b) over (partition by A order by id) then 0
            else 1
        end has_changed_or_0
    from
    (
        --#1: Test data
        select '01' ID, 'T' A, 1 B from dual union all
        select '02' ID, 'T' A, 1 B from dual union all
        select '03' ID, 'T' A, 0 B from dual union all
        select '04' ID, 'T' A, 0 B from dual union all
        select '05' ID, 'T' A, 1 B from dual union all
        select '06' ID, 'T' A, 1 B from dual union all
        select '07' ID, 'T' A, 1 B from dual union all
        select '08' ID, 'T' A, 0 B from dual union all
        select '09' ID, 'T' A, 1 B from dual union all
        select '10' ID, 'T' A, 1 B from dual union all
        select '11' ID, 'T' A, 0 B from dual
    ) test_data
)
order by id;

关于oracle - 按序列号分组的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11660742/

相关文章:

sql - 在 Oracle 中,查找大于一组数字的 80% 的数字

sql - 当数据丢失时插入表

oracle - 获取 PL/SQL : numeric or value error: character to number conversion error

oracle - PL/SQL 日志记录 - 如何控制?

oracle - 如何获取 Oracle 数据库中发生的插入/更新次数?

sql - 正确的 Oracle 查询

sql - 一次撤销多个用户的 Oracle 权限

sql - 如何在Oracle中多次更新与另一个表连接的表?

sql - 在 where 子句中使用 select 子句中的列号。提取别名原始名称

sql - 表分区,哪个更好?