POSGTRESQL 9.10 - возвращает максимальное значение из массивов JSON - PullRequest
0 голосов
/ 30 августа 2018

Поиск метода для вычисления максимального значения - это числовые массивы, содержащиеся в массиве json с использованием postgresql.

Простой пример:

room, data
1   , '{"history":{"samples":{"101":[5,10,50,20],"102":[10,15,5,5]}}}'

То, что я ищу, - это максимальное значение для определенного элемента "история -> образец" для комнаты. В этом случае это будет «50» для образца 101 и «15» для образца 102, но реальные данные будут больше, чем эта.

Вот sqlfiddle для некоторых фактических данных. http://sqlfiddle.com/#!17/2c7a0

В конечном счете, я хотел бы получить сводную таблицу с комнатой и выборками в виде столбцов с максимальным значением в этом массиве. Есть ли достаточно простой способ сделать это с большим количеством элементов в массивах? (перекрестная таблица или перекрестное боковое соединение?) Что-то вроде следующего, основанное на простом примере сверху:

room | 101 | 102 | ... ->
1    |  50 |  15
2    |   x |   x
etc..
..

снова, см. sqlfiddle для получения примеров данных

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Это не полный ответ, но он может помочь вам приблизиться к тому, что вы ищете:

select key, data->'history'->'data' #> array[key] as values
from
(select *, jsonb_object_keys(data->'history'->'data') as key
from jsonData) as a

Выход:

enter image description here

См. демонстрация скрипки

Вы можете выбрать только одну комнату и выполнить всю работу над ней, тогда это проще:

select key, max(val::text::float) from
(
select key, jsonb_array_elements(values) as val
from
(select key, data->'history'->'data' #> array[key] as values
from
(select *, jsonb_object_keys(data->'history'->'data') as key
from jsonData) as a) 
  as b
  ) as c
group by key
order by 1

Демонстрация скрипки

* * Тысяча двадцать-одина выход:

enter image description here

И если вы хотите отобразить его горизонтально, а не по вертикали, вы можете использовать кросс-таблица (tablefunc)

0 голосов
/ 30 августа 2018

Вы можете использовать LATERAL и json_array_elements:

SELECT j.id, s2.*
FROM jsonData j
,LATERAL (SELECT (data -> 'history') -> 'data' ) s(c)
,LATERAL ( VALUES(
          (SELECT MAX(value::text::decimal(10,2))
          FROM json_array_elements((s.c -> '101')::json) x),
          (SELECT MAX(value::text::decimal(10,2))
          FROM json_array_elements((s.c -> '102')::json) x))
         )s2("101","102");  -- are more cols here

Демоверсия DBFiddle

...