数据库中使用SQL作分组处理01(简单分组)
1.简单分组
GroupBy什么就Select什么
SELECT Name,Score
From StudentScore
GROUP BY Name,Score
2.聚合函数(MAX SUM AVG COUNT)
(1)计算
1.表的全部字段都可以用聚合函数,但是筛选聚合函数的结果要用Having关键字
2.聚合函数默认排除Null值
ID | Name | Score |
1 | 小苏 | 100 |
2 | 小苏 | 92 |
3 | 小苏 | 80 |
4 | 小军 | 50 |
5 | 小军 | NULL |
6 | 小军 | 62 |
7 | 小红 | 98 |
8 | 小红 | 85 |
9 | 小红 | 90 |
SELECTName,SUM(Score) AS AllScore,AVG(Score) AS AverageScore,MAX(Score) AS MaxScore,MIN(Score) AS MinScore,Count(Score) As ExamCount,COUNT(CASE WHEN Score >= 60 THEN 1 END) AS PassedCount
FROM StudentScore
GROUP BY Name;
查询结果(结论:聚合函数默认排除Null值):
(2)条数查询
1.现代数据库中,COUNT(1) 和 COUNT(*) 查询结果一致,效率一致
2.Count(字段) 查的是 该分组 中这个字段 ≠ NULL 的条数
3.Count(非分组字段) 中,重复的非 NULL 值都会被算进去,COUNT(DISTINCT 非分组字段) 则计算的是非NULL非重复的条数,简而言之,COUNT里面加DISTINCT,结果会更少
SELECTName -- 分组字段1,Score -- 分组字段2,Count(Name) As NameCount -- 该分组中 Name ≠ NULL 的条数,Count(Score) As ScoreCount-- 该分组中 Score ≠ NULL 的条数,COUNT(1) -- 该分组中的条数(不看字段的值),COUNT(*) -- 该分组中的条数(不看字段的值)
FROM StudentScore
GROUP BY Name,Score;
【不分组全查】
SELECT COUNT(1) FROM StudentScore; --不分组,查全表条数
3.非聚合字段查询
【错误的写法】根据标题一,Group字段 和 Select字段 不一致会报错(但是我想显示出Score)
SELECT Name, Age, ScoreFROM PERSONGROUP BY Name, Age;
【方法一】取分组的MAX值
SELECT Name, Age, MAX(SCORE) AS ScoreFROM PERSONGROUP BY Name, Age;
【方法二】子查询(不推荐,不一定是唯一的)
SELECT Name,Age,(SELECT SCORE FROM SCORETABLE WHERE NAME=NAME) AS ScoreFROM PERSONGROUP BY Name,Age
4.聚合结果字段、别名字段查询
【引入】
SELECT ID,NAME,MAX(SCORE),(SELECT Code FROM TABLE2 WHERE ID = ID) AS Code
FROM TABLE
WHERE Code=500 AND SCORE > 60
GROUP BYID,NAME
这个SQL是不对的,不能对聚合函数和别名字段直接筛选,且ID=ID有歧义,解决方案有两个:
(1)SQL外包一层
SELECT * FROM (你的SQL) AS SubQuery WHERE 你的SQL的条件
SELECT *
FROM (SELECT ID,NAME,MAX(SCORE) AS MaxScore,(SELECT Code FROM TABLE2 WHERE ID = T.ID) AS Code --注意这里ID = T.ID 的 T 指代表名很重要FROM TABLE TGROUP BY ID, NAME
) AS SubQuery
WHERE Code = 500 AND MaxScore > 60;
--【注】包完之后一定要 'AS SubQuery',否则报错
(2)Having关键字
对于 聚合函数的结果 用 Having 筛选,对于别名字段在 子查询SQL 中过滤
SELECT ID,NAME,MAX(SCORE) AS MaxScore,(SELECT Code FROM TABLE2 WHERE ID = T.ID AND Code = 500) AS Code --注意这里ID = T.ID 的 T 指代表名很重要
FROM TABLE T
GROUP BY ID, NAME
HAVING MAX(SCORE) > 60;
--【注】HAVING SCORE > 60 是不对的。