postgres如何进行条件连接

Posted

技术标签:

【中文标题】postgres如何进行条件连接【英文标题】:postgres how to make conditional join 【发布时间】:2021-02-22 07:13:40 【问题描述】:

我有一个包含对象或对象数组的 json 字段。如果字段只包含一个对象,我需要从对象中加入一个键,如果有数组,我需要使用横向连接。我使用jsonb_typeof() 来确定它是数组还是对象,并想做这样的事情

SELECT DISTINCT ON
    (id) id,
    jsonb_typeof(field) AS type,
    CASE WHEN jsonb_typeof = 'object' THEN field->>'key' END
FROM
    test_table
    CASE WHEN jsonb_typeof = 'array' THEN lateral JOIN expression

有可能做这样的事情吗?此时我得到:

未定义的列错误(jsonb_typeof)

...在什么条件下

【问题讨论】:

伪代码太多,无法得到准确的答案。请提供示例数据和所需结果以阐明您的要求 如果你必须做一个有条件的加入,那就出问题了。如果您的数据模型定义正确,则永远不必进行条件连接。 在数据库中存储 JSON blob 已经够糟糕的了,使用基于该 JSON 的 JOIN 运算符更糟糕。您需要重新设计数据库以将这些 JSON blob 规范化为实际表和列,否则您将陷入痛苦的世界。 条件连接,听起来像左连接。 【参考方案1】:

您可以将其拆分为两个子查询:

SELECT DISTINCT ON (id) id, jsonb_typeof(field) AS type,
    CASE WHEN jsonb_typeof = 'object' THEN field->>'key' END
FROM ((SELECT id, jsonb_typeof(field) AS type, field->>'key' as col
       FROM test_table
       WHERE jsonb_typeof(field) = 'object'
      ) UNION ALL
      (SELECT id, jsonb_typeof(field) AS type, field->>'key' as col
       FROM test_table LEFT JOIN LATERAL
            . . .
       WHERE jsonb_typeof(field) = 'array'
      ) 
     ) t
ORDER BY id, ???;

请注意,当您使用DISTINCT ON 时,您也应该使用ORDER BY。通常,除了DISTINCT ON 键之外还有其他列来确定您想要哪个行。

【讨论】:

【参考方案2】:

您可以在子查询中转换数据:

    json_array_elements取消嵌套数组 union 带有对象集的未嵌套集 在普通连接(通过键或其他方式)中将此临时集与统一对象列一起使用

【讨论】:

以上是关于postgres如何进行条件连接的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Prisma 为 Postgres 进行 SQL 插入,条件是行数?

如何使用 Postgres 数据库 url 字符串传递证书路径以进行 SSL 连接

Postgres:避免与其他条件重叠范围的最佳方法

如何在特定条件后对特定列求和(Postgres)

如何在 Postgres 中对数组列使用 BETWEEN 条件?

Postgres:更新与物化视图连接的表?错误:视图无法在物化视图中锁定行