【问题标题】:Postgres Lateral Join Multiple Tables to Limit ResultsPostgres 横向连接多个表以限制结果
【发布时间】:2017-06-30 20:43:29
【问题描述】:

我有一个关于 Postgres 横向连接的问题。

我的用例是我想返回一个组合了多个表的数据集,但限制了返回的出版物和评论的数量。简化的表架构如下

表格作者

  • 身份证
  • 姓名

表格审核

  • 身份证
  • AUTHOR_ID
  • PUBLICATION_ID
  • 内容

表格发布

  • 身份证
  • 姓名

表作者发布

  • 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

这将返回我需要的数据,例如我得到作者的姓名、ID 以及他们所属的所有评论和出版物的列表。我想要做的是限制评论和出版物的数量。例如返回 5 条评论和 3 篇出版物。

我尝试使用横向查询来执行此操作,但遇到了一个问题,即如果我执行单个横向查询,它会按预期工作。

很喜欢:

INNER JOIN LATERAL
 (SELECT r.* FROM public.review r WHERE r.author_id = a.id LIMIT 5) r ON TRUE

这将返回只有 5 条评论的数据集 - 但如果我添加第二个横向查询

INNER JOIN LATERAL
 (SELECT ap.* FROM public.author_publication ap WHERE ap.author_id = a.id LIMIT 5) r ON TRUE

我现在得到 25 条评论和出版物的结果,其中包含重复/重复的数据。

所以我的问题是,您是否允许在单个 PG 查询中进行多个横向连接,如果不允许,有什么好方法可以限制 JOIN 的结果数量?

谢谢!

【问题讨论】:

    标签: postgresql join lateral


    【解决方案1】:

    您必须将查询更改为以下内容:

    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'
    

    【讨论】:

    • 当我将查询更新为您建议的内容时,我收到以下错误:``` 列“r.id”必须出现在 GROUP BY 子句中或用于聚合函数 ``` 和添加 GROUP BY 会给我:``` [Err] 错误:用作表达式的子查询返回的不止一行 ``` 但是如果我只限制为 1,那么我只会得到一个结果。
    • 我发现的另一个有趣的事情是运行以下查询:SELECT json_agg(r.uuid) FROM public.review r WHERE r.author_uuid = 'b3113a70-e4bf-4b30-a9ca-9b0530a3115b' LIMIT 1 Creates 创建一个包含所有匹配字段的 json 数组。但是如果我删除 json_agg 我只会得到第一个字段的 1 行。
    • 抱歉,不使用 db 结构写查询有点不方便。当您问下一个问题时 - 请提供 CREATE TABLE 语句、一些典型数据和预期输出。
    • 嗨 Roman - 您所做的更新完美运行!非常感谢你的帮助。这正是我所需要的。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 2011-01-17
    • 2012-12-13
    • 2021-05-16
    相关资源
    最近更新 更多