如何重复行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()
枚举出原来的行数,进行计数。然后我们生成新行,并在达到目标行数时立即停止。这在某种程度上比生成比需要更多的行然后过滤更有效。
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
我想重复 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()
枚举出原来的行数,进行计数。然后我们生成新行,并在达到目标行数时立即停止。这在某种程度上比生成比需要更多的行然后过滤更有效。
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