Having基础用法

集合结果指定条件

注:HAVING子句中能够使用三种要素:常数,聚合函数,GROUP BY子句中指定的列名(聚合建)

HAVING子句:

用having就一定要和group by连用, 用group by不一有having(它只是一个筛选条件用的)

商品品种分组后结果中筛选出数据行数为2行的数据:
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING COUNT(*) = 2;
平均数,销售价格大于2500的
SELECT product_type, AVG(sale_price)
FROM Product
GROUP BY product_type
HAVING AVG(sale_price) >= 2500;

相对于HAVING子句,更适合写再Where子句中的条件:

  • where子句 = 指定行所对应的条件
  • having子句 = 指定组所对应的条件

    聚合建所对应的条件不应该书写在HAVING子句中,而应书写在WHERE子句当中。虽执行结果一样,但将条件写在where子句中比写在having子句中的处理速度更快,返回结果时间更短。

    原因:聚合操作时,DBMS内部会进行排序处理,where在排序之前就对数据进行过滤,having是在排序之后在对数据进行分组。
-- 先过滤后分组
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING product_type = '衣服'; -- 先分组后过滤(性能差点)
SELECT product_type, COUNT(*)
FROM Product
WHERE product_type = '衣服'
GROUP BY product_type;

寻找缺失编号

seq name
1 小明
2 小红
3 小王
5 小李
6 小黄
8 小小
-- 查看是否存在缺失编号
SELECT '存在缺失的编号' AS gap
FROM SeqTbl
HAVING COUNT(*) <> MAX(seq);
-- 查询缺失编号的最小值
SELECT MIN(seq + 1) AS ga
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl)

如果表 SeqTbl 里包含 NULL ,那么这条 SQL 语句的查询结果就不正确了(因为null值表示不确定)

用 HAVING 子句进行子查询:求众数

平均值有一个缺点,那就是很容易受到离群值(outlier)的影响。这种时候就必须使用更能准确反映出群体趋势的指标——众数(mode)就是其中之一。它指的是在群体中出现次数最多的值

CREATE TABLE Graduates
(name VARCHAR(16) PRIMARY KEY,
income INTEGER NOT NULL);
-- 桑普森是个离群值,会拉高平均数
INSERT INTO Graduates VALUES('桑普森', 400000);
INSERT INTO Graduates VALUES('迈克', 30000);
INSERT INTO Graduates VALUES('怀特', 20000);
INSERT INTO Graduates VALUES('阿诺德', 20000);
INSERT INTO Graduates VALUES('史密斯', 20000);
INSERT INTO Graduates VALUES('劳伦斯', 15000);
INSERT INTO Graduates VALUES('哈德逊', 15000);
INSERT INTO Graduates VALUES('肯特', 10000);
INSERT INTO Graduates VALUES('贝克', 10000);
INSERT INTO Graduates VALUES('斯科特', 10000);
-- 众数的SQL 语句(1):使用谓词
SELECT income, COUNT(*) AS cnt
FROM Graduates
GROUP BY income HAVING COUNT(*) >= ALL ( SELECT COUNT(*) FROM Graduates GROUP BY income)

ALL 谓词用于 NULL 或空集时会出现问题,可以用极值函数来代替

-- 求众数的SQL 语句(2) :使用极值函数
SELECT income, COUNT(*) AS cnt
FROM Graduates
GROUP BY incomeHAVING COUNT(*) >= ( SELECT MAX(cnt)
FROM ( SELECT COUNT(*) AS cnt
FROM Graduates
GROUP BY income) TMP )

用 HAVING 子句进行自连接:求中位数

中位数:统计学中的专有名词,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。

-- 将集合里的元素按照大小分为上半部分和下半部分两个子集,同时让这 2 个子集共同拥有集合正中间的元素
SELECT T1.income FROM Graduates T1, Graduates T2 GROUP BY T1.income
HAVING SUM(CASE WHEN T2.income >= T1.income THEN 1 ELSE 0 END) >= COUNT(*) / 2
AND SUM(CASE WHEN T2.income <= T1.income THEN 1 ELSE 0 END) >= COUNT(*) / 2 -- 将上下部分集合平均然后得中值
SELECT AVG(DISTINCT income) FROM (
SELECT T1.income FROM Graduates T1, Graduates T2 GROUP BY T1.income
HAVING SUM(CASE WHEN T2.income >= T1.income THEN 1 ELSE 0 END) >= COUNT(*) / 2
AND SUM(CASE WHEN T2.income <= T1.income THEN 1 ELSE 0 END) >= COUNT(*) / 2 ) TMP;

查询不包含 NULL 的集合

COUNT()和COUNT(列)的区别:

第一个是性能上的区别;

第二个是 COUNT(
)可以用于NULL,而COUNT(列名)与其他聚合函数一样,要先排除掉NULL 的行再进行统计。

