PostgreSQL中的递归CTE生成不同频率的数据

Jur*_*eri 2 postgresql cte recursive

我正在尝试编写一个在 Postgresql 14 中使用递归 CTE 的数据生成查询。

考虑包含函数 getfreq 的模式“sc”。getfreq 将 int 作为参数(代表另一个表的外键),并返回 int,代表频率。

现在考虑这个查询:

WITH RECURSIVE rec AS 
(
SELECT 1 as fk FROM generate_series(1, sc.getfreq(1), 1)
UNION ALL
SELECT r.fk + 1 FROM rec AS r WHERE r.fk + 1 <= 10
)
select row_number() OVER () as pk, fk from rec
Run Code Online (Sandbox Code Playgroud)

getfreq 期望一个从 1 到 10 的 int(因此 r.fk <= 10 退出条件)。它返回频率 N。我希望递归 CTE 的每次迭代都创建 N 行。每次迭代的结果将通过 UNION ALL 子句组合在一起。最后,我想要一个结果,其中行数等于 getfreq 在 10 次迭代中返回的频率之和。

在上面的示例中,sc.getfreq(1) 将始终返回 5,因此我得到 50 行的结果集;第一个 5 个 fk = 1,第二个 5 个 fk = 2,依此类推。然而,实际上应该使用迭代值调用 sc.getfreq(),因此第二次迭代应该是 sc.getfreq(2) 等等。当然,sc.getfreq(2) 会返回不同的频率,而不是 5,因此最终结果不应有 50 行。

我尝试在 getfreq 中使用“fk”,如下所示: sc.getfreq(fk); 因为“fk”通过 CTE 的递归部分递增(因此在第二次迭代中为 2,在第三次迭代中为 3,依此类推),但列“fk”不存在于 FROM 的上下文中,大概是因为“SELECT”部分还没有运行。

递归 CTE 适合解决这个问题吗?我可以通过一些调整来实现我想要的吗?

示例输出,其中 getfreq(1) 返回 5,getfreq(2) 返回 2,getfreq(3) 返回 1。

PK 氟肯
1 1
2 1
3 1
4 1
5 1
6 2
7 2
8 3

……等等(这是 3 次迭代的不完整示例)。

ype*_*eᵀᴹ 5

我认为你不需要递归解决方案。

select 
    row_number() over (order by r.fk, s.p) as pk, 
    r.fk
from 
    generate_series(1, 10) as r (fk),
    generate_series(1, sc.getfreq(r.fk)) as s (p)
 ;
Run Code Online (Sandbox Code Playgroud)