在Oracle中的分组列上创建数字序列 查询结果

问题描述

请在表格下方使用a,b,c列。

a   b   c
3   4   5
3   4   5
6   4   1
1   1   8
1   1   8
1   1   0
1   1   0

我需要一条select语句才能获得以下输出。即基于列a,b,c的列递增“ rn”列。

a   b   c   rn
3   4   5   1
3   4   5   1
6   4   1   2
1   1   8   3
1   1   8   3
1   1   0   4
1   1   0   4

解决方法

首先,要使您的答案完全有意义,您需要一列来定义行的顺序。让我假设您有一个名为id的列。

然后,您可以使用窗口功能:

select a,b,c,sum(case when a = lag_a and b = lag_b and c = lag_c then 0 else 1 end) over(order by id) rn
from (
    select t.*,lag(a) over(order by id) lag_a,lag(b) over(order by id) lag_b,lag(c) over(order by id) lag_c
    from mytable t
) t
,

您可以使用DENSE_RANK分析函数为A,B和C的每种组合获取唯一的ID。请注意,如果将新值插入表中,则A的每种组合的ID ,B和C将移动,并且可能会不同。

查询

WITH
    my_table (a,c)
    AS
        (SELECT 3,4,5 FROM DUAL
         UNION ALL
         SELECT 3,5 FROM DUAL
         UNION ALL
         SELECT 6,1 FROM DUAL
         UNION ALL
         SELECT 1,1,8 FROM DUAL
         UNION ALL
         SELECT 1,0 FROM DUAL
         UNION ALL
         SELECT 1,0 FROM DUAL)
SELECT t.*,DENSE_RANK () OVER (ORDER BY b desc,c desc,a) as rn
  FROM my_table t;

结果

   A    B    C    RN
____ ____ ____ _____
   3    4    5     1
   3    4    5     1
   6    4    1     2
   1    1    8     3
   1    1    8     3
   1    1    0     4
   1    1    0     4
,

假设您可以通过某种方式对行进行排序,则可以使用MATCH_RECOGNIZE

SELECT a,rn
FROM   table_name
MATCH_RECOGNIZE (
  ORDER BY id
  MEASURES MATCH_NUMBER() AS rn
  ALL ROWS PER MATCH
  PATTERN ( FIRST_ROW EQUAL_ROWS* )
  DEFINE EQUAL_ROWS AS (
      EQUAL_ROWS.a = PREV( EQUAL_ROWS.a )
  AND EQUAL_ROWS.b = PREV( EQUAL_ROWS.b )
  AND EQUAL_ROWS.c = PREV( EQUAL_ROWS.c )
  )
)

因此,对于您的测试数据:

CREATE TABLE table_name ( id,a,c ) AS
SELECT 1,3,5 FROM DUAL UNION ALL
SELECT 2,5 FROM DUAL UNION ALL
SELECT 3,6,1 FROM DUAL UNION ALL
SELECT 4,8 FROM DUAL UNION ALL
SELECT 5,8 FROM DUAL UNION ALL
SELECT 6,0 FROM DUAL UNION ALL
SELECT 7,0 FROM DUAL;

输出:

 A |  B |  C | RN
-: | -: | -: | -:
 3 |  4 |  5 |  1
 3 |  4 |  5 |  1
 6 |  4 |  1 |  2
 1 |  1 |  8 |  3
 1 |  1 |  8 |  3
 1 |  1 |  0 |  4
 1 |  1 |  0 |  4

db 提琴here

,

通过获取不同的组并为每个组编号,也可以不进行任何排序。借用EJ Egjed的第一部分:

WITH  my_table (a,c)  AS
        (SELECT 3,0 FROM DUAL),groups as (select distinct a,c
            from my_table),groupnums as (select rownum as num,c 
           from groups)
select a,num
from   my_table join groupnums using(a,c);