PostgreSQL 10:跨连接用MAX函数遇空表全返回NULL的解决方案咨询
解决PostgreSQL 10中多表max查询遇空表全返回null的问题
我之前也遇到过一模一样的坑,你的问题根源出在笛卡尔积的特性上:当你用from a, b, c这种写法做查询时,只要其中任意一个表没有数据,整个连接后的结果集就会是空的。而MAX()函数作用在空数据集上会返回null,最终就导致所有字段都变成了null。
最优解决方案:拆分独立子查询求最大值
把每个表的MAX(modified_at)查询拆成独立的子查询,再将这些子查询做交叉连接。这样每个子查询都会独立执行,哪怕某个表为空,它的子查询也会返回一行(值为null),而其他有数据的表能正常返回正确的最大值。
具体SQL语句如下:
SELECT a_sub.a_modified_at, b_sub.b_modified_at, c_sub.c_modified_at FROM (SELECT MAX(modified_at) AS a_modified_at FROM a) AS a_sub, (SELECT MAX(modified_at) AS b_modified_at FROM b) AS b_sub, (SELECT MAX(modified_at) AS c_modified_at FROM c) AS c_sub;
原理说明
- 每个子查询
(SELECT MAX(...) FROM 表)都会返回恰好一行数据:如果表中有记录,就是该表modified_at的最大值;如果表为空,就返回null。 - 交叉连接(
,在PostgreSQL中等价于CROSS JOIN)这三个单行结果,最终会得到一行数据,其中有数据的表对应字段是正确的最大值,空表对应字段为null,完全匹配你的需求。
额外优化(可选)
如果你需要把空表对应的null替换成某个默认值(比如初始时间'1970-01-01'),可以用COALESCE()函数处理,示例如下:
SELECT COALESCE(a_sub.a_modified_at, '1970-01-01'::timestamp) AS a_modified_at, COALESCE(b_sub.b_modified_at, '1970-01-01'::timestamp) AS b_modified_at, COALESCE(c_sub.c_modified_at, '1970-01-01'::timestamp) AS c_modified_at FROM (SELECT MAX(modified_at) AS a_modified_at FROM a) AS a_sub, (SELECT MAX(modified_at) AS b_modified_at FROM b) AS b_sub, (SELECT MAX(modified_at) AS c_modified_at FROM c) AS c_sub;
内容的提问来源于stack exchange,提问作者xindi
相关产品推荐
相关产品推荐

