如何在 PostgreSQL JSONB 列中查询具有异构元素的嵌套数组

Posted

技术标签:

【中文标题】如何在 PostgreSQL JSONB 列中查询具有异构元素的嵌套数组【英文标题】:How to query nested array with heterogeneous elements in PostgreSQL JSONB column 【发布时间】:2021-04-07 12:52:20 【问题描述】:

我在 PostgreSQL (12.5) 表 Data_Source 中有一个 JSONB 字段,里面有类似的数据:


  "C1": [
    
      "id": 13371,
      "class": "class_A1",
      "inputs": 
        "input_A1": 403096
      ,
      "outputs": 
        "output_A1": 403097
      
    ,
    
      "id": 10200,
      "class": "class_A2",
      "inputs": 
        "input_A2_1": 403096,
        "input_A2_2": 403095
      ,
      "outputs": 
        "output_A2": [
          [
            403098,
            
              "output_A2_1": 403101
            ,
            
              "output_A2_2": [
                403099,
                403100
              ]
            
          ]
        ],
        "output_A2_3": 403102,
        "output_A2_4": 403103,
        "output_A2_5": 403104
      
    
  ]

您能否建议我一些 SQL 查询来从 JSONB 字段中提取输出。 我需要得到什么结果:

输出:

name value
output_A1 403096
output_A2 403098
output_A2_1 403101
output_A2_2 403099
output_A2_2 403100
output_A2_3 403102
output_A2_4 403103
output_A2_5 403104

有什么想法吗?

【问题讨论】:

【参考方案1】:

每当遇到array,然后遇到JSONB_ARRAY_ELEMENTS(),或遇到object,则可能会应用JSONB_EACH() 函数以及辅助JSONB_TYPEOF() 函数来连续确定各自的类型。最后,结合arrayobject类型的结果 not通过使用UNION ALL如 p>

WITH j AS
(
SELECT j2.*, JSONB_TYPEOF(j2.value) AS type
  FROM t,
  JSONB_EACH(jsdata) AS j0(k,v),
  JSONB_ARRAY_ELEMENTS(v) AS j1,
  JSONB_EACH((j1.value ->> 'outputs')::JSONB) AS j2
), jj AS
(
SELECT key,j1.*,JSONB_TYPEOF(j1.value::JSONB) AS type
  FROM j,
  JSONB_ARRAY_ELEMENTS(value) AS j0(v),
  JSONB_ARRAY_ELEMENTS(v) AS j1
 WHERE type = 'array'  
), jjj AS
(
 SELECT key,j0.v,JSONB_TYPEOF(j0.v::JSONB) AS type,k
   FROM jj,
   JSONB_EACH(value) AS j0(k,v)
  WHERE type IN ('array','object') 
)
SELECT key,value
  FROM
  (
   SELECT key,value,type
     FROM j  
    UNION ALL
   SELECT key,value,type
     FROM jj
    UNION ALL
   SELECT k,v,type
     FROM jjj
   ) jt  
WHERE type NOT IN ('array','object')  
UNION ALL 
SELECT k,value
  FROM jjj,JSONB_ARRAY_ELEMENTS(v) AS j0
 WHERE type IN ('array','object') 

Demo

【讨论】:

以上是关于如何在 PostgreSQL JSONB 列中查询具有异构元素的嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Postgresql 中实现对复杂嵌套 JSONB 的全文搜索

在 postgresql 的 jsonb[] 类型列中插入数据的正确语法是啥

读取一个变量 JSONB 并将其放入 postgresql 的列中

使用 PostgreSQL 查询更新复杂 JSONB 对象以删除子子属性

在 PostgreSQL 中的 jsonb 列中搜索 json 数组,其中数据为 json 数组

如何在 JPA 中编写动态 sql 查询以从 jsonb 列中查询数据?