我使用PostgreSQL构建了以下方案-
Table A:
id | name
1 | a
2 | b
Table B:
id | parent-A-id | searchValue | dataB
1 | 1 | val1 | a
2 | 2 | val2 | b
3 | 2 | val2 | c
Table C:
id | parent-A-id | dataC
1 | 1 | x
2 | 2 | y
3 | 2 | z
Table D:
id | parent-A-id | parent-B-id | searchValue-REF
1 | 1 | 1 | val1
2 | 2 | 2 | val2
2 | 3 | 2 | val2
2 | 3 | 3 | val2
我正在尝试检索以下数据-
给定N,仅使用符合searchByVal-REF上运行的函数的项D,找到n个数量的B,其父级A和子级C的子集,这意味着计算出计算结果(例如-位置),对N值。
基于N的数据输出示例为-
[
{
A.name : "a",
A.id : 1
B.id : 1,
B.dataB : "a",
[{C.id : 1, C.dataC : "x"}],
computedVal : someVal
},
{
A.name : "b",
A.id : 2
B.id : 2,
B.dataB : "b",
[{C.id : 2, C.dataC : "y"}],
computedVal : someVal
},
{
A.name : "b",
A.id : 2
B.id : 3,
B.dataB : "c",
[{C.id : 2, C.dataC : "y"}, {C.id : 3, C.dataC : "z"}],
computedVal : someVal
}
]
数据基本上是B的行以及每个B的B个父级A和每个B的n个子级C,这些行的序列化数组以每行B的单列表示。
我不确定是否过于复杂,但是目前我正试图通过将结果数组转换为序列化的json,将一组记录C分组到单个列中。但是,由于我试图在外部查询上引用子查询,因此我尚未设法使其正常工作,因为我认为该查询过于嵌套,因此失败了。
这就是我坚持的地方-
SELECT
b_items_found.*,
row_to_json(C_json_arr) as C_list
FROM
(
SELECT
*
FROM
(
SELECT
array_agg("parent-C-id") as selected_Cs,
"parent-B-id",
computedVal
FROM
(
SELECT
ComputeA(searchValue-REF) AS computedVal,
"parent-B-id",
"parent-C-id"
FROM
D
CROSS JOIN (
SELECT
ComputeC(N)
) AS r
WHERE
ComputeB(searchValue-REF)
ORDER BY
ComputeA(searchValue-REF)
) select-b-items
GROUP BY
"parent-B-id",
computedVal
) b_and_c
JOIN B ON b_and_c."parent-B-id" = B.id
JOIN A ON B."parent-a-id" = A.id
) b_items_found,
(
SELECT
array_agg(row_to_json(t)) as m
from
(
SELECT
*
from
C
WHERE C.id = ANY(b_items_found.selected_Cs)
) t
) C_json_arr
当前结果为-
表“ b-items-found”有一个条目,但是不能从查询的这一部分中引用。
我想知道是否有一个单一的查询解决方案,或者应该将其分为几个查询(查询和处理服务器端)。
运行PostgreSQL 9.6.8
答案 0 :(得分:1)
尽管查询看起来确实过于复杂,但是您的主要问题是您正在尝试访问查询中的临时表b_items_found
,优化器可能会决定首先执行以下查询,这就是为什么您无法引用它的原因(没有兄弟姐妹参考,只有孩子)。
为此,您必须使用CTE(Common Table Expression),如下所示:
WITH b_items_found AS (
SELECT
*
FROM
(
SELECT
array_agg("parent-C-id") as selected_Cs,
"parent-B-id",
computedVal
FROM
(
SELECT
ComputeA(searchValue-REF) AS computedVal,
"parent-B-id",
"parent-C-id"
FROM
D
CROSS JOIN (
SELECT
ComputeC(N)
) AS r
WHERE
ComputeB(searchValue-REF)
ORDER BY
ComputeA(searchValue-REF)
) select-b-items
GROUP BY
"parent-B-id",
computedVal
) b_and_c
JOIN B ON b_and_c."parent-B-id" = B.id
JOIN A ON B."parent-a-id" = A.id
),
C_json_arr AS (
SELECT
array_agg(row_to_json(t)) as m
from
(
SELECT
*
from
C
WHERE C.id = ANY(b_items_found.selected_Cs)
) t
)
SELECT
b_items_found.*,
row_to_json(C_json_arr) as C_list
FROM b_items_found, C_json_arr
但是,由于您的查询与您的表结构不匹配,因此未经测试。