postgresql 如何使用SQL转置表?

xdnvmnnf  于 2023-03-08  发布在  PostgreSQL
关注(0)|答案(2)|浏览(118)

我有这样一张table:
| 身份证|P级|C级|A类|B|
| - ------|- ------|- ------|- ------|- ------|
| 1个|一百|三个|a1|b1|
| 第二章|一百零一|三个|a2|b2|
| 三个|一百零二|三个|a3|b3|
| 四个|一百零三|三个|a4|b4|
| 五个|一百|四个|a5|b5|
| 六个|一百零一|四个|a6|b6|
| 七|一百零二|四个|a7|b7|
| 八个|一百零三|四个|a8|b8|
我想得到一个新的转置结构,像这样:
| P级|_3A|_3B|_4A|_4B|
| - ------|- ------|- ------|- ------|- ------|
| 一百|a1|b1|a5|b5|
| 一百零一|a2|b2|a6|b6|
| 一百零二|a3|b3|a7|b7|
| 一百零三|a4|b4|a8|b8|
正如你所看到的,新的字段名已经从原表的C字段中提取出来了。有什么方法可以用SQL来实现吗?

nnsrf1az

nnsrf1az1#

Postgres在数组和crosstab方面有一些高级功能,但是,一种独立于数据库的方法是使用聚合:

select t.p,
       max(case when c = 3 then a end) as a3,
       max(case when c = 3 then b end) as b3,
       max(case when c = 4 then a end) as a4,
       max(case when c = 4 then b end) as b4
from atable t
group by t.p;

这将在SQLite和Postgres(以及几乎任何其他数据库)中工作。

n6lpvg4x

n6lpvg4x2#

测试数据

DECLARE @TABLE TABLE (id INT, P INT, C INT, A VARCHAR(2), B VARCHAR(2))
INSERT INTO @TABLE VALUES 
(1  ,100 ,3  ,'a1','b1'),
(2  ,101 ,3  ,'a2','b2'),
(3  ,102 ,3  ,'a3','b3'),
(4  ,103 ,3  ,'a4','b4'),
(5  ,100 ,4  ,'a5','b5'),
(6  ,101 ,4  ,'a6','b6'),
(7  ,102 ,4  ,'a7','b7'),
(8  ,103 ,4  ,'a8','b8')

查询

SELECT * FROM 
 (
    SELECT P , Vals , '_' + CAST(C AS VARCHAR(10)) + N  AS Cols
    FROM @TABLE 
        UNPIVOT (Vals FOR N IN (A, B))up
 )A
 PIVOT (MAX(Vals)
        FOR Cols 
        IN ([_3A],[_3B],[_4A],[_4B])
        )p

结果

╔═════╦═════╦═════╦═════╦═════╗
║  P  ║ _3A ║ _3B ║ _4A ║ _4B ║
╠═════╬═════╬═════╬═════╬═════╣
║ 100 ║ a1  ║ b1  ║ a5  ║ b5  ║
║ 101 ║ a2  ║ b2  ║ a6  ║ b6  ║
║ 102 ║ a3  ║ b3  ║ a7  ║ b7  ║
║ 103 ║ a4  ║ b4  ║ a8  ║ b8  ║
╚═════╩═════╩═════╩═════╩═════╝

相关问题