分组数据问题

时间:2019-01-13 16:46:50

标签: sql

我创建了虚拟表来探索SQL中的分组概念。

我想对要显示的数据进行分组,

  1. 学生的总成绩。
  2. 要以逗号分隔的方式显示主题。

我的问题:为什么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   

2 个答案:

答案 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系统都有自己的方法

  • Oracle有LISTAGG(column, ',')
  • mysql具有GROUP_CONCAT(column, ',')
  • MSSQL具有STR_AGG(column, ',')