组中的重复行达到给定值 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.

您可以使用 PARTITIONed 连接到 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