如何重复行n次

How to repeat the rows n times

我想重复 table 的行 n 次。

假设我有一个 table 如下

选项卡 1

A B C
-----
1 2 3
2 3 4

和 n =9

我想得到如下结果

1 2 3
2 3 4
1 2 3
2 3 4
1 2 3
2 3 4
1 2 3
2 3 4
1 2 3

我试过按级别连接,但没有得到预期的结果。

像这样?

SQL> with test (a, b, c) as
  2    (select 1, 2, 3 from dual union all
  3     select 2, 3, 4 from dual
  4    ),
  5  temp as
  6    (select a, b, c,
  7       row_number() over (order by column_value, a) rn
  8     from test cross join table(cast(multiset(select level from dual
  9                                              connect by level <= 9
 10                                             ) as sys.odcinumberlist))
 11    )
 12  select a, b, c
 13  from temp
 14  where rn <= 9
 15  order by rn  ;

         A          B          C
---------- ---------- ----------
         1          2          3
         2          3          4
         1          2          3
         2          3          4
         1          2          3
         2          3          4
         1          2          3
         2          3          4
         1          2          3

9 rows selected.

SQL>

它有什么作用?

  • 第 1 - 4 行代表您的示例数据
  • CTE temp(第 5 - 11 行)创建了所有这些行; row_number 用于对它们进行“排名”,按 column_value 排序(将其视为 level 伪列,如果它更接近您)和 a 列值(为什么?您的示例输出表明如此)
  • 最终查询(第 12 - 15 行)选择 rn <= 9 的结果(因为您希望获得 9 行)

一种方法是递归查询。如果你想要9条记录,那么:

with cte(a, b, c, rn, cnt, lvl) as (
    select a, b, c, row_number() over(order by a, b, c) rn, count(*) over() cnt, 0 lvl from mytable
    union all 
    select a, b, c, rn, cnt, lvl + 1 from cte where lvl * cnt + rn < 8
)
select a, b, c from cte order by lvl, rn

思路是用row_number()枚举出原来的行数,进行计数。然后我们生成新行,并在达到目标行数时立即停止。这在某种程度上比生成比需要更多的行然后过滤更有效。

Demo on DB Fiddle:

 A |  B |  C
-: | -: | -:
 1 |  2 |  3
 2 |  3 |  4
 1 |  2 |  3
 2 |  3 |  4
 1 |  2 |  3
 2 |  3 |  4
 1 |  2 |  3
 2 |  3 |  4
 1 |  2 |  3