Получить данные строки в виде таблицы в PostgreSQL
Всем привет!
- Что я имею. Есть таблица Журнал(journal), которая хранит значения определённых параметров для определённой сущности в разное время и имеет вот такой вид:
| Id | entity_id | date | parameter1 | parameter2 | parameter3 | ... | parameterN | type_work |
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 2021-07-28 | 111 | 222 | 333 | ... | 1001 | 1 |
| 2 | 1 | 2021-07-28 | 444 | 555 | 666 | ... | 1002 | 2 |
| 3 | 1 | 2021-07-28 | 777 | 888 | 999 | ... | 1003 | 3 |
| 4 | 2 | 2021-07-28 | 1 | 2 | 3 | ... | 1004 | 1 |
| 5 | 3 | 2021-07-29 | 4 | 5 | 6 | ... | 1005 | 1 |
то есть как вы видите для одной и той же сущности для одной и той же даты разные параметры могут принимать разные значения в зависимости от типа работы type_work.
- Также ещё есть и таблица Параметры(param), которая имеет следующий вид:
| Id | Title | Code |
|---|---|---|
| 1 | Параметр 1 | parametr1 |
| 2 | Параметр 2 | parametr2 |
| 3 | Параметр 3 | parametr3 |
| . | .......... | ......... |
| N | Параметр N | parametrN |
- Что мне нужно:
я сейчас пишу хранимую функцию, которая на входа принимает 2 параметра:
- Id сущности, то есть entity_id
- дату, то есть date
мне нужно по дате и по Id сущности взять данные из таблицы Журнала(journal) и положить её в результирующую таблицу result_data, которая должна будет иметь следующий вид (например для entity_id = 1 и date = '2021-07-28'):
| Id | entity_id | date | type_work | param_id | value |
| ------ | --------- | ---------- | --------- | -------- | ----- |
| 1 | 1 | 2021-07-28 | 1 | 1 | 111 |
| 2 | 1 | 2021-07-28 | 1 | 2 | 222 |
| 3 | 1 | 2021-07-28 | 1 | 3 | 333 |
| ...... | ......... | .......... | ......... | ........ | ..... |
| N | 1 | 2021-07-28 | 1 | N | 1001 |
| N+1 | 1 | 2021-07-28 | 2 | 1 | 444 |
| N+2 | 1 | 2021-07-28 | 2 | 2 | 555 |
| N+3 | 1 | 2021-07-28 | 2 | 3 | 666 |
| ...... | ......... | .......... | ......... | ........ | ..... |
| 2N | 1 | 2021-07-28 | 2 | N | 1002 |
| 2N+1 | 1 | 2021-07-28 | 3 | 1 | 777 |
| 2N+2 | 1 | 2021-07-28 | 3 | 2 | 888 |
| 2N+3 | 1 | 2021-07-28 | 3 | 3 | 999 |
| ...... | ......... | .......... | ......... | ........ | ..... |
| 3N | 1 | 2021-07-28 | 3 | N | 1003 |
То есть как видите группировка происходит по entity_id, date и type_work. То есть в результирующей таблице result_data есть индекс уникальности для строчки по полям entity_id, date, type_work, то есть не может быть ни одной строчки с одинаковым набором данных полей.
Кроме того в запросе мне нужно иметь возможность передать те параметры из таблицы Журнал(journal), которые я хочу добавить в результирующую таблицы. То есть, например, хочу добавлять только параметры parameter1, parameter2, parameter3 - значит добавляю только их.
И есть важное ограничение! Тимлид сказал мне делать это всё без циклов. В текущей реализации я использую конструкцию вида
FOR temprow IN
SELECT * FROM
....
LOOP
...
END LOOP;
Так вот мне нужно без цикла.
Я нашёл одно решение, которое мне некоторым образом помогло:
select * from
jsonb_each
(
(select to_jsonb(j.*) from journal j where j.id = 1)
) s
Оно выводит результат такого вида:
| key | value |
| ---------- | ---------- |
| Id | 1 |
| entity_id | 1 |
| date | 2021-07-28 |
| parameter1 | 111 |
| parameter2 | 222 |
| parameter3 | 333 |
| .......... | .......... |
| parameterN | 1001 |
| type_work | 1 |
Но это только для одной записи для одного типа работы type_work! А как мне также выбрать записи по entity_id, date(дате) и type_work? Ведь для разных типов работ у одной и той же сущности для одной и той же даты значения параметров могут быть разные.
Может быть хоть какие-нибудь идеи есть на это счёт? Как это делается вообще? Я могу скинуть в принципе и рабочий код с циклом как я сделал, если нужно. Но в том то и дело, что сделать всё нужно БЕЗ ЦИКЛА.
Заранее спасибо всем кто ответит!
Ответы (1 шт):
SELECT
j.entity_id,
j.date,
j.type_work,
p.id,
CASE
WHEN p.code = 'parametr1' THEN j.parameter1
WHEN p.code = 'parametr2' THEN j.parameter2
WHEN p.code = 'parametr3' THEN j.parameter3
WHEN p.code = 'parametr4' THEN j.parameter4
END as value
FROM journal AS j
CROSS JOIN param AS p
WHERE j.date = '2021-07-28'
Решение по ссылке: http://sqlfiddle.com/#!17/5cbf40/1