У меня есть поле JSON в таблице, как показано ниже
{
"Ui": [
{
"element": "TG1",
"mention": "in",
"time": 123
},
{
"element": "TG1",
"mention": "out",
"time": 125
},
{ "element": "TG2",
"mention": "in",
"time": 251
},
{
"element": "TG2",
"mention": "out",
"time": 259
}
]
}
Я намерен получить что-то вроде ниже
| element | Timespent |
| TG1 | 2 |
| TG2 | 8 |
но оказались совершенно безуспешными.
Как я могу получить разницу (сумма за все время, когда упоминание включено - сумма за все время, когда упоминание отсутствует)?
В настоящее время я пытаюсь сделать sum(jsonb_extract_path(data::jsonb, 'ui','hovers')->0->'when')
, чтобы получить сумму, но не могу понять, как рекурсивно просматривать файл json и фильтровать его для упоминания.
Используйте json_array_elements()
для извлечения столбцов из массива json:
select value->>'element' as element, value->>'time' as time_spent
from my_table
cross join json_array_elements(json_column->'Ui')
element | time_spent
-----+------------
TG1 | 123
TG1 | 125
TG2 | 251
TG2 | 259
(4 rows)
Измените приведенный выше запрос, чтобы получить суммы в группах по элементам:
select element, sum(time) as time_spent
from my_table
cross join lateral (
select
value->>'element' as element,
case value->>'mention' when 'in' then -(value->>'time')::numeric else (value->>'time')::numeric end as time
from json_array_elements(json_column->'Ui')) as elements
group by 1
order by 1
element | time_spent
---------+------------
TG1 | 2
TG2 | 8
(2 rows)
Где именно необходимость в рекурсии?