CREATE TABLE Students
(student_id INTEGER PRIMARY KEY,
dpt VARCHAR(16) NOT NULL,
sbmt_date DATE); INSERT INTO Students VALUES(100, '理学院', '2005-10-10');
INSERT INTO Students VALUES(101, '理学院', '2005-09-22');
INSERT INTO Students VALUES(102, '文学院', NULL);
INSERT INTO Students VALUES(103, '文学院', '2005-09-10');
INSERT INTO Students VALUES(200, '文学院', '2005-09-22');
INSERT INTO Students VALUES(201, '工学院', NULL);
INSERT INTO Students VALUES(202, '经济学院', '2005-09-25');
-- 查询“提交日期”列内不包含NULL 的学院(1) :使用COUNT 函数
SELECT dpt
FROM Students
GROUP BY dpt
HAVING COUNT(*) = COUNT(sbmt_date); -- 查询“提交日期”列内不包含NULL 的学院(2) :使用CASE 表达式
SELECT dpt
FROM Students
GROUP BY dpt
HAVING COUNT(*) = SUM(CASE WHEN sbmt_date IS NOT NULL THEN 1 ELSE 0 END);

Having子句用法的更多相关文章

  1. sql语句having子句用法,很多时候你曾忘掉

    显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区. SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY reg ...

  2. mysql LIMIT 子句用法及原理

    使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,已 经为我们提供了这样一个功能. LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接 ...

  3. SQL Server output子句用法 output inserted.id 获取刚插入数据的id

    --插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...

  4. Oracle学习之start with...connect by子句的用法

    转自:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html,多谢博主分享 Oracle中start with…connect by ...

  5. Hierarchical query-层次查询之START WITH CONNECT BY用法

    Hierarchical query-层次查询中start with...connect by prior子句用法: connect by 是结构化查询中用到的,其基本语法是:  select ... ...

  6. OpenMP用法大全

    OpenMP基本概念OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并 ...

  7. java基础高级2 MySQL 高级

    1.数据库简介 DDL(数据定义语言) DML(数据操作语言) 2. 准备工作 解压缩文件目录下找到my.ini文件,文件中写入[mysql] default-character set= utf-8 ...

  8. sql 几点记录

      1       With子句 1.1     学习目标 掌握with子句用法,并且了解with子句能够提高查询效率的原因. 1.2     With子句要点 with子句的返回结果存到用户的临时表 ...

  9. 并行计算之OpenMP中的任务调度

    本文参考<OpenMP中的任务调度>博文,主要讲的是OpenMP中的schedule子句用法. 一.应用需求 在OpenMP并行计算中,任务调度主要用于并行的for循环.当for循环中每次 ...

随机推荐

  1. 常用Git命令大全思维导图

    开发中代码管理少不了使用Git,对于初学者来说Git命令的学习是一个难过的坎,为了帮助大家记忆并快速掌握Git的基本使用,我把常用的Git命令整理成思维导图,分享给大家. 高清大图在线预览 http: ...

  2. 用sqlldr导入csv文件

    1.新建文件test.ctl,内容如下 load dataCHARACTERSET 'UTF16' \*指定编码格式,很重要*\ infile 'vodall.csv' append into tab ...

  3. Windows超级卸载工具Total Uninstaller,能完全卸载.NET Framework

    https://github.com/tsasioglu/Total-Uninstaller

  4. 一段关于python 闭包的例子

    >>> def counter(a=0): ... count = a ... def incr(): ... b = 1 + count ... return b ... retu ...

  5. 为什么视频流一般都用UDP

    我们知道TCP 和 UDP的一个区别之一就是TCP要保证丢失的package会被再次重发,确保对方能够收到. 而在视频播放中,如果有一秒钟的信号确实,导致画面出现了一点瑕疵,那么最合适的办法是把这点瑕 ...

  6. AngularJS:让submit重新生效

    当我们在html中声明了ng-app后,form的submit就会失效,必须通过angularJS来处理.如果这时还是想用普通的方式提交的话,需要修改form标签,如下所示: <form met ...

  7. MVC.Net:读取Web.config/App.config配置

    需要读取Web.config/App.config的配置很简单,首先我们需要将配置写入到<appSettings>中,例如: <appSettings> <add key ...

  8. keras与sklearn的结合使用

    keras与sklearn的结合使用 新建 模板 Fly Time: 2017-4-14 引言 代码 引言 众所周知,keras目前没有提供交叉验证的功能,我们要向使用交叉验证,就需要与sklearn ...

  9. Spring 计时器 @Scheduled cron 含义

    Spring 计时器 @Scheduled cron 含义 学习:http://blog.csdn.net/prisonbreak_/article/details/49180307 http://b ...

  10. MySQL命令行登陆

    环境介绍 OS:CentOS6.X & Win2003 & Win2008 MySQL版本号:5.5.x 除了经常使用的MySQL管理工具,还有MySQLclient命令行工具经常被用 ...