Открепленные данные в PostgreSQL

#postgresql #unpivot

#postgresql #отменить доступ

Вопрос:

У меня есть таблица в PostgreSQL со следующими значениями,

 empid    hyderabad    bangalore    mumbai    chennai
 1        20           30           40        50
 2        10           20           30        40
  

И мой вывод должен быть таким, как показано ниже

 empid    city         nos
1        hyderabad    20
1        bangalore    30
1        mumbai       40
1        chennai      50
2        hyderabad    10
2        bangalore    20
2        mumbai       30
2        chennai      40
  

Как я могу сделать это в PostgreSQL?

Комментарии:

1. Похоже, вам нужно переосмыслить свой дизайн

Ответ №1:

Вы можете использовать боковое объединение:

 select t.empid, x.city, x.nos
from the_table t
  cross join lateral (
     values 
       ('hyderabad', t.hyderabad),
       ('bangalore', t.bangalore),
       ('mumbai', t.mumbai),
       ('chennai', t.chennai)
  ) as x(city, nos)
order by t.empid, x.city;
  

Ответ №2:

Или этот: более простой для чтения — и настоящий обычный SQL …

 WITH
input(empid,hyderabad,bangalore,mumbai,chennai) AS (
          SELECT 1,20,30,40,50
UNION ALL SELECT 2,10,20,30,40
)
,
i(i) AS (
          SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
)
SELECT
  empid
, CASE i 
    WHEN 1 THEN 'hyderabad'
    WHEN 2 THEN 'bangalore'
    WHEN 3 THEN 'mumbai'
    WHEN 4 THEN 'chennai'
    ELSE        'unknown'
  END AS city
, CASE i 
    WHEN 1 THEN hyderabad
    WHEN 2 THEN bangalore
    WHEN 3 THEN mumbai
    WHEN 4 THEN chennai
    ELSE        NULL::INT
  END AS city 
FROM input CROSS JOIN i
ORDER BY empid,i;
-- out  empid |   city    | city 
-- out ------- ----------- ------
-- out      1 | hyderabad |   20
-- out      1 | bangalore |   30
-- out      1 | mumbai    |   40
-- out      1 | chennai   |   50
-- out      2 | hyderabad |   10
-- out      2 | bangalore |   20
-- out      2 | mumbai    |   30
-- out      2 | chennai   |   40