sql - 使用选择列分组我无法在分组依据子句中输入
问题描述
我写了一个查询是SQL Server,它从customers 表中选择first_name,然后从students 表中选择grade。它在没有 CASE 表达式的情况下也可以正常工作,在 MySQL 中也可以正常工作,但是在 SQL Server 中,我似乎一直遇到以下问题:
消息 8120,级别 16,状态 1,第 81 行列 'papers.grade' 在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中。
我真的不知道为什么这是一个问题,我发现的唯一解决方案是将它作为“GROUP BY first_name,grade”包含在 group by 中。但是,这会修改我的输出,因此不可用。谁能解释一下为什么这个错误不断发生?将不胜感激。
我的sql查询
SELECT
first_name,
AVG(ISNULL(grade, 0)) AS average,
CASE
WHEN grade < 75 THEN'failing'
ELSE'passing' ENDAS result
FROM students
LEFT JOIN papers
ON papers.student_Id = students.id
GROUP BY first_name
ORDER BY average DESC
解决方案
您的查询失败,因为case
表达式 ( grade
) 中有一个不属于该group by
子句的未聚合列。在大多数数据库中,这是一个致命错误——尽管 MySQL 对此很松懈,这可能会导致令人惊讶的行为。
最有可能的是,您想要:
SELECT
s.first_name,
AVG(ISNULL(p.grade, 0)) AS average,
CASE WHEN AVG(ISNULL(p.grade, 0)) < 75 THEN 'failing' ELSE 'passing' END result
FROM students s
LEFT JOIN papers p ON p.student_Id = s.id
GROUP BY s.id, s.first_name
ORDER BY average DESC
这将result
根据grade
每个的平均值设置student
。
请注意,我在您的查询中添加了表别名,并在每列前面加上它所属的表;这使得查询更易于阅读和编写,并且对底层表结构毫不含糊。
旁注:我对ISNULL()
聚合函数中的构造非常怀疑AVG()
;AVG()
忽略NULL
s 值,因此您的表达会导致没有成绩的学生获得0
平均值,而不是NULL
- 这可能不是您真正想要的。
推荐阅读
- node.js - 在计时器或 RDS 事件上将数据发送到 websocket 连接
- javascript - 反应电话输入数字值格式问题
- xpath - 阻止 xPath 请求
- java - 检查 Gzip 中的文件是否是 JAVA 中的 Xml?
- python-3.x - 将图像加载到 TKinter Canvas 小部件时的奇怪行为
- ruby - 为使用 Ruby 上传的对象设置 AWS S3 存储类
- angular - ng test 和 ng serve 失败并显示“发生未处理的异常:无效或意外的令牌”
- sql - SQL - 13 个数字列的组合如何等于 1 列
- javascript - 如何使用ajax get rest api从aws s3获取对象
- python - 如何使用 Selenium 和 Python 从通过 xpath 找到的 webdriver 元素中提取文本