Postgres - Как искать и объединять из столбца JSON - PullRequest
1 голос
/ 05 июня 2019

У меня есть таблица asset_quantities, как показано ниже

id   |   asset_type   |    quantity   |    site_id   |   asset_ids_json
  1      'Container'           3              1             [{"id":1,"make":"am1","model":"amo1"},{"id":2,"make":"am1","model":"amo2"},{"id":3,"make":"am3","model":"amo3"}]
  2      'Cage'                3              1             [{"id":4,"make":"bm1","model":"bmo1"},{"id":5,"make":"bm2","model":"bmo2"},{"id":6,"make":"bm2","model":"cmo3"}]
  3      'Crate'               3              1             [{"id":7,"make":"cm1","model":"cmo1"},{"id":8,"make":"cm1","model":"cmo1"},{"id":9,"make":"cm1","model":"cmo2"}]

Я хочу написать SQL-запрос в Postgres, который даст мне подсчет количества каждого типа актива для данной марки или модели.

например. Если бы я хотел получить количество для каждого типа актива, где make = 'am1',

site_id   |   Container_qty    |     Cage_qty     |     Crate_qty
   1               2                     0                  0

например. Если бы я хотел получить количество для каждого типа актива, где make = 'cm1', результирующий набор был бы похож на

site_id   |   Container_qty    |     Cage_qty     |     Crate_qty
   1               0                     0                  3

Я написал приведенный ниже запрос, чтобы развернуть значения из строк 'asset_type' в столбцы, но не могу понять, как отфильтровать и объединить значения на основе атрибутов внутри поля asset_ids_json. Можно с уверенностью предположить, что длина массива json внутри asset_ids_json всегда будет равна значению в столбце «количество».

select
  aq.site_id, 
  sum(case when aq.asset_type = 'Container' then aq.quantity end) container_qty,
  sum(case when aq.asset_type = 'Cage' then aq.quantity end) cage_qty ,
  sum(case when aq.asset_type = 'Crate' then aq.quantity end) crate_qty,
from asset_quantities aq
group by aq.site_id;

Суть моего вопроса в том, как я могу фильтровать и агрегировать результаты на основе атрибутов в столбце json 'asset_ids_json'. Я использую Postgres 9.4.

1 Ответ

1 голос
/ 05 июня 2019

пошаговая демонстрация: db <> fiddle

SELECT
    site_id,
    SUM(case when asset_type = 'Container' then quantity end) container_qty,
    SUM(case when asset_type = 'Cage' then quantity end) cage_qty ,
    SUM(case when asset_type = 'Crate' then quantity end) crate_qty
FROM (
    SELECT DISTINCT ON (id)
        site_id,
        asset_type,
        quantity
    FROM asset_quantities aq,
        json_array_elements(asset_ids_json)
    WHERE value ->> 'make' = 'cm1'
) s
GROUP BY site_id

Чтобы получить предложение WHERE для содержимого массива JSON, необходимо развернуть массив.json_array_elements() создает одну строку для каждого элемента.При этом можно запросить определенное значение.

Из-за этого расширения текущие строки умножаются (здесь три раза, потому что в массиве три элемента).Поскольку вас интересуют только исходные данные site_id, asset_type и quantity, которые были просто скопированы в новые записи, вы можете удалить их с помощью DISTINCT.DISTINCT ON проверяет различные значения каждого id.Поэтому, если два массива JSON будут содержать один и тот же ключ / значение, оба будут сохранены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...