sql中的 where 、group by 和 having 用法解析

废话不多说了,直接给大家贴代码了,具体代码如下所示:

--sql中的 where 、group by 和 having 用法解析

--如果要用到group by 一般用到的就是“每这个字” 例如说明现在有一个这样的表:每个部门有多少人 就要用到分组的技术

select DepartmentID as '部门名称',COUNT(*) as '个数' from BasicDepartment group by DepartmentID
--这个就是使用了group by +字段 进行了分组,其中我们就可以理解为我们按照了部门的名称ID
--DepartmentID将数据集进行了分组;然后再进行各个组的统计数据分别有多少;
--如果不用count(*) 而用类似下面的语法
select DepartmentID,DepartmentName from BasicDepartment group by DepartmentID

--将会出现错误
--选择列表中的列 'BasicDepartment.DepartmentName' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
  这就是我们需要注意的一点,如果在返回集字段中,这些字段
  要么就要包含在Group By语句的后面,作为分组的依据;
  要么就要被包含在聚合函数中,作为分组的依据;
--出现的错误详解:咱们看看group by 的执行的过程,先执行select 的操作返回一个程序集,
--然后去执行分组的操作,这时候他将根据group by 后面的字段
--进行分组,并且将相同的字段并称一列数据,如果group by 后面没有这个字段的话就要分成好多的数据。
--但是分组就只能将相同的数据分成两列数据,而一列中又只能放入一个字段,所以那些没有进行分组的
--数据系统不知道将数据放入哪里,所以就出现此错误
--目前一种分组情况只有一条记录,一个数据格是无法放入多个数值的,
--所以这里就需要通过一定的处理将这些多值的列转化成单值,然后将其放在对应的
--数据格中,那么完成这个步骤的就是聚合函数。这就是为什么这些函数叫聚合函数(aggregate functions)了

--group by all语法解析:
--如果使用 ALL 关键字,那么查询结果将包括由 GROUP BY 子句产生的所有组,即使某些组没有符合搜索条件的行。
--没有 ALL 关键字,包含 GROUP BY 子句的 SELECT 语句将不显示没有符合条件的行的组。
select DepartmentID,DepartmentName as '部门名称',
COUNT(*) as '个数' from BasicDepartment group by all DepartmentID,DepartmentName

==========================================================================================================

--group by 和having 解释:前提必须了解sql语言中一种特殊的函数:聚合函数,
例如SUM, COUNT, MAX, AVG等。这些函数和其它函数的根本区别就是它们一般作用在多条记录上。

having是分组(group by)后的筛选条件,分组后的数据组内再筛选
where则是在分组前筛选

where子句中不能使用聚集函数,而having子句中可以,所以在集合函数中加上了HAVING来起到测试查询结果是否符合条件的作用。
即having子句的适用场景是可以使用聚合函数

having 子句限制的是组,而不是行
having 子句中的每一个元素也必须出现在select列表中。有些数据库例外,如oracle

当同时含有 where 子句、group by 子句 、having 子句及聚集函数时,执行顺序如下:
执行where子句查找符合条件的数据;
使用group by 子句对数据进行分组;对group by 子句形成的组运行聚集函数计算每一组的值;最后用having 子句去掉不符合条件的组

  ex:  显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。
    SELECT region, SUM(population), SUM(area)
    FROM bbc
    GROUP BY region
    HAVING SUM(area)>1000000
    在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。(where子句中不能使用聚集函数)
    相反,HAVING子句可以让我们筛选成组后的各组数据

  ex:create TABLE Table1
    (
      ID int identity(1,1) primary key NOT NULL,
      classid int,
      sex varchar(10),
      age int,
    )
    --添加测试多条数据
    Insert into Table1 values(1,'男',20)
    Insert into Table1 values(2,'女',22)
    Insert into Table1 values(3,'男',23)
    Insert into Table1 values(4,'男',22)
    Insert into Table1 values(1,'男',24)
    ..........
    查询每一个班级中年龄大于20,性别为男的人数至少为2个的情况
    select COUNT(age) as '>20岁人数',classid from Table1 where sex='男' group by classid having COUNT(age)>2

底下这个例子很好
    SQL> select * from sc;

        SNO PNO    GRADE
      ---------- ----- ----------
YW       95
SX       98
YY       90
YW      89
SX       91
YY       92
YW      85
SX       88
YY       96
YW      95
SX       89
YY       88

    这个表所描述的是4个学生对应每科学习成绩的记录,其中SNO(学生号)、PNO(课程名)、GRADE(成绩)。

    1、显示90分以上学生的课程名和成绩

    //这是一个简单的查询,并没有使用分组查询

    SQL> select sno,pno,grade from sc where grade>=90;

        SNO PNO    GRADE
      ---------- ----- ----------
