用Postgres计数jsonb数组中的对象

时间:2019-02-19 15:14:28

标签: postgresql jsonb

假设表中的每个jsonb值都具有以下结构:

{
  "level1": [
    {
      "level2": [
        {
          "key": key,
          "value": value,
          "messages": [

          ]
        },
        {
          "key": key,
          "value": value,
          "messages": [

          ]
        },
        {
          "key": key,
          "value": value,
          "messages": [

          ]
        }
      ]
    }
  ]
}

level1的名称是动态的,因此可以是任何名称(这就是我使用jsonb_object_keys的原因)。 我需要检查level2.messages内部的每个日期是否为空。 也就是说:如果日期中所有level2.messages为空,则返回false。否则(至少一个带有message的对象具有非空数组),返回true。

我以为我可以在子查询中使用json函数,但是在子查询中不知道它们。 我有这样的东西:

SELECT t2.date, 
(SELECT 1 FROM fields WHERE jsonb_array_length(fields ->> 'messages') = 1 LIMIT 1) AS hasMessages
FROM table1 t1
INNER JOIN table2 t2 ON t2.id = t1.id,
jsonb_object_keys(t1.result) AS rootNode,
jsonb_array_elements(t1.result -> rootNode) AS level2,
jsonb_array_elements(level2 -> 'level2') AS fields
GROUP BY t2.date

1 个答案:

答案 0 :(得分:0)

根据问题中的零碎信息,这将起作用:

SELECT date
     , count(*) AS message_count
     , count(*) FILTER (WHERE l2_val->'messages' = '[]') AS empty_message_count
FROM   table1 t1
     , jsonb_object_keys(result) AS key1
     , jsonb_array_elements(result->key1->0->'level2') AS l2_val
GROUP  BY 1
-- HAVING ?

这是假设:

  • 在JSON对象的外部级别始终仅一个密钥名称。
  • level1中仅一个数组元素。
  • 嵌套数组的键名是level2'。

我想您想确定那些有邮件,但全部为空的邮件...