postgreSQL-PARTITIONs的笛卡尔乘积



有一个非常复杂的查询,我无法独自思考。在查询的表中有5列:PK_ID,它是值的唯一标识符,ID,它连接一个组中的聚合值,count,它说应该聚合多少个值组(如果没有足够的值组,则应该从查询结果中删除具有这样的ID的组(,num,它说组内聚合值的数量,以及待聚合的CCD_ 6。

(Table T1)
PK_ID |   ID  |  num  |  count |  value
------+-------+-------+--------+--------
1    |   1   |   1   |   3    |   A
------+-------+-------+--------+--------
2    |   1   |   2   |   3    |   B
------+-------+-------+--------+--------
3    |   1   |   3   |   3    |   C
------+-------+-------+--------+--------
4    |   1   |   1   |   3    |   D
------+-------+-------+--------+--------
5    |   1   |   3   |   3    |   E
------+-------+-------+--------+--------
6    |   1   |   2   |   3    |   F
------+-------+-------+--------+--------
7    |   1   |   3   |   3    |   G
------+-------+-------+--------+--------
8    |   2   |   1   |   2    |   H
------+-------+-------+--------+--------
9    |   2   |   2   |   2    |   I
------+-------+-------+--------+--------
10   |   2   |   1   |   2    |   J
------+-------+-------+--------+--------
11   |   3   |   1   |   5    |   X

这种查询的结果是:

PK_ID | T1_ID | cross_aggr | T1_PK_IDs
------+-------+------------+-----------
1   |   1   | {A, B, C}  | {1, 2, 3}
------+-------+------------+-----------
2   |   1   | {A, B, E}  | {1, 2, 5}
------+-------+------------+-----------
3   |   1   | {A, B, G}  | {1, 2, 7}
------+-------+------------+-----------
4   |   1   | {A, F, C}  | {1, 6, 3}
------+-------+------------+-----------
5   |   1   | {A, F, E}  | {1, 6, 5}
------+-------+------------+-----------
6   |   1   | {A, F, G}  | {1, 6, 7}
------+-------+------------+-----------
7   |   1   | {D, B, C}  | {4, 2, 3}
------+-------+------------+-----------
8   |   1   | {D, B, E}  | {4, 2, 5}
------+-------+------------+-----------
9   |   1   | {D, B, G}  | {4, 2, 7}
------+-------+------------+-----------
10  |   1   | {D, F, C}  | {4, 6, 3}
------+-------+------------+-----------
11  |   1   | {D, F, E}  | {4, 6, 5}
------+-------+------------+-----------
12  |   1   | {D, F, G}  | {4, 6, 7}
------+-------+------------+-----------
13  |   2   | {H, I}     | {8, 9}
------+-------+------------+-----------
14  |   2   | {J, I}     | {10, 9}

因此,它返回了每个组内value的每一个可能组合,由ID定义,并由count描述,这些值按每个单独的num的顺序进行聚合。

看起来我必须使用CROSS JOIN(以与线性代数中的笛卡尔乘积相同的方式(,但CROSS JOIN似乎只有在事先知道JOINed表的数量的情况下才能工作,但存在count的复杂性。count本身可能(我的意思是它没有,但它可能(在2infinity的范围内。

我曾想过用WINDOW函数、PARTITION BYIDnum来处理它,但在那之后我就陷入了困境,因为似乎没有办法得到这些分区的笛卡尔乘积。

我应该到此为止,找到另一种方法来处理数据,还是有一种方法可以组成这样的查询?

这读起来像是一个图遍历问题,需要递归查询。

with recursive cte as (
select id, num, cnt, 1 as lvl,
array[value::text] as arr_values, 
array[pk_id::int] as arr_pk_id
from mytable where num = 1
union all
select c.id, t.num, c.cnt, c.lvl + 1, 
c.arr_values || t.value::text, 
c.arr_pk_id  || t.pk_id
from cte c
inner join mytable t 
on  t.id = c.id 
and t.num = c.num + 1 
and t.num <= c.cnt
)
select id, arr_values, arr_pk_id 
from cte 
where array_length(arr_pk_id, 1) = cnt
order by arr_pk_id

对于每个id,递归查询在num1处开始,并遵循所有可能的路径。外部查询只过滤路径的末尾。

DB Fiddle上的演示

id|arr_values|arr_pk_id-:|:--------|:--------1|{A,B,C}|{1,2,3}1|{A,B,E}|{1,2,5}1|{A,B,G}|{1,2,7}1|{A,F,C}|{1,6,3}1|{A,F,E}|{1,6,5}1|{A,F,G}|{1,6,7}1|{D,B,C}|{4,2,3}1|{D,B,E}|{4,2,5}1|{D,B,G}|{4,2,7}1|{D,F,C}|{4,6,3}1|{D,F,E}|{4,6,5}1|{D,F,G}|{4,6,7}2|{H,I}|{8,9}2|{J,I}|{10,9}

相关内容

  • 没有找到相关文章

最新更新