Estou tentando escrever uma consulta de geração de dados que usa CTE recursiva no Postgresql 14.
Considere o esquema "sc" que inclui uma função getfreq. getfreq recebe um int como parâmetro (que representa uma chave estrangeira para outra tabela) e retorna um int back, que representa uma frequência.
Agora considere esta consulta:
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
getfreq espera um int de 1 a 10 (daí a condição de saída r.fk <= 10). Ele retorna uma frequência N. Eu quero que cada iteração do CTE recursivo crie N linhas. O resultado de cada iteração deve ser combinado pela cláusula UNION ALL. No final, quero um resultado em que a contagem de linhas seja igual à soma das frequências retornadas por getfreq nas 10 iterações.
No exemplo acima, sc.getfreq(1) sempre retornará 5, portanto, estou obtendo um conjunto de resultados de 50 linhas; primeiros 5 com fk = 1, segundos 5 com fk = 2 e assim por diante. No entanto, sc.getfreq() deve de fato ser chamado com o valor iterado, então a segunda iteração deve ser sc.getfreq(2) e assim por diante. Naturalmente, sc.getfreq(2) retornaria uma frequência diferente e não 5 e, portanto, o resultado final não deveria ter 50 linhas.
Eu tentei usar "fk" em getfreq, da seguinte forma: sc.getfreq(fk); já que "fk" está sendo incrementado pela parte recursiva do CTE (e, portanto, seria 2 na segunda iteração, 3 na terceira iteração e assim por diante), mas a coluna "fk" não existe dentro do contexto do FROM, presumivelmente porque a parte "SELECT" ainda não teria sido executada.
Os CTEs recursivos são adequados para resolver isso? Posso conseguir com o que quero com alguns ajustes?
Exemplo de saída onde getfreq(1) retorna 5, getfreq(2) retorna 2 e getfreq(3) retorna 1.
PK | FK |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 1 |
5 | 1 |
6 | 2 |
7 | 2 |
8 | 3 |
...... e assim por diante (este é um exemplo incompleto de 3 iterações).
Eu acho que você não precisa de uma solução recursiva.