在 PostgreSQL 中反透视数据

Posted

技术标签:

【中文标题】在 PostgreSQL 中反透视数据【英文标题】:Unpivot data in PostgreSQL 【发布时间】:2020-08-18 19:27:37 【问题描述】:

我在 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】:

您可以使用横向连接:

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

【讨论】:

以上是关于在 PostgreSQL 中反透视数据的主要内容,如果未能解决你的问题,请参考以下文章

在 SSIS 中反透视数据

使用 PostgreSQL 创建数据透视表

Postgresql 如何在 SQL 数据库上透视表

在 Tableau 中反透视数据 将行转换为列

在 SQL 中反透视表时获取值存在的列的位置

在 Postgres 9.6 中创建数据透视表