PostgreSQL:需要三列以上时将行转换为列

时间:2020-10-27 10:21:32

标签: postgresql crosstab

我有一张类似以下的表格:

+---------+-------+-------+-------------+--+
| Section | Group | Level | Fulfillment |  |
+---------+-------+-------+-------------+--+
| A       | Y     |     1 | 82.2        |  |
| A       | Y     |     2 | 23.2        |  |
| A       | M     |     1 | 81.1        |  |
| A       | M     |     2 | 28.2        |  |
| B       | Y     |     1 | 89.1        |  |
| B       | Y     |     2 | 58.2        |  |
| B       | M     |     1 | 32.5        |  |
| B       | M     |     2 | 21.4        |  |
+---------+-------+-------+-------------+--+

这将是我想要的输出:

+---------+-------+--------------------+--------------------+
| Section | Group | Level1_Fulfillment | Level2_Fulfillment |
+---------+-------+--------------------+--------------------+
| A       | Y     | 82.2               | 23.2               |
| A       | M     | 81.1               | 28.2               |
| B       | Y     | 89.1               | 58.2               |
| B       | M     | 32.5               | 21.4               |
+---------+-------+--------------------+--------------------+

因此,对于每个部分和组,我想获得其在1级和2级的实现百分比。为实现这一点,我尝试了crosstab(),但是使用此函数会返回一个错误(“提供的SQL必须返回3列:rowid,category和values。“),因为我使用的列多于三列(我需要将section和group保持为每行的标识符)。在这种情况下可以使用交叉表吗?

致谢。

1 个答案:

答案 0 :(得分:2)

我发现crosstab()不必要复杂且喜欢使用条件聚合:

select section, 
       "group", 
       max(fulfillment) filter (where level = 1) as level_1,
       max(fulfillment) filter (where level = 2) as level_2
from the_table
group by section, "group"
order by section;

Online example