我正在尝试从汇总中输出和标记总计列。
select coalesce(column_1, 'Total') as coalesced_value,
sum(column_2) as column_sum
from table
where yada yada
group by rollup(coalesced_value)
order by coalesced_value
查询工作正常,并按预期生成总计,但我希望是“总计”的列值显示为[null]。
很有可能是我缺乏理解,但是有这样的话说PostgreSQL's COALESCE is non-standard,让我怀疑是否真的是我。
引用:
行类型为COALESCE
该规范将COALESCE(X,Y)定义为对CASE的句法转换,当X不为空则X否则为Y END(它通过禁止非确定性表达式或带有在这种情况下的副作用)。这样的结果是,对行类型的空测试应用了相当奇怪的规则。 PostgreSQL仅对X应用“不是空值”测试。因此,如果X是包含空列的行值,则PostgreSQL将返回X,而规范将要求返回Y。
(可爱的解释,对吧?)
我还遇到了一些信息,这些信息指示COALESCE数据类型必须匹配,否则该功能会自动失败。 (!)
我希望将字符串文字'Total'解释为varchar,而column_1在数据库中定义为varchar(12),但目前我不确定有什么要帮助的,非常感谢。
答案 0 :(得分:2)
问题是这样的:
group by rollup(coalesced_value)
您将根据应用coalesce()
之后的值 进行分组。因此,rollup
随后将生成null
值。
相反,按数据中的列分组:
select coalesce(column_1, 'Total') as coalesced_value,
sum(column_2) as column_sum
from table
where yada yada
group by rollup(column_1)
order by (column_1 is null)::int, -- put the total at the end
coalesced_value;
这将以您想要的方式显式排序结果。没有它,结果将是您想要的(我认为)。第一部分(column1 is null)::int
是转换为数字的布尔表达式。 Null值是true,并分配值为1;否则为0。为非NULL值分配一个0值。它们是第一个,因为排序是递增的(默认情况下)。
答案 1 :(得分:1)
我不是POSTGRESQL的专家,但是我仍然可以提供一些见解。最简单的方法是只使用子查询:
select coalesce(column_1,'Total') as coalesced_value
,column_sum
from
(
select column_1
,sum(column_2) as column_sum
from table
where yada yada
group by rollup(column_1)
) a
order by coalesced_value;
如果要避免子查询,则应该能够使用GROUPING函数。我知道这可以在Teradata SQL中使用,但是经过一番谷歌搜索之后,它似乎也应该在POSTGRESQL中使用:
select case when grouping(column_1) = 1 then 'Total'
else column_1 end as grouping_value
,sum(column_2) as column_sum
from table
where yada yada
group by rollup(column_1)
order by grouping_value;