【问题标题】:PostgreSQL JSON - Subset of nested listsPostgreSQL JSON - 嵌套列表的子集
【发布时间】:2018-10-10 20:30:15
【问题描述】:

我在 PostgreSQL 数据库中有一个列,它基本上是一个 json 化的 python 元组列表:

[
  ["Mobile","111-111-1111"],
  ["Office","222-222-2222"],
  ["Mobile","333-333-3333"],
  ["Fax","444-444-4444"],
]

我想构造一个查询,它根据每个嵌套列表中的第一个值返回列表的子集。下面是一个伪查询,希望能说明我所追求的:

SELECT
  foo AS bar,
  (SELECT 
     element 
   FROM 
     phone_numbers 
   WHERE
     element::json->>0 = "Mobile") AS mobile_numbers
FROM
  db
;

mobile_numbers == [["Mobile","111-111-1111"],["Mobile","333-333-3333"]]

我只知道关于 PostgreSQL 中的 json 运算符(以及一般的 SQL 查询)的点点滴滴,主要是在字典方面。我可以在这里找到很多关于如何挖掘嵌套字典并返回一个值的示例,但我没有找到任何与我所追求的完全匹配的东西。

感谢您的帮助。

【问题讨论】:

    标签: python json postgresql list jsonb


    【解决方案1】:

    假设该列包含有效的 json 作为数组数组,您应该使用 jsonb_array_elements() 取消嵌套外部数组,通过第一个(索引 0)它们的元素过滤内部数组 (tuples) 并使用聚合结果jsonb_agg().

    with my_table(phone_numbers) as (
    values
    ('[
      ["Mobile","111-111-1111"],
      ["Office","222-222-2222"],
      ["Mobile","333-333-3333"],
      ["Fax","444-444-4444"]
    ]'::jsonb)
    )
    
    select jsonb_agg(phone)
    from my_table
    cross join jsonb_array_elements(phone_numbers) as arr(phone)
    where phone->>0 = 'Mobile'
    
                            jsonb_agg                         
    ----------------------------------------------------------
     [["Mobile", "111-111-1111"], ["Mobile", "333-333-3333"]]
    (1 row) 
    

    【讨论】:

    • 稍微调整一下效果很好!我在我的 SELECT 语句中使用了您编写的 SELECT 语句作为子查询,但我没有使用 CROSS JOIN,而是使用了常规 JOIN,并且 ON 语句是 ext_table._id = subq_table._id。 CROSS JOIN 似乎为我的外部查询中的每一行产生了表中的所有“Mobile”号码,而常规连接只为该行产生“Mobile”号码。也许不是最优雅的方式,但结果是想要的。
    • cross join <function> 总是横向,你不应该害怕笛卡尔积,例如PostgreSQL json_array_elements in FROM clause - why is this not cartesian join?
    猜你喜欢
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2020-07-18
    • 2018-09-21
    • 2021-08-02
    • 1970-01-01
    • 2020-12-09
    • 2014-09-16
    相关资源
    最近更新 更多