使用CASE语句与窗口函数结果异常,请求排查(MySQL)
问题原因
你遇到的核心问题是MySQL对标识符(列名)和字符串字面量的解析规则:
- MySQL默认情况下,双引号
"用于表示字符串,而非列名。你在CASE语句里写的total_sales > "City Average Total Sales",实际是把数值型的total_sales和字符串"City Average Total Sales"做比较。 - MySQL会自动将字符串隐式转换为数值,
"City Average Total Sales"转成数值后是0,所以只要total_sales大于0,就会触发第一个WHEN条件,导致所有行都返回"Above Average"。
解决方案
针对带空格的列名,有两种处理方式:
- 方式一:用反引号
`包裹列名(MySQL中标识符的标准写法) - 方式二:修改子查询中的列名,去掉空格(更推荐,避免后续出现类似问题)
修正后的SQL代码(方式一)
select *, case when total_sales > `City Average Total Sales` then "Above Average" when total_sales < `City Average Total Sales` then "Below Average" when total_sales = `City Average Total Sales` then "Equal to Average" end as "Sales Tracking" from ( select *, round(total_sales / Population, 0) AS `Revenue Over Residents`, round(avg(total_sales) over (Partition by city), 2) as `City Average Total Sales` from nm_cannabis_sales_population ) a;
修正后的SQL代码(方式二,更规范)
select *, case when total_sales > city_avg_total_sales then "Above Average" when total_sales < city_avg_total_sales then "Below Average" when total_sales = city_avg_total_sales then "Equal to Average" end as sales_tracking from ( select *, round(total_sales / Population, 0) AS revenue_over_residents, round(avg(total_sales) over (Partition by city), 2) as city_avg_total_sales from nm_cannabis_sales_population ) a;
补充说明
如果你的MySQL开启了ANSI_QUOTES模式,双引号会被当作标识符,但默认是关闭的,所以不依赖这个模式更稳妥。使用下划线命名的列名符合SQL的通用规范,能减少这类语法陷阱。
内容的提问来源于stack exchange,提问作者Bobby
相关产品推荐
相关产品推荐

