两种含条件的SQL窗口聚合写法哪种更优?
两种SQL写法对比与优劣判断
首先需要纠正第二个语句的笔误:COUT是拼写错误,正确写法应为COUNT,修正后的语句如下:
SELECT CASE WHEN val IS NOT NULL THEN COUNT(*) OVER() ELSE 0 END c
1. 逻辑正确性差异
- 第一种写法:
COUNT( CASE WHEN val IS NOT NULL THEN val ELSE 0 END) OVER() c
COUNT函数会忽略NULL值,但这里的CASE分支中,无论val是否为NULL,返回的结果都是非NULL值(val非空时返回val,为空时返回0),因此这个COUNT实际统计的是全表总行数,和直接写COUNT(*) OVER()效果完全一致,属于冗余写法。 - 修正后的第二种写法:
CASE WHEN val IS NOT NULL THEN COUNT(*) OVER() ELSE 0 END c
逻辑是对每一行做判断:若当前行的val不为NULL,就返回全表总行数;若当前行val为NULL,则返回0。最终结果会包含两种值:全表行数(对应val非空的行)和0(对应val为空的行)。
2. 性能与可读性分析
- 性能上,两种写法都依赖窗口函数
OVER(),都会扫描全表一次,但第一种写法的CASE分支完全多余,既增加了代码复杂度,又没有实际意义,可读性极差。 - 第二种写法逻辑清晰,直接表达了业务意图,可读性远优于第一种。如果业务需求就是“当前行val非空时返回总行数,否则返回0”,那第二种是合理的写法;如果需求是统计val非空的行数,那两种都不符合要求,应该写成
COUNT(val) OVER()或者COUNT(CASE WHEN val IS NOT NULL THEN 1 END) OVER()。
3. 结论
如果是实现“当前行val非空时返回全表总行数,否则返回0”的逻辑,修正后的第二种写法更优,逻辑清晰、可读性强;第一种写法冗余且无法实现第二种的业务逻辑,完全没有使用价值。
内容的提问来源于stack exchange,提问作者Ray Ronnaret
相关产品推荐
相关产品推荐

