SELECT中的CASE语句如何影响ORDER BY的排序结果?
问题原因解析
核心差异源于ORDER BY count引用的列对象不同,结合数据库的NULL排序规则,最终导致了NULL位置的差异:
1. 先明确CTE foo 中的count值
count(u.id)统计的是非NULL的u.id数量,左连接后LA没有匹配的用户,u.id为NULL,因此count(u.id)=0。所以foo里的count是纯数值列:
- NY → 2
- SF → 1
- LA → 0
完全没有NULL值。
2. 查询A和B的行为解释
- CASE逻辑:当
foo.count>0时返回原数值,否则返回NULL。最终SELECT的第二列结果是:NY→2,SF→1,LA→NULL。 - 排序逻辑:
ORDER BY count引用的是foo中的数值型count列(因为CASE结果没有设置别名,数据库优先解析FROM子句中的列)。 - 按数值0、1、2升序排序,结果顺序为LA(0)→SF(1)→NY(2),对应SELECT的第二列就是NULL→1→2,所以NULL排在首位。
- NULLS LAST无效的原因:排序的列是
foo.count(纯数值,无NULL),NULLS LAST只对包含NULL的列排序生效,因此不会改变结果顺序。
3. 查询C的行为解释
- CASE逻辑:当
foo.count=0时返回NULL,否则返回原数值。SELECT的第二列结果同样是:NY→2,SF→1,LA→NULL。 - 排序逻辑:这里的
ORDER BY count被数据库解析为SELECT里的CASE结果(在MySQL中,若SELECT表达式使用了与FROM子句同名的列,ORDER BY会优先引用SELECT的表达式结果;或实际运行时给CASE结果加了别名count)。 - 以MySQL为例,默认升序规则是
NULLS LAST,按CASE结果(2、1、NULL)升序排序时,顺序为SF(1)→NY(2)→LA(NULL),所以NULL排在末位。 - NULLS FIRST有效的原因:添加
NULLS FIRST后,排序规则改为NULL优先,NULL会跑到首位,因此该修饰符生效。
内容的提问来源于stack exchange,提问作者konart
相关产品推荐
相关产品推荐

