如何在postgresql中的`tablefunc`查询中包含空值?

我正在尝试使用 postgresql中的 crosstab函数来创建数据透视表.但是,我很难理解如何在查询中构建我的sql.我的数据由四列组成,如下所示:

我使用以下代码创建此表:

CREATE TABLE ct(id SERIAL,zone_id int,group_id int,area double precision);
INSERT INTO ct(zone_id,group_id,area) VALUES(1,2,6798.50754160784);
INSERT INTO ct(zone_id,3,10197.7613124118);
INSERT INTO ct(zone_id,area) VALUES(2,1,85708.8676744647);
INSERT INTO ct(zone_id,56006.5971338327);
INSERT INTO ct(zone_id,5584.33145616642);
INSERT INTO ct(zone_id,5,8611.99732832252);
INSERT INTO ct(zone_id,6,36103.5509183704);
INSERT INTO ct(zone_id,8,9801.14541428806);
INSERT INTO ct(zone_id,area) VALUES(5,45796.0020793546);

紧跟postgresql文档,我在交叉表查询中使用以下代码

SELECT *
FROM crosstab(
  'select zone_id,area
   from ct
   ')
AS ct(row_name integer,g_1 double precision,g_2 double precision,g_3 double precision,g_4 double precision,g_5 double precision,g_6 double precision,g_7 double precision,g_8 double precision);

这导致下表不是我想要的那样:

例如,在第二行中,我想要以下值:

85708.8676744647,56006.5971338327,5584.33145616642,NULL,8611.99732832252,36103.5509183704,9801.14541428806

相反,价值观是:

85708.8676744647,9801.14541428806

但是,似乎忽略了空值,因此我的列名称g1到g8与原始组不对应.

解决方法

使用 crosstab() variant with two parameters

SELECT * FROM crosstab(
   'SELECT zone_id,area
    FROM   ct
    ORDER  BY 1,2','SELECT g FROM generate_series(1,8) g'  -- ! Provide values explicitly
   )
AS ct(
     row_name integer,g_1 float8,g_2 float8,g_3 float8,g_4 float8,g_5 float8,g_6 float8,g_7 float8,g_8 float8);

从而明确地声明哪个值在哪个输出列中.因此该函数知道填充NULL值的位置.在这种情况下,generate_series()派上用场提供8行数字1-8. VALUES表达式可以替代:

'VALUES (1),(2),(3),(4),(5),(6),(7),(8)'

另外,不要忘记第一个参数查询中的ORDER BY子句.

我提供了detailed explanation in this related answer.

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...