微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