【问题标题】:PostgreSQL Aggregate data into single rowPostgreSQL 将数据聚合成单行
【发布时间】:2018-09-11 23:37:44
【问题描述】:

使用以下 SQL 查询,我想添加一个 JSON 对象数组,该数组包含另一个表中的数据,基于 posts.liked_by 数组:

SELECT 
  p.id, 
  p.author, 
  p.content, 
  u2.id, 
  u2.username, 
  p.liked_by AS likedby
FROM posts p
INNER JOIN users u1 
    ON p.author = u1.id
LEFT JOIN users u2 
    ON u2.id = ANY(p.liked_by)

我得到了预期的输出

╔════╤════════╤═════════════╤══════════╤═════════╗
║ id │ author │ content     │ username │ likedby ║
╠════╪════════╪═════════════╪══════════╪═════════╣
║ 1  │ 1      │ Lorem Ipsum │ John Doe │ {1, 2}  ║
╚════╧════════╧═════════════╧══════════╧═════════╝

现在,我想将 likedby 列修改为包含用户数据的对象数组,按照以下内容:

+----+--------+-------------+----------+-----------------------------------------------------------------+
| id | author | content     | username | liked_by                                                        |
+----+--------+-------------+----------+-----------------------------------------------------------------+
| 1  | 1      | Lorem Ipsum | John Doe | [{id: 1, username: "John Doe"}, {id: 2, username: "Sam Smith"}] |
+----+--------+-------------+----------+-----------------------------------------------------------------+

posts 表的数据结构类似于

+----+--------+-------------+-----------+-----------+
| id | author | content     | author_id | liked_by  |
+----+--------+-------------+-----------+-----------+
| 1  | 1      | lorem ipsum | 1         | {1, 2, 3} |
+----+--------+-------------+-----------+-----------+

用户表的结构为

+----+----------+
| id | username |
+----+----------+
| 1  | John Doe |
+----+----------+

我该怎么做呢?

【问题讨论】:

  • 从这里:FROM public.posts AS posts, public.users 删除:, public.users
  • @OtoShavadze 这只是将错误切换到users 表。作为参考,我将其更改为 FROM public.posts AS posts LEFT JOIN users u ON users.id = ANY (posts.likedby)
  • @a_horse_with_no_name 我的查询基于另一个查询,用于从用户表中获取作者数据以及作者列值以及帖子数据
  • 请edit您的问题并添加一些sample data 和基于该数据的预期输出。 Formatted text 请no screen shots。 (edit 您的问题 - 在 cmets 中不邮政编码或其他信息)
  • 问题已经用示例数据和理想的输出进行了编辑。

标签: sql postgresql join


【解决方案1】:

它适用于显式连接(顺便说一句,混合和匹配的形式不好):

SELECT
    ...
FROM posts p
INNER JOIN users u1 
    ON p.author = u1.id
LEFT JOIN users u2 
    ON u2.id = ANY(p.liked_by)

至于为什么,来自postgres documentation:

... JOIN 比逗号绑定得更紧密。例如 FROM T1 交叉连接 T2 INNER JOIN T3 ON 条件与 FROM T1、T2 INNER 不同 JOIN T3 ON 条件,因为该条件可以在 第一种情况,但不是第二种情况。

【讨论】:

  • 这解决了错误的问题,谢谢,我已经编辑了这个问题以更接近地反映我想做的事情。
  • 好的,但您不应该那样更改您的问题,因为现在答案是针对不再出现在问题中的问题。创建一个关于如何以某种格式获得结果的新问题,或者在不删除原始问题的情况下编辑您的问题。
【解决方案2】:

要获取liked_by 列的聚合用户名,您可以使用带有jsonb_agg() 和jsonb_build_object() 函数的子查询:

SELECT posts.*, "user".username as author_name,  
    (SELECT jsonb_agg(jsonb_build_object("user".id, "user".username)) FROM "user" where "user".id = any(posts.liked_by)  )
FROM posts
INNER JOIN "user"
ON posts.author_id = "user".id

http://rextester.com/KMEY13984

【讨论】:

  • 这正是我想要的!谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-08-07
  • 2010-10-30
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2018-01-12
  • 2022-07-27
相关资源
最近更新 更多