在 sql 中重复每 N 行的最简单方法

Simplest way to repeat every N rows in sql

我知道这可以通过一些复杂的技术实现,我想知道任何最简单的方法来实现每 10 行应该重复的模式。 例如

        select a,b from tablename; (repeating 2 for example)

会给

        a1,b1     
        a2,b2
        a1,b1  
        a2.b2
        a3,b3
        a4,b4
        a3,b3
        a4,b4

如果它是 10,它会像

    a1,b1 to a10,b10 again a1,b1 to a10,b10

然后

    a11,b11 to a20,b20 again a11,b11 to a20,b20

等等

使用 CTE 并联合所有:

with rows as (
      select a, b
      from tablename
      where rownum <= 2
     )
select *
from rows
union all
select *
from rows;

只是一些注意事项。如果您想要 table 中的特定行,您应该使用 order by。这很重要,因为相同的 select 可以 return 不同的行集。实际上,考虑到这一点,更好的方法可能是:

with rows as (
      select a, b
      from tablename
      where rownum <= 2
     )
select *
from rows cross join
     (select 1 as n from dual union all select 2 from dual) n;

我宁愿不使用 UNION 这么多次。我的方式是 CONNECT BY ROWNUM <=N。居然一个CARTESIAN JOIN。所以,基本上你需要一个 ROW GENERATOR 来笛卡尔加入它。,

更新

例如,这将重复 10 行 2 次 -

SQL> WITH t AS
  2    ( SELECT 'a1' A, 'b1' b FROM dual
  3    UNION ALL
  4    SELECT 'a2' a, 'b2' b FROM dual
  5    UNION ALL
  6    SELECT 'a3' a, 'b3' b FROM dual
  7    UNION ALL
  8    SELECT 'a4' A, 'b4' b FROM dual
  9    UNION ALL
 10    SELECT 'a5' A, 'b5' b FROM dual
 11    UNION ALL
 12    SELECT 'a6' a, 'b6' b FROM dual
 13    UNION ALL
 14    SELECT 'a7' A, 'b7' b FROM dual
 15    UNION ALL
 16    SELECT 'a8' a, 'b8' b FROM dual
 17    UNION ALL
 18    SELECT 'a9' a, 'b9' b FROM dual
 19    UNION ALL
 20    SELECT 'a10' a, 'b10' b FROM dual
 21    )
 22  SELECT A,B FROM t,
 23    (SELECT 1 FROM DUAL CONNECT BY ROWNUM <=2
 24    )
 25    /

A   B
--- ---
a1  b1
a2  b2
a3  b3
a4  b4
a5  b5
a6  b6
a7  b7
a8  b8
a9  b9
a10 b10
a1  b1
a2  b2
a3  b3
a4  b4
a5  b5
a6  b6
a7  b7
a8  b8
a9  b9
a10 b10

20 rows selected.

SQL>

所以,上面的 CONNECT BY ROWNUM <=10 表示重复行 10 次。如果你想让它重复 N 次使用 CONNECT BY ROWNUM <=N.

您希望十行的块重复两次。所以得到:

rows 1 to 10
rows 1 to 10
rows 11 to 20
rows 11 to 20
...

为了获得行 n 次交叉连接 table 持有 n 条记录。 (例如,您可以通过查询足够大的 table 并在行数 n 处停止。)

您还需要原始记录的行号,因此您可以先获取块1,然后获取块2,依此类推。使用整数除法从行号到块。

select t.a, t.b
from (select a, b, row_number() over (order by a, b) as rn from tablename) t
cross join (select rownum as repeatno from bigenoughtable where rownum <= 2) r
order by trunc((t.rn -1) / 10), r.repeatno, t.a, t.b;