GroupBy 语句用来对选择的结果进行分组,GroupBy通常和聚合函数一起使用。比如有下面的一张表:
如果我们要将其按照City分组,并且计算出每个City的工资总和的话,可以使用下面的语句:
SELECT [City],SUM([Salary]) AS TotalSalary FROM [Sample].[dbo].[tblEmployee] GROUP BY [City]
下面是执行结果:
这里有一点要注意的是:如果我们不写Group By 语句,那么上面的代码会报错。原因很简单既然我们想用SUM函数来求和,那么我们应该指定如何对其分组。
Msg 8120, Level 16, State 1, Line 2
Column ‘Sample.dbo.tblEmployee.City‘ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
下面,我们更进一步。上面的代码演示了根据City对结果进行分组,并求出每一组City的工资总和。现在我们还想在这个基础上再根据性别(Gender)进行分组,也就是说,显示出同一个City中不同性别的人的工资总和。下面的代码可以实现该功能:
SELECT [City],[Gender],SUM([Salary]) AS TotalSalary FROM [Sample].[dbo].[tblEmployee] GROUP BY [City],[Gender] ORDER BY [City]
下面是查询结果:
在文章的最开始讲到,Group By 语句通常和聚合函数一起使用。前面的例子演示了Group By和SUM函数一起使用,其实我们还可以在查询语句中加入更多的聚合函数。如,我们在第一个例子的基础上还想计算出每个City的员工总数,那么可以使用下面的查询语句:
SELECT [City],[Gender],SUM([Salary]) AS TotalSalary,COUNT(*) AS TotalEmployee FROM [Sample].[dbo].[tblEmployee] GROUP BY [City],[Gender] ORDER BY [City]
下面是查询结果:
好的,通过上面的几个小例子我们已经了解到了,Group By语句可以和不同的聚合函数配合使用。有朋友可能会问,如果我想对结果进行筛选该怎么实现呢?比如,我们只想要性别为男性(Male)的员工的统计结果,该如何实现?聪明的你一定想到了使用where语句。完全正确!通过where语句可以对查询结果进行筛选,请看下面的示例代码:
SELECT [City],SUM([Salary]) AS TotalSalary,COUNT(*) AS TotalEmployee FROM [Sample].[dbo].[tblEmployee] WHERE [Gender] = ‘Male‘ GROUP BY [City] ORDER BY [City]
下面是查询结果:
可以看到,通过where语句我们实现了想要的功能:只选出性别为男性的员工,并且根据City进行分组然后计算出总的工资数和总的员工数。
其实,除了用where语句我们还可以用Having子句对查询结果进行筛选,请看下面的代码:
SELECT [City],[Gender],SUM([Salary]) AS TotalSalary,COUNT(*) AS TotalEmployee FROM [Sample].[dbo].[tblEmployee] GROUP BY [City],[Gender] HAVING [Gender] = ‘Male‘ ORDER BY [City]
下面是运行结果:
同样,我们得到了想要的结果。
那么使用Where子句和Having子句有什么区别呢?总结如下(这也是面试中经常被问到的问题):
- Where语句可以被应用在Select、Insert、Update语句中,然而Having子句只能用在Select语句中
- Where语句在聚合函数生效之前就对结果集进行了过滤,然而,Having子句是聚合函数生效过后再将结果集进行过滤
- 聚合函数不能出现在where子句中,但是聚合函数可以出现在Having子句中