组中的重复行达到给定值 Oracle
Duplicate rows in a group up to a given value Oracle
我需要复制每组中的排序行 -"n_group" 以便每组输出 5 行。组内应填入组前几行的值。
输入table:
n_group
n_sort
n_name
aa
1
pr_1
bb
1
pr_1
bb
2
pr_2
cc
1
pr_4
cc
2
pr_8
cc
3
pr_9
期望的结果:
n_group
n_sort
n_name
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
bb
1
pr_1
bb
2
pr_2
bb
1
pr_1
bb
2
pr_2
bb
1
pr_1
cc
1
pr_4
cc
2
pr_8
cc
3
pr_9
cc
1
pr_4
cc
2
pr_8
这是一个选项 - 它使用分层查询。看看有没有帮助。
示例数据:
SQL> with test (n_group, n_sort, n_name) as
2 (select 'aa', 1, 'pr_1' from dual union all
3 select 'bb', 1, 'pr_1' from dual union all
4 select 'bb', 2, 'pr_2' from dual union all
5 select 'cc', 1, 'pr_4' from dual union all
6 select 'cc', 2, 'pr_8' from dual union all
7 select 'cc', 3, 'pr_9' from dual
8 ),
查询从这里开始;将现有行乘以第 15 行的次数 returns; row_number
分析函数的结果稍后用于仅获取每个 n_group
.
的前 5 行
9 temp as
10 (select t.n_group, t.n_sort, t.n_name,
11 row_number() over (partition by n_group order by n_sort, n_name) rn
12 from test t cross join
13 table(cast(multiset(select level from dual
14 connect by level <=
15 (select 5 - case when max(b.n_sort) = 1 then 0 else max(b.n_sort) end
16 from test b
17 where b.n_group = t.n_group)
18 ) as sys.odcinumberlist))
19 )
20 select n_group, n_sort, n_name
21 from temp
22 where rn <= 5
23 order by n_group, n_sort, n_name;
结果:
N_GROUP N_SORT N_NAME
---------- ---------- ----------
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
bb 1 pr_1
bb 1 pr_1
bb 1 pr_1
bb 2 pr_2
bb 2 pr_2
cc 1 pr_4
cc 1 pr_4
cc 2 pr_8
cc 2 pr_8
cc 3 pr_9
15 rows selected.
您可以使用 PARTITION
ed 连接到 row-generator 函数:
SELECT n_group, n_sort, n_name
FROM ( SELECT LEVEL AS n FROM DUAL CONNECT BY LEVEL <= 5 ) l
INNER JOIN (
SELECT t.*,
COUNT(*) OVER (PARTITION BY n_group) AS n_rows
FROM table_name t
) t
PARTITION BY (t.n_group)
ON (MOD(l.n - 1, t.n_rows) + 1 = t.n_sort)
ORDER BY t.n_group, l.n;
其中,对于示例数据:
CREATE TABLE table_name (n_group, n_sort, n_name) AS
SELECT 'aa', 1, 'pr_1' FROM DUAL UNION ALL
SELECT 'bb', 1, 'pr_1' FROM DUAL UNION ALL
SELECT 'bb', 2, 'pr_2' FROM DUAL UNION ALL
SELECT 'cc', 1, 'pr_4' FROM DUAL UNION ALL
SELECT 'cc', 2, 'pr_8' FROM DUAL UNION ALL
SELECT 'cc', 3, 'pr_9' FROM DUAL;
输出:
N_GROUP
N_SORT
N_NAME
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
aa
1
pr_1
bb
1
pr_1
bb
2
pr_2
bb
1
pr_1
bb
2
pr_2
bb
1
pr_1
cc
1
pr_4
cc
2
pr_8
cc
3
pr_9
cc
1
pr_4
cc
2
pr_8
db<>fiddle here
我需要复制每组中的排序行 -"n_group" 以便每组输出 5 行。组内应填入组前几行的值。
输入table:
n_group | n_sort | n_name |
---|---|---|
aa | 1 | pr_1 |
bb | 1 | pr_1 |
bb | 2 | pr_2 |
cc | 1 | pr_4 |
cc | 2 | pr_8 |
cc | 3 | pr_9 |
期望的结果:
n_group | n_sort | n_name |
---|---|---|
aa | 1 | pr_1 |
aa | 1 | pr_1 |
aa | 1 | pr_1 |
aa | 1 | pr_1 |
aa | 1 | pr_1 |
bb | 1 | pr_1 |
bb | 2 | pr_2 |
bb | 1 | pr_1 |
bb | 2 | pr_2 |
bb | 1 | pr_1 |
cc | 1 | pr_4 |
cc | 2 | pr_8 |
cc | 3 | pr_9 |
cc | 1 | pr_4 |
cc | 2 | pr_8 |
这是一个选项 - 它使用分层查询。看看有没有帮助。
示例数据:
SQL> with test (n_group, n_sort, n_name) as
2 (select 'aa', 1, 'pr_1' from dual union all
3 select 'bb', 1, 'pr_1' from dual union all
4 select 'bb', 2, 'pr_2' from dual union all
5 select 'cc', 1, 'pr_4' from dual union all
6 select 'cc', 2, 'pr_8' from dual union all
7 select 'cc', 3, 'pr_9' from dual
8 ),
查询从这里开始;将现有行乘以第 15 行的次数 returns; row_number
分析函数的结果稍后用于仅获取每个 n_group
.
9 temp as
10 (select t.n_group, t.n_sort, t.n_name,
11 row_number() over (partition by n_group order by n_sort, n_name) rn
12 from test t cross join
13 table(cast(multiset(select level from dual
14 connect by level <=
15 (select 5 - case when max(b.n_sort) = 1 then 0 else max(b.n_sort) end
16 from test b
17 where b.n_group = t.n_group)
18 ) as sys.odcinumberlist))
19 )
20 select n_group, n_sort, n_name
21 from temp
22 where rn <= 5
23 order by n_group, n_sort, n_name;
结果:
N_GROUP N_SORT N_NAME
---------- ---------- ----------
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
aa 1 pr_1
bb 1 pr_1
bb 1 pr_1
bb 1 pr_1
bb 2 pr_2
bb 2 pr_2
cc 1 pr_4
cc 1 pr_4
cc 2 pr_8
cc 2 pr_8
cc 3 pr_9
15 rows selected.
您可以使用 PARTITION
ed 连接到 row-generator 函数:
SELECT n_group, n_sort, n_name
FROM ( SELECT LEVEL AS n FROM DUAL CONNECT BY LEVEL <= 5 ) l
INNER JOIN (
SELECT t.*,
COUNT(*) OVER (PARTITION BY n_group) AS n_rows
FROM table_name t
) t
PARTITION BY (t.n_group)
ON (MOD(l.n - 1, t.n_rows) + 1 = t.n_sort)
ORDER BY t.n_group, l.n;
其中,对于示例数据:
CREATE TABLE table_name (n_group, n_sort, n_name) AS
SELECT 'aa', 1, 'pr_1' FROM DUAL UNION ALL
SELECT 'bb', 1, 'pr_1' FROM DUAL UNION ALL
SELECT 'bb', 2, 'pr_2' FROM DUAL UNION ALL
SELECT 'cc', 1, 'pr_4' FROM DUAL UNION ALL
SELECT 'cc', 2, 'pr_8' FROM DUAL UNION ALL
SELECT 'cc', 3, 'pr_9' FROM DUAL;
输出:
N_GROUP N_SORT N_NAME aa 1 pr_1 aa 1 pr_1 aa 1 pr_1 aa 1 pr_1 aa 1 pr_1 bb 1 pr_1 bb 2 pr_2 bb 1 pr_1 bb 2 pr_2 bb 1 pr_1 cc 1 pr_4 cc 2 pr_8 cc 3 pr_9 cc 1 pr_4 cc 2 pr_8
db<>fiddle here