YW      95
SX       98
YY       90
SX       91
YY       92
YY       96
YW      95

    2、显示每个学生的成绩在90分以上的各有多少门

    --进行分组显示,并且按照where条件之后计数

    SQL> select sno,count(*) from sc where grade>=90 group by sno;

        SNO  COUNT(*)
    -  --------- ----------
     3
     2
     1
     1

    3、这里我们并没有使用having语句,接下来如果我们要评选三好学生,条件是至少有两门课程在90分以上才能有资格,
      列出有资格的学生号及90分以上的课程数。

    //进行分组显示,并且按照where条件之后计数,在根据having子句筛选分组

    SQL> select sno,count(*) from sc where grade>=90 group by sno having count(*)>=2;

        SNO  COUNT(*)
    ---------- ----------
     3
     2

    这个结果是我们想要的,它列出了具有评选三好学生资格的学生号,跟上一个例子比较之后,发现这是在分组后进行的子查询。

    4、学校评选先进学生,要求平均成绩大于90分的学生都有资格,并且语文课必须在95分以上,请列出有资格的学生

    //实际上,这个查询先把语文大于95分的学生号提取出来,之后求平均值,分组显示后根据having语句选出平均成绩大于90的

    SQL> select sno,avg(grade) from sc where SNO IN (SELECT SNO FROM SC WHERE GRADE>=95 AND PNO='YW') group by sno having avg(grade)>=90;

        SNO AVG(GRADE)
    ---------- ----------
  94.3333333
  90.6666667

    5、查询比平均成绩至少比学号是3的平均成绩高的学生学号以及平均分数

    //having子句中可进行比较和子查询
    SQL> select sno,avg(grade) from sc
         group by sno
         having avg(grade) > (select avg(grade) from sc where sno=3);
(0)

相关推荐

  • 详解SQL中Group By的用法

    GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组. 1.概述 "Group By"从字面意义上理解就是根据"By"指定的规则对数据进行分组,所谓的分组就是将一个"数据集"划分成若干个"小区域",然后针对若干个"小区域"进行数据处理. 2.原始表 3.简单Group By 示例1 select 类别, sum(数量) as 数量之和 from A group by 类别 返回结果如下表

  • MySql中having字句对组记录进行筛选使用说明

    having的用法 having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前.而 having子句在聚合后对组记录进行筛选. SQL实例: 一.显示每个地区的总人口数和总面积 SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region 先以region把返回记录分成多个组,这就是GROUP BY的字面含义.分完组后,然后用聚合函数对每组中的不同字段

  • mysql中group by与having合用注意事项分享

    group by函数应该的使用应该是SELECT 列表中指定的每一列也必须出现在 GROUP BY 子句中,除非这列是用于聚合函数,但是今天帮同事调试一个mysql中的group by函数,让我大跌眼镜,当时感觉不可思议,然后回来做了个简化版试验,试验过程如下: mysql表结构 复制代码 代码如下: mysql> desc t;+---+----–+--+-–+---+---+| Field | Type | Null | Key | Default | Extra |+---+----–+-

  • MySQL分组查询Group By实现原理详解

    由于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作.当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算.所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引. 在MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用.下面我们分别针对这三种实现方式做一个分

  • sql语句中where和having的区别

    HAVING是先分组再筛选记录,WHERE在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前:而 HAVING子句在聚合后对组记录进行筛选. 作用的对象不同.WHERE 子句作用于表和视图,HAVING 子句作用于组.WHERE 在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算), 而 HAVING 在分组和聚集之后选取分组的行.因此,WHERE 子句不能包含聚集函数: 因为试图用聚集函数判断那些行输入给聚集运算是没有意义的. 相反,HAVING 子句总是

  • 解析sql语句中left_join、inner_join中的on与where的区别

    table a(id, type):id     type ----------------------------------1      1         2      1          3      2          table b(id, class):id    class ---------------------------------1      12      2sql语句1:select a.*, b.* from a left join b on a.id = b

  • MySQL左联多表查询where条件写法示例

    复制代码 代码如下: select * from _test a left join _test b on a.id=b.id where a.level='20' and a.month='04' and b.level='20' and b.month='03'; select a.*,b.* from (select * from _test where level='20' and month='04') as a left join (select * from _test where

  • MySQL Where 条件语句介绍和运算符小结

    WHERE 条件 有时候操作数据库时,只操作一些有条件限制的数据,这时可以在SQL语句中添加WHERE子句来规定数据操作的条件. 语法: 复制代码 代码如下: SELECT column,- FROM tb_name WHERE definition WHERE 关键字后面接有效的表达式(definition),该表达式表示被操作的数据记录必须满足的条件. 除 SELECT 外,WHERE 条件关键字可以用于任何 SQL 语法允许的场合,如 UPDATE(更新).DELETE(删除)等. 例子:

  • Mysql中order by、group by、having的区别深入分析

    order by 从英文里理解就是行的排序方式,默认的为升序. order by 后面必须列出排序的字段名,可以是多个字段名.  group by 从英文里理解就是分组.必须有"聚合函数"来配合才能使用,使用时至少需要一个分组标志字段. 什么是"聚合函数"? 像sum().count().avg()等都是"聚合函数" 使用group by 的目的就是要将数据分类汇总. 一般如: select 单位名称,count(职工id),sum(职工工资)

  • 详解MySQL中WHERE子句的用法

    我们已经看到SQL SELECT命令来从MySQL表获取数据.我们可以使用一个条件子句WHERE子句中筛选出来的结果.使用WHERE子句,我们可以指定一个选择的标准来从表中选择所需的记录. 语法: 下面是通用的SQL WHERE子句来获取数据从MySQL表的SELECT命令的语法: SELECT field1, field2,...fieldN table_name1, table_name2... [WHERE condition1 [AND [OR]] condition2..... 可以使

  • MySQL中distinct与group by之间的性能进行比较

    最近在网上看到了一些测试,感觉不是很准确,今天亲自测试了一番.得出了结论,测试过程在个人计算机上,可能不够全面,仅供参考. 测试过程: 准备一张测试表 CREATE TABLE `test_test` ( `id` int(11) NOT NULL auto_increment, `num` int(11) NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1

随机推荐