Подсчет объектов в массиве jsonb с помощью Postgres - PullRequest
0 голосов
/ 19 февраля 2019

Предположим, что каждое значение 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.В противном случае (по крайней мере один из объектов с сообщением имеет непустой массив), верните 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 голосов
/ 19 февраля 2019

На основании фрагментарной информации в вопросе это будет работать:

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 '.

Полагаю, вы хотите идентифицировать те, которые имеют сообщения, но все пустые ...

...