#sql #postgresql #unpivot
#sql #postgresql #открепить
Вопрос:
У меня есть таблица, подобная этой:
id_edifc classe_a classe_b classe_c
9001 0 0 1
9002 1 1 1
9003 0 1 2
9004 0 0 0
9005 1 1 0
и вместо этого я хотел бы визуализировать это так:
id_edifc classe
9001 classe_c
9002 classe_a
9002 classe_b
9002 classe_c
9003 classe_b
9003 classe_c
9003 classe_c
9004 NULL
9005 classe_a
9005 classe_b
Ответ №1:
Использование БОКОВОГО:
SELECT t.id_edifc, s.name
FROM tab t
,LATERAL ( VALUES (classe_a, 'classe_a')
,(classe_b, 'classe_b')
,(classe_c, 'classe_c'))s(val, name)
WHERE val = 1;
Для обработки всех нулей в строке и реплицирующих значений:
SELECT t.id_edifc, s2.name
FROM tab t
LEFT JOIN LATERAL (SELECT s.name
FROM (VALUES (classe_a, 'classe_a')
,(classe_b, 'classe_b')
,(classe_c, 'classe_c'))s(val, name)
,LATERAL generate_series(1,s.val)
WHERE val > 0
) s2 ON TRUE
ORDER BY t.id_edifc;
Вывод:
----------- ----------
| id_edifc | name |
----------- ----------
| 9001 | classe_c |
| 9002 | classe_a |
| 9002 | classe_b |
| 9002 | classe_c |
| 9003 | classe_b |
| 9003 | classe_c |
| 9003 | classe_c |
| 9004 | NULL |
| 9005 | classe_a |
| 9005 | classe_b |
----------- ----------
Комментарии:
1. спасибо Лукашу, но я хочу, чтобы отображались только те, у которых соответствующее значение больше нуля … и появляться столько раз, сколько стоит значение
2. @ishankaganepola
I want only those with corresponding value greater than zero to appear... and to appear as many times as the value is worth
— 9003 classe_c дважды, он был реплицирован столько раз, сколько необходимо
Ответ №2:
Использование jsonb
функций позволяет сделать это для произвольного количества столбцов:
with pvt as (
select id_edifc, k as classe
from xpose
cross join lateral to_jsonb(xpose) as j(obj)
cross join lateral jsonb_each_text(obj - 'id_edifc') as e(k, v)
cross join lateral generate_series(1, v::int)
)
select x.id_edifc, p.classe
from xpose x
left join pvt p
on p.id_edifc = x.id_edifc
order by x.id_edifc, p.classe;
┌──────────┬──────────┐
│ id_edifc │ classe │
├──────────┼──────────┤
│ 9001 │ classe_c │
│ 9002 │ classe_a │
│ 9002 │ classe_b │
│ 9002 │ classe_c │
│ 9003 │ classe_b │
│ 9003 │ classe_c │
│ 9003 │ classe_c │
│ 9004 │ │
│ 9005 │ classe_a │
│ 9005 │ classe_b │
└──────────┴──────────┘
(10 rows)