SQLServer中groupby⽤法以及容易出错的点SQL Server中,group by ⼀般是和聚合函数⼀起搭配使⽤的,不然⽤了也没什么意
义除了消除重复功能外,但消除重复⼀般使⽤distinct。
例如,有这样的⼀学⽣成绩表(学号,课程号,成绩)
我们按学号分组查询,
lect SNo from sc group by SNo
结果:
从上⾯我们可以看到,group by ⼦句可以将查询结果按某⼀列或多列的值进⾏分
组。
容易出错的点:
(1) 出现在lect后⾯的字段 要么是是聚合函数中的,要么是在group by 中的。
什么意思?
例如:还是上⾯那个表,当我执⾏以下语句:
lect sno,cno from sc group by sno
报错:(可能mySQL不会,因为它的执⾏是不严格的)
因为,我的lect字段中有cno课程号,但却不是在聚合函数或者group by⼦句中,所以报错。
正确⽤法:
//这⼀句是查看,每个⼈修读了⼏门课
lect sno,count(cno) from sc group by sno
//这⾥先按学号分组再按课程号分组,只按学号分组不会出现重复的学号的
lect sno,cno from sc group by SNo,CNo
小乌龟
人性向善4
(2) 如果是筛选结果 可以先使⽤where指定条件 再⽤group by 或者先⽤group by 再⽤having来指定条件,(聚合函数不能出现在where⼦句中,只可以和lect 或having搭配,SQL Server会报错,据说MySQL不会报错)
//查询选修两个门课及以上的学⽣
//报错
lect SNo from sc group by SNo where count(*)>1
//正解
lect SNo from sc group by SNo having count(*)>1
山楂条的做法//查看每个学⽣选了⼏门课,且选的课的成绩不为空
//报错,group by要在where后⾯
lect sno,count(cno) from sc group by SNo where score is not null
//正解
lect sno,count(cno) from sc where score is not null group by SNo
总结
名人对联之前在⾯试试题看到这样⼀道题,有⼀个学⽣成绩表,就像我们上⾯说的那个表⼀样,查询学⽣成绩重复的⾏。
确认过眼神,以为很简单,上来就是
lect Score from sc group by Score having count(*)>1 and score is not null
中暑的处理方法毫⽆疑问,当然是错的,⼀开始没看到是查询⾏,也就是查询的
要包括整个元组的信息。想了想改成:
lect * from sc group by Score having count(*)>1 and score is not null
也是错的,犯了上⾯的问题。想了想,⽆奈,⽤内连接。
隔着门缝吹喇叭lect a1.SNo,a1o,a1.Score from sc a1
inner join sc on sc.Score=a1.Score and (a1.SNo!=sc.SNo or a1o !=sco)
虽然结果对了,但是个⼈感觉要是做项⽬这样查,领导和同事得
⽤⼑砍死我,因为耗费资源,效率还慢。
哎,简洁写法
lect * from sc where score in(
lect Score from sc group by Score having count(*)>1至宝三鞭丸
其实你一直都在
and score is not null
)
这种东西还是得多练,刚上⼿时更是得练,如果感觉上⼿了就搁置⼀段时间,⽤到时⼜得回去翻笔记。写下来,希望和各位道友共勉。