【问题标题】:Postgres Subquery - How to create ALIAS in object format from subqueriesPostgres 子查询 - 如何从子查询创建对象格式的别名
【发布时间】:2019-06-23 16:10:10
【问题描述】:

我正在尝试将多个查询包装成 1 个复杂查询。

这里是场景。给定“xxxxx-xx-xxxxx”的user_id,我必须在多个表中查询多个数据点。我将下面的大部分查询都包含了一些 JOIN,但我真的很想看看是否有可能获得我获得 用户名电子邮件 的最后一个查询strong> 包装成作为对象存储的ALIAS 列?我不确定这是否可能,但这里是分解的查询..

漫漫长路

查询 1:

SELECT * FROM requests WHERE created_by = 'xxxx-xx-xxxxx';

此查询将返回这样的一行:

id   |   created_by   |   created_date ...
1141   xxxx-xx-xxxxx    2019-04-09 19:33:40.889+00 ...

然后我必须运行另一个查询来查找返回 id 的所有批准者 查询 2:

SELECT * FROM approvers WHERE request_id = 1141

这可能会返回很多行:

request_id   |   user_id      |   decision    |    type   | .....
1141            xxxxx-xx-xxxxx       approve         approver     ......
1141            aaaaa-aa-aaaaa      approve         approver     ......
1141            bbbbb-bb-bbbbb    under review      watcher     ......
1141            ccccc-cc-ccccc      reject          approver     .......

最后要找到我必须运行查询的用户名(对于查询 2 的每个返回行) 查询 3、4、5、6:

SELECT * FROM users WHERE id = 'xxxx-xx-xxxxx' LIMIT 1

将返回:

id           |     given_name     |     family_name     |     email     | .....
xxxx-xx-xxxxx      John                  Doe             johndoe@email.com    ....

是否可以运行子查询并创建 approver_infoALIAS 列,并将关联的批准者和用户存储为 JSON 对象?

所需查询/结果:

1 个查询:

SELECT * FROM requests
WHERE created_by = 'xxxxx-xx-xxxxx'
SUBQUERY HERE ...

这将产生以下结果:

id   |  created_by    |  created_date               |  approver_info    ...
1141    xxxx-xx-xxxxx    2019-04-09 19:33:40.889+00    [{"id" : "xxxxx-xx-xxxxx", "given_name" : "John", "family_name" : "Doe", "email":"john@email.com","decision" : "approve", "type" : "approver"},
                                                        {"id" : "aaaaa-aa-aaaaa", "given_name" : "Sansa", "family_name" : "Stark", "email":"sansa@.com","decision" : "approve", "type" : "approver"},
                                                        {"id" : "bbbbb-bb-bbbbb", "given_name" : "Arya", "family_name" : "Stark", "email":"arya@email.com","decision" : "under review", "type" : "watcher"},
                                                        {"id" : "ccccc-cc-ccccc", "given_name" : "Ned", "family_name" : "Stark", "email":"ned@email.com","decision" : "approve", "type" : "approver"}]

【问题讨论】:

  • 您的 Postgres 版本和实际的基本表定义(CREATE TABLE 语句)将很有帮助。假设users.id是表的主键,那为什么LIMIT 1呢?

标签: sql json postgresql join


【解决方案1】:

您的查询可能如下所示:

SELECT r.id, r.created_by, r.created_date
    , (SELECT json_agg(au)
       FROM  (
          SELECT u.id, u.given_name, u.family_name, u.email, a.decision, a.type -- , ...
          FROM   approvers a
          JOIN   users     u ON u.id = a.user_id
          WHERE  a.request_id = r.id
          ) au
      ) AS approver_info
FROM   requests  r
WHERE  r.created_by = 'xxxx-xx-xxxxx';

使用相关子查询将 0-n 相关行聚合到 JSON 数组 approver_info

LATERAL 连接将是等效的替代方案:

嵌套子查询是一种以原始列名作为键构建 JSON 数组的方式。还有其他人(json_build_object()row_to_json()):

【讨论】:

    【解决方案2】:

    看来你正在寻找加入

    SELECT * 
    FROM requests r
    INNER JOIN  approvers a on r.id = a.id 
    INNER JOIN users u on u.id = r.user_id 
    WHERE r.created_by = 'xxxx-xx-xxxxx';
    

    如果您需要将行结果的某些部分作为 json 格式,您可以尝试使用 row_to_json()

    select r.user_id, r.request_id,  row_to_json(row(your_col1,your_col2,.....))
    FROM requests r
    INNER JOIN  approvers a on r.id = a.id 
    INNER JOIN users u on u.id = r.user_id 
    WHERE r.created_by = 'xxxx-xx-xxxxx';
    

    【讨论】:

    • 感谢 scaisEdge 的快速回复。我实际上正在对上面的大多数查询进行 JOIN ......但我很想知道是否可以将请求 id 的所有关联用户获取到存储为 JSON 对象的 ALIAS 中。您可以在问题底部看到所需查询结果的示例。再次感谢!
    • 答案已更新。值得建议...希望有用
    • 是的,它肯定会有用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2019-06-08
    • 2021-04-14
    相关资源
    最近更新 更多