Having子句用法
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子句用法的更多相关文章
- sql语句having子句用法,很多时候你曾忘掉
显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区. SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY reg ...
- mysql LIMIT 子句用法及原理
使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,已 经为我们提供了这样一个功能. LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接 ...
- SQL Server output子句用法 output inserted.id 获取刚插入数据的id
--插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...
- Oracle学习之start with...connect by子句的用法
转自:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html,多谢博主分享 Oracle中start with…connect by ...
- Hierarchical query-层次查询之START WITH CONNECT BY用法
Hierarchical query-层次查询中start with...connect by prior子句用法: connect by 是结构化查询中用到的,其基本语法是: select ... ...
- OpenMP用法大全
OpenMP基本概念OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并 ...
- java基础高级2 MySQL 高级
1.数据库简介 DDL(数据定义语言) DML(数据操作语言) 2. 准备工作 解压缩文件目录下找到my.ini文件,文件中写入[mysql] default-character set= utf-8 ...
- sql 几点记录
1 With子句 1.1 学习目标 掌握with子句用法,并且了解with子句能够提高查询效率的原因. 1.2 With子句要点 with子句的返回结果存到用户的临时表 ...
- 并行计算之OpenMP中的任务调度
本文参考<OpenMP中的任务调度>博文,主要讲的是OpenMP中的schedule子句用法. 一.应用需求 在OpenMP并行计算中,任务调度主要用于并行的for循环.当for循环中每次 ...
随机推荐
- BNUOJ 1021 信息战(七)——情报传递
信息战(七)——情报传递 Time Limit: 3000ms Memory Limit: 262144KB 64-bit integer IO format: %lld Java clas ...
- linux 各命令字 练习
=============================================================== ...
- 1393 0和1相等串 51nod
1393 0和1相等串 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等. I ...
- mongodb mapreduce使用总结
文章来自本人个人博客: mongodb mapreduce使用总结 大家都知道,mongodb是一个非关系型数据库.也就是说.mongodb数据库中的每张表是独立存在的,表与表之间没有不论什么依赖 ...
- 应用程序 /dev/rtc 编程 获取时间 2011-12-13 01:01:06【转】
本文转载自:http://blog.chinaunix.net/uid-16785183-id-3040310.html 分类: 原文地址:应用程序 /dev/rtc 编程 获取时间 作者:yuwei ...
- B1208 [HNOI2004]宠物收养所 平衡树||set (滑稽)
这个题是一道splay裸题,但是我不太会写,所以用set直接水过去!!!哈哈哈哈,美滋滋. set总结: set是一个集合,然后里面没用重复的元素.里面有一些函数: begin() ,返回se ...
- 多线程编程和Java网络编程
1. 线程概述 多任务处理有两种类型:基于进程.基于线程(进程是指一种“自包容”的运行程序,有自己的地址空间; 线程是进程内部单一的一个顺序控制流) 基于进程的特点是允许计算机同时运行两个或更多的程序 ...
- C++ this指针 全部
在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的.叫做this.它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起 始地址.例如:当调用成员函数a.volume ...
- hihoCoder 1033
题目链接: http://hihocoder.com/problemset/problem/1033 听说这个题是xiaodao出的~~ 我们要知道dp其实就是一个记忆化搜索的过程,如果某个子结构之前 ...
- Django day01 web应用程序 , http协议
一:web应用程序1.什么是web应用程序 是一种可以通过web访问的应用程序,最大的好处就是, 只要有浏览器,用户就能很容易访问到应用程序 2. web应用程序的优缺点 缺点: 应用程序强调了浏览器 ...