Oracle分区依据 - 在组更改时选择ZERO或ONE

时间:2016-01-12 13:06:31

标签: oracle

我以这种方式排了几行:

ID      DESTINATION
1       A
2       A
3       B
4       B
5       B
6       C   

我想在DESTINATION更改时显示一个查询,并将其标记为0-1(在此之间切换)。

现在,我已经将分区用于"分区"目的地,结果如下:

ID      DESTINATION     OVER_PARTITION_BY
1       A               1
2       A               2
3       B               1  << Destination change
4       B               2
5       B               3
6       C               1  << Destination change

我需要的结果如下:

ID      DESTINATION     OVER_PARTITION_BY
1       A               1
2       A               1
3       B               0   << Group has changed, i switch from 1 to 0
4       B               0
5       B               0
6       C               1   << Group has changed, i switch from 0 to 1

1 个答案:

答案 0 :(得分:2)

例如 -

with t as
   (select 1 as id, 'A' as DESTINATION from dual union all
    select 2 as id, 'A' from dual union all
    select 3 as id, 'B' from dual union all
    select 4 as id, 'B' from dual union all
    select 5 as id, 'B' from dual union all
    select 6 as id, 'C' from dual)
select id, DESTINATION,  case when mod(dense_rank() over (order by DESTINATION), 2) = 0 then 0 else 1 end as grp_id
 from t
order by id

输出:

ID      DESTINATION     OVER_PARTITION_BY
1       A               1
2       A               1
3       B               0  << Destination change
4       B               0
5       B               0
6       C               1  << Destination change

另一个解决方案,如果DESTINATION的值可以重复而不是作为ID排序(不是最佳解决方案) -

with t as
   (select 1 as id, 'A' as DESTINATION from dual union all
    select 2 as id, 'A' from dual union all
    select 3 as id, 'B' from dual union all
    select 4 as id, 'B' from dual union all
    select 5 as id, 'B' from dual union all
    select 6 as id, 'C' from dual union all
    select 7 as id, 'A' from dual)
select id, destination, case when mod(dense_rank() over (order by gr_max),2) = 0 then 0 else 1 end as grp_id
from
   (select d.*, max(gr) over (partition by DESTINATION order by id) as gr_max
      from
       (select t.*,  case when DESTINATION = lag(DESTINATION) over (order by id) then null else dense_rank() over (order by id) end as gr
          from t) d) v
order by id

输出:

ID      DESTINATION     OVER_PARTITION_BY
1       A               1
2       A               1
3       B               0  << Destination change
4       B               0
5       B               0
6       C               1  << Destination change
7       A               0  << Destination change