为一组生成具有相同值的序列
Generating Sequence with Same Values for a Group
我低于 table 中的值:
| Val1 |
| 201900 |
| 201910 |
| 201920 |
| 201930 |
| 201901 |
| 201911 |
| 201921 |
| 201931 |
| 201902 |
| 201912 |
| 201922 |
| 201932 |
最后一位是2019年的级别(0,1,2,..)。倒数第二位是在特定日期有效的标识符。意味着 0 在 201900 中的 3 个月内有效,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)
是这样的吗?有用的部分是第 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>
如果 VAL1 列的数据类型是 NUMBER 那么为什么不这样做呢?
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;
输出:
+--------+-----+
| 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 |
+--------+-----+
更新#1:
你问的是OUTER JOIN
. But maybe you need the functionality of the LAG
解析函数?我还认为没有必要按标识符排序,因为在按年份和级别分区后,VAL1 列值为我们提供了结果分区中的自然排序。
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;
输出:
+--------+-----+------------+
| 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 |
+--------+-----+------------+
LAG解析函数:
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;
输出:
+--------+------------+
| VAL1 | PREV_VALUE |
+--------+------------+
| 201900 | |
| 201910 | 201900 |
| 201920 | 201910 |
| 201930 | 201920 |
| 201901 | |
| 201911 | 201901 |
| 201921 | 201911 |
| 201931 | 201921 |
| 201902 | |
| 201912 | 201902 |
| 201922 | 201912 |
| 201932 | 201922 |
+--------+------------+
使用 db<>fiddle 在线测试。
我低于 table 中的值:
| Val1 | | 201900 | | 201910 | | 201920 | | 201930 | | 201901 | | 201911 | | 201921 | | 201931 | | 201902 | | 201912 | | 201922 | | 201932 |
最后一位是2019年的级别(0,1,2,..)。倒数第二位是在特定日期有效的标识符。意味着 0 在 201900 中的 3 个月内有效,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)
是这样的吗?有用的部分是第 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>
如果 VAL1 列的数据类型是 NUMBER 那么为什么不这样做呢?
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;
输出:
+--------+-----+
| 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 |
+--------+-----+
更新#1:
你问的是OUTER JOIN
. But maybe you need the functionality of the LAG
解析函数?我还认为没有必要按标识符排序,因为在按年份和级别分区后,VAL1 列值为我们提供了结果分区中的自然排序。
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;
输出:
+--------+-----+------------+
| 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 |
+--------+-----+------------+
LAG解析函数:
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;
输出:
+--------+------------+
| VAL1 | PREV_VALUE |
+--------+------------+
| 201900 | |
| 201910 | 201900 |
| 201920 | 201910 |
| 201930 | 201920 |
| 201901 | |
| 201911 | 201901 |
| 201921 | 201911 |
| 201931 | 201921 |
| 201902 | |
| 201912 | 201902 |
| 201922 | 201912 |
| 201932 | 201922 |
+--------+------------+
使用 db<>fiddle 在线测试。