【问题标题】:postgres how to make conditional joinpostgres如何进行条件连接
【发布时间】: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 规范化为实际表和列,否则您将陷入痛苦的世界。
  • 条件连接,听起来像左连接。

标签: sql postgresql eloquent


【解决方案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】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多