为组生成具有相同值的序列

时间:2019-02-26 19:29:15

标签: oracle oracle11g snowflake

我在表格中有以下值:

|  Val1  |  
| 201900 |  
| 201910 |  
| 201920 |
| 201930 |
| 201901 |
| 201911 |
| 201921 |  
| 201931 |  
| 201902 |  
| 201912 | 
| 201922 | 
| 201932 |  

最后一个数字是2019年的级别(0,1,2,..)。第二个最后一个数字是在特定日期有效的标识符。意味着0在201900的3个月内有效,三个月后将添加新值201910。例如,对于级别0和1,在给定时间将有两个不同的活动记录,分别为201900和201901。我想为这两个记录分配相同的序列号。输出应如下所示:

|  Val1  | Seq |  
| 201900 |  1  |
| 201910 |  2  |
| 201920 |  3  |
| 201930 |  4  |
| 201901 |  1  | 
| 201911 |  2  |
| 201921 |  3  |
| 201931 |  4  |
| 201902 |  1  |
| 201912 |  2  |
| 201922 |  3  |
| 201932 |  4  |

我正在使用Snowflake云DW,但是Oracle语法应该可以正常工作。但是Snowflake按顺序没有CurrVal选项。
我正在尝试此方法,但是不起作用:

> (SUBSTRING(Val1,6,1)=0 OR SUBSTRING(Val1,6,1)=1
> OR SUBSTRING(Val1,6,1)=2 OR
> SUBSTRING(Val1,6,1)=3 OR SUBSTRING(Val1,6,1)=4 
>     OR SUBSTRING(Val1,6,1)=5) THEN (SELECT  s.nextval FROM table(getnextval(test_seq)) s)

2 个答案:

答案 0 :(得分:1)

像这样?有用的部分是第16-17行。

SQL> with test (val1) as
  2    (select 201900 from dual union all
  3     select 201910 from dual union all
  4     select 201920 from dual union all
  5     select 201930 from dual union all
  6     select 201901 from dual union all
  7     select 201911 from dual union all
  8     select 201921 from dual union all
  9     select 201931 from dual union all
 10     select 201902 from dual union all
 11     select 201912 from dual union all
 12     select 201922 from dual union all
 13     select 201932 from dual
 14    )
 15  select val1,
 16    row_number() over (partition by substr(val1, 1, 4), substr(val1, -1)
 17                       order by substr(val1, 5, 1)) seq
 18  from test;

      VAL1        SEQ
---------- ----------
    201900          1
    201910          2
    201920          3
    201930          4
    201901          1
    201911          2
    201921          3
    201931          4
    201902          1
    201912          2
    201922          3
    201932          4

12 rows selected.

SQL>

答案 1 :(得分:1)

如果VAL1列的数据类型为NUMBER,为什么不这样做呢?

offsetY

输出:

with test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual)
select val1,
  row_number() over (partition by trunc(val1/100), mod(val1, 10)
                     order by mod(trunc(val1/10), 10)) seq
from test;

更新#1:

您要询问的是OUTER JOIN。但是,也许您需要LAG分析功能的功能?我还认为不需要按标识符排序,因为在按年份和级别划分之后,VAL1列值使我们对结果分区进行自然排序。

+--------+-----+
|  VAL1  | SEQ |
+--------+-----+
| 201900 |   1 |
| 201910 |   2 |
| 201920 |   3 |
| 201930 |   4 |
| 201901 |   1 |
| 201911 |   2 |
| 201921 |   3 |
| 201931 |   4 |
| 201902 |   1 |
| 201912 |   2 |
| 201922 |   3 |
| 201932 |   4 |
+--------+-----+

输出:

with
  test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual),
  t as
  (select
     test.*,
     row_number() over (partition by trunc(val1/100), mod(val1, 10)
                        order by val1) as seq
   from test)
select
  a.*, b.val1 as prev_value
from t a
left outer join t b
  on trunc(a.val1/100) = trunc(b.val1/100) and
     mod(a.val1, 10) = mod(b.val1, 10) and
     a.seq = b.seq + 1
order by trunc(a.val1/100), mod(a.val1, 10), a.val1;

LAG分析功能:

+--------+-----+------------+
|  VAL1  | SEQ | PREV_VALUE |
+--------+-----+------------+
| 201900 |   1 |            |
| 201910 |   2 |     201900 |
| 201920 |   3 |     201910 |
| 201930 |   4 |     201920 |
| 201901 |   1 |            |
| 201911 |   2 |     201901 |
| 201921 |   3 |     201911 |
| 201931 |   4 |     201921 |
| 201902 |   1 |            |
| 201912 |   2 |     201902 |
| 201922 |   3 |     201912 |
| 201932 |   4 |     201922 |
+--------+-----+------------+

输出:

with test (val1) as
  (select 201900 from dual union all
   select 201910 from dual union all
   select 201920 from dual union all
   select 201930 from dual union all
   select 201901 from dual union all
   select 201911 from dual union all
   select 201921 from dual union all
   select 201931 from dual union all
   select 201902 from dual union all
   select 201912 from dual union all
   select 201922 from dual union all
   select 201932 from dual)
select val1,
  lag(val1) over (partition by trunc(val1/100), mod(val1, 10)
                  order by val1) as prev_value
from test;

使用db<>fiddle在线进行测试。