Postgresql COALESCE with String Literals does not work as expected
我正在尝试从汇总中输出和标记总计列。
1 2 3 4 5 6 | 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的COALESCE是非标准的,这让我怀疑它是否真的是我。
报价:
COALESCE on row types
The spec defines COALESCE(X,Y) as a syntactic transformation to CASE WHEN X IS NOT NULL THEN X ELSE Y END (it leaves open the question of whether X is really evaluated twice by disallowing non-deterministic expressions or expressions with side effects in this context). A consequence of this is that the rather odd rules for null tests of row types are applied.
PostgreSQL applies only the"is not the null value" test to X. Accordingly, if X is a row value containing null columns, PostgreSQL will return X, while the spec would require returning Y.
(可爱的解释,对吧?)
我还遇到了一些信息,这些信息指示COALESCE数据类型必须匹配,否则该功能将以静默方式失败。 (!)
我希望将字符串文字'Total'解释为varchar,而column_1在数据库中定义为varchar(12),但是目前我还不确定有什么事情,任何帮助将不胜感激 。
问题是这样的:
1 | GROUP BY rollup(coalesced_value) |
应用
而是,按数据中的列分组:
1 2 3 4 5 6 7 | 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; |
这将按照您想要的方式显式排序结果。 没有它,结果将是您想要的(我认为)。 第一部分
我不是POSTGRESQL的专家,但是我仍然可以提供一些见解。 最简单的方法是只使用子查询:
1 2 3 4 5 6 7 8 9 10 11 | 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中工作:
1 2 3 4 5 6 7 | 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; |