首页 > 解决方案 > 使用选择列分组我无法在分组依据子句中输入

问题描述

我写了一个查询是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

标签: sqlsql-servertsqljoingroup-by

解决方案


您的查询失败,因为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()忽略NULLs 值,因此您的表达会导致没有成绩的学生获得0平均值,而不是NULL- 这可能不是您真正想要的。


推荐阅读