【问题标题】:How to JOIN a JSONB column with an array by a text column?如何通过文本列将 JSONB 列与数组连接?
【发布时间】:2018-08-02 14:05:01
【问题描述】:

使用 PostgreSQL 9.6+

两个表(简化为仅与示例数据相关的列):

表 1:

-------------------------------------------------------
key (PK) [Text]| resources [JSONB]
-------------------------------------------------------
asdfaewdfas    | [i0c1d1233s49f3fce, z0k1d9921s49f3glk]

表 2:

-------------------------------------------------------
resource (PK) [Text]| data [JSONB]
-------------------------------------------------------
i0c1d1233s49f3fce   | {large json of data}
z0k1d9921s49f3glk   | {large json of data}

尝试从表 1 的 resources 列访问表 2 的 data 列。

【问题讨论】:

    标签: sql json postgresql jsonb postgresql-9.6


    【解决方案1】:

    取消嵌套 JSON 数组并加入第二个表。喜欢:

    SELECT t1.*, t2.data -- or just the bits you need
    FROM   table1 t1, jsonb_array_elements_text(t1.resources) r(resource)
    JOIN   table2 t2 USING (resource)
    WHERE  t1.key = ?
    

    或者,保留 table1 中具有空/空/不匹配资源的所有行:

    SELECT t1.*, t2.data -- or just the bits you need
    FROM   table1 t1
    LEFT   JOIN LATERAL jsonb_array_elements_text(t1.resources) r(resource) ON true
    LEFT   JOIN table2 t2 USING (resource)
    WHERE  t1.key = ?
    

    关于jsonb_array_elements_text():

    第一个查询中有一个隐式的LATERAL 连接。见:

    考虑一个规范化的数据库设计,其中每个链接资源有一行而不是列table1.resources,正确实现 m:n 关系。通过这种方式,您可以使用关系功能强制执行参照完整性、数据完整性等。并且查询变得更简单。 jsonb 因为一切都很简单一开始。但是,如果您经常使用嵌套数据,这可能会反过来影响您。

    【讨论】:

    • 遇到错误:USING 子句中指定的列“资源”在左表中不存在。
    • @ThomasChen:忘记了函数jsonb_array_elements_text() 的列名默认为value。添加了一个列别名,它现在应该可以工作了。
    • 跟进:有一个边缘情况问题,如果资源为空 [],则连接不包括表 1 中的该行。有没有办法将表 1 的行包含空资源并将它们连接到表 2 的空白行放在它现在在做什么之上?
    • @ThomasChen。有。 LEFT JOIN .. ON true。请按照我的答案中的第一个链接进行详细评估。 The included fiddle should give a quick overview。我在上面添加了一个变体来说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2021-09-11
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多