Postgres 横向连接多个表以限制结果
Postgres Lateral Join Multiple Tables to Limit Results
我对 Postgres 中的横向连接有疑问。
我的用例是我想要 return 一个结合了多个 table 的数据集,但限制了出版物和评论的数量 returned。简化的 table 架构如下
Table作者
- ID
- 姓名
Table评论
- ID
- AUTHOR_ID
- PUBLICATION_ID
- 内容
Table 发表
- ID
- 姓名
Table 作者出版物
- AUTHOR_ID
- PUBLICATION_ID
所以对于我的初始查询,我有这个:
SELECT
a.id,
a.name
json_agg (
json_build_object (
'id', r.id,
'content', r.content
)
) AS reviews,
json_agg (
json_build_object(
'id', p.id,
'name', p.name
)
) AS publications
FROM
public.author a
INNER JOIN
public.review r ON r.author_id = a.id
INNER JOIN
public.author_publication ap ON ap.author_id = a.id
INNER JOIN
public.publication p ON p.id = ap.publication_id
WHERE
a.id = '1'
GROUP BY
a.id
这 return 是我需要的数据,例如,我得到了作者的姓名、ID 以及他们所属的所有评论和出版物的列表。我希望能够做的是限制评论和出版物的数量。例如 return 5 条评论和 3 篇出版物。
我尝试通过横向查询来执行此操作,但 运行 遇到了一个问题,如果我执行单个横向查询,它会按预期工作。
很喜欢:
INNER JOIN LATERAL
(SELECT r.* FROM public.review r WHERE r.author_id = a.id LIMIT 5) r ON TRUE
这个 return 数据集只有 5 条评论 - 但如果我添加第二个横向查询
INNER JOIN LATERAL
(SELECT ap.* FROM public.author_publication ap WHERE ap.author_id = a.id LIMIT 5) r ON TRUE
我现在使用 repeated/duplicated 数据获得 25 个评论和出版物的结果。
所以我的问题是,您是否允许在单个 PG 查询中进行多个横向联接?如果不允许,限制联接结果数量的好方法是什么?
谢谢!
您必须将查询更改为如下内容:
SELECT
a.id,
a.name,
(
SELECT
json_agg ( r )
FROM (
SELECT
json_build_object (
'id', r.id,
'content', r.content
) AS r
FROM public.review r
WHERE r.author_id = a.id
ORDER BY r.id
LIMIT 5
) AS a
) AS reviews,
(
SELECT
json_agg (p)
FROM (
SELECT
json_build_object(
'id', p.id,
'name', p.name
) AS p
FROM public.author_publication ap
INNER JOIN public.publication p ON p.id = ap.publication_id
WHERE ap.author_id = a.id
ORDER BY p.id
LIMIT 3
) AS a
) AS publications
FROM
public.author a
WHERE
a.id = '1'
我对 Postgres 中的横向连接有疑问。
我的用例是我想要 return 一个结合了多个 table 的数据集,但限制了出版物和评论的数量 returned。简化的 table 架构如下
Table作者
- ID
- 姓名
Table评论
- ID
- AUTHOR_ID
- PUBLICATION_ID
- 内容
Table 发表
- ID
- 姓名
Table 作者出版物
- AUTHOR_ID
- PUBLICATION_ID
所以对于我的初始查询,我有这个:
SELECT
a.id,
a.name
json_agg (
json_build_object (
'id', r.id,
'content', r.content
)
) AS reviews,
json_agg (
json_build_object(
'id', p.id,
'name', p.name
)
) AS publications
FROM
public.author a
INNER JOIN
public.review r ON r.author_id = a.id
INNER JOIN
public.author_publication ap ON ap.author_id = a.id
INNER JOIN
public.publication p ON p.id = ap.publication_id
WHERE
a.id = '1'
GROUP BY
a.id
这 return 是我需要的数据,例如,我得到了作者的姓名、ID 以及他们所属的所有评论和出版物的列表。我希望能够做的是限制评论和出版物的数量。例如 return 5 条评论和 3 篇出版物。
我尝试通过横向查询来执行此操作,但 运行 遇到了一个问题,如果我执行单个横向查询,它会按预期工作。
很喜欢:
INNER JOIN LATERAL
(SELECT r.* FROM public.review r WHERE r.author_id = a.id LIMIT 5) r ON TRUE
这个 return 数据集只有 5 条评论 - 但如果我添加第二个横向查询
INNER JOIN LATERAL
(SELECT ap.* FROM public.author_publication ap WHERE ap.author_id = a.id LIMIT 5) r ON TRUE
我现在使用 repeated/duplicated 数据获得 25 个评论和出版物的结果。
所以我的问题是,您是否允许在单个 PG 查询中进行多个横向联接?如果不允许,限制联接结果数量的好方法是什么?
谢谢!
您必须将查询更改为如下内容:
SELECT
a.id,
a.name,
(
SELECT
json_agg ( r )
FROM (
SELECT
json_build_object (
'id', r.id,
'content', r.content
) AS r
FROM public.review r
WHERE r.author_id = a.id
ORDER BY r.id
LIMIT 5
) AS a
) AS reviews,
(
SELECT
json_agg (p)
FROM (
SELECT
json_build_object(
'id', p.id,
'name', p.name
) AS p
FROM public.author_publication ap
INNER JOIN public.publication p ON p.id = ap.publication_id
WHERE ap.author_id = a.id
ORDER BY p.id
LIMIT 3
) AS a
) AS publications
FROM
public.author a
WHERE
a.id = '1'