我创建了虚拟表来探索SQL中的分组概念。
我想对要显示的数据进行分组,
我的问题:为什么SQL不允许在StudentID
子句中仅保留GROUP BY
,当我们在GROUP BY
子句中提到ID,name..other列时才允许。
我收到此错误:
列'SampleData.StudentName'在选择列表中无效,因为它既不包含在聚合函数中也不在GROUP BY子句中。
以及如何在SQL输出中以逗号分隔的方式显示主题?
这是我编写的SQL:
SELECT
StudentID,
StudentName,
Standard,
Subject,
SUM(MarksObtained)
FROM
SampleData
GROUP BY
StudentID, StudentName
--,Standard
--,Subject
ORDER BY
StudentID
供参考的样品表:
StudentID StudentName Standard Subject MarksObtained
-----------------------------------------------------
1 A VI Maths 59
3 C VII English 62
2 B IX Maths 75
2 B IX English 81
1 A VI Science 47
1 A VI History 61
预期输出:
StudentID StudentName Standard Subject MarksObtained
-------------------------------------------------------------------
1 A VI Maths,Science,History 167
3 C VII English 62
2 B IX Maths,English 156
答案 0 :(得分:0)
优良作法是将GROUP BY
定义的所有未协商字段都显式放入SELECT
子句中。某些RDBMS对此要求严格(例如Oracle),而其他RDBMS可能不严格(例如,禁用了sql模式ONLY_FULL_GROUP_BY
的MySQL)。
要在单个字段中串联Subject
,您需要一个汇总函数。并非所有RDBMS都具有相同的标准。他们通常接受ORDER BY
选项。
使用SQL Server 2017或更高版本:STR_AGG
:
SELECT
StudentID
,StudentName
,Standard
,STR_AGG(Subject, ',') WITHIN GROUP ( ORDER BY StudentID)
,SUM(MarksObtained)
FROM
SampleData
GROUP BY
StudentID
,StudentName
,Standard
ORDER BY
StudentID
使用MySQL:GROUP_CONCAT
:
SELECT
StudentID
,StudentName
,Standard
,GROUP_CONCAT(Subject ORDER BY StudentID SEPARATOR ', ')
,SUM(MarksObtained)
FROM
SampleData
GROUP BY
StudentID
,StudentName
,Standard
ORDER BY
StudentID
使用Oracle 11g或更高版本:LISTAGG
:
SELECT
StudentID
,StudentName
,Standard
,LISTAGG(Subject, ',') WITHIN GROUP ( ORDER BY StudentID)
,SUM(MarksObtained)
FROM
SampleData
GROUP BY
StudentID
,StudentName
,Standard
ORDER BY
StudentID
答案 1 :(得分:0)
第一个问题:
当您发布汇总(例如总和,计数,最大值,最小值,平均值)时,您需要对其他未汇总的列进行分组。汇总是针对已分组的列进行的。
您的查询语言为英语,
获取从SampleData获得的有关StudentID,StudentName,Standard,Subject的标记总和
第二个问题:
我们需要知道您正在使用哪个dbms。每个dbms系统都有自己的方法
LISTAGG(column, ',')
GROUP_CONCAT(column, ',')
STR_AGG(column, ',')