7 SQL 集合运算
7 集合运算
7-1 表的加减法
本章将会和大家一起学习“集合运算”操作。在数学领域,“集合”表示“(各种各样的)事物的总和”;在数据库领域,表示“记录的集合”。具体来说,表、视图和查询的执行结果都是“记录的集合”。
所谓集合运算,就是对满足同一规则的记录进行的加减等“四则运算”。通过集合运算,可以得到两张表中记录的集合,或者是公共记录的集合,又或者是其中某张表记录的集合。像这样用来进行集合运算的运算符称为“集合运算符”。
UNION等集合运算符通常都会除去重复的记录。
|
表的加法-UNION |
|
CREATE TABLE `shohin2` ( `shohin_id` char(4) NOT NULL, `shohin_mei` varchar(100) NOT NULL, `shohin_bunrui` varchar(32) NOT NULL, `hanbai_tanka` int(11) DEFAULT NULL, `shiire_tanka` int(11) DEFAULT NULL, `torokubi` date DEFAULT NULL, PRIMARY KEY (`shohin_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; START TRANSACTION; INSERT INTO shohin2 VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20'); INSERT INTO shohin2 VALUES ('0002', '打孔器', '办公用品', 500, 300, '2009-09-11'); INSERT INTO shohin2 VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL); INSERT INTO shohin2 VALUES ('0009', '手套', '衣服', 800, 500, NULL); INSERT INTO shohin2 VALUES ('0010', '水壶', '厨房用具', 2000, 1700, '2009-09-20'); COMMIT; SELECT shohin_id, shohin_mei FROM shohin UNION SELECT shohin_id, shohin_mei FROM shohin2; -- 错误例子 SELECT shohin_id, shohin_mei FROM shohin UNION SELECT shohin_id, shohin_mei, hanbai_tanka FROM shohin2; SELECT shohin_id, hanbai_tanka FROM shohin UNION SELECT shohin_id, torokubi FROM shohin2; SELECT shohin_id, shohin_mei FROM shohin WHERE shohin_bunrui = '厨房用具' UNION SELECT shohin_id, shohin_mei FROM shohin2 WHERE shohin_bunrui = '厨房用具' ORDER BY shohin_id; SELECT shohin_id, shohin_mei FROM shohin UNION ALL SELECT shohin_id, shohin_mei FROM shohin2; |
|
法则7-1 |
|
集合运算符会除去重复的记录。 |
只需要在UNION后面添加ALL关键字就可以保留重复行。
|
包含重复行的集合运算-ALL选项 |
|
SELECT shohin_id, shohin_mei,FROM shohin UNION ALL SELECT shohin_id,shohin_mei FROM shohin2; |
|
法则7-2 |
|
在集合运算中使用ALL选项,可以保留重复行。 |
与使用AND可以选取一张表中满足多个条件的公共部分不同,INTERSECT应用于两张表,选取出它们当中的公共记录。
希望保留重复行时同样需要使用INTERESECT ALL。
|
选取表中公共部分-INTERSECT |
|
-- oracle sql SERVER db2 postgresql 目前mysql不支持 SELECT shohin_id, shohin_mei FROM shohin INTERSECT SELECT shohin_id, shohin_mei FROM shohin2; |
集合运算符:减法运算的EXCEPT(差集)。
EXCEPT有一点与UNION和INTERSECT不同,需要注意一下。那就是在减法运算中减数和被减数的位置不同,所得到的结果也不相同。
|
记录的减法-EXCEPT |
|
-- sql server db2 postgresql 目前mysql还不支持,Oracle有特定写法 SELECT shohin_id, shohin_mei FROM shohin EXCEPT SELECT shohin_id, shohin_mei FROM shohin2; -- oracle SELECT shohin_id, shohin_mei FROM shohin MINUS SELECT shohin_id, shohin_mei FROM shohin2; -- sql server db2 postgresql 目前mysql还不支持,Oracle有特定写法 表的位置不同得到的结果也不同 SELECT shohin_id, shohin_mei FROM shohin2 EXCEPT SELECT shohin_id, shohin_mei FROM shohin; |
集合运算的注意事项:
第一, 作为运算对象的记录的列数必须相同;
第二, 作为运算对象的记录中列的类型必须一致;
第三, 可以使用任何SELECT语句,但ORDER BY子句只能在最后使用一次。
7-2 联结(以列为单位对表进行联结)
前一节我们学习了UNION和INTERSECT等集合运算。这些集合运算的特征就是以行方向为单位进行操作。通俗来说,就是进行这些集合运算时,会导致记录行的增减。使用UNION会增加记录行数,而使用INTERSECT或者EXCEPT会减少记录行数。
本节将要学习的联结(JOIN)运算,简单来说,就是将其他表中的列添加过来,进行“添加列”的运算。
所谓联结运算,一言以弊之,就是“以A中的列作为桥梁,将B中满足同样条件的列汇集到同一结果之中”。
使用关键字INNER JOIN就可以将两张表联结在一起了。我们可以在ON之后指定两张表联结所使用的列(联结键)。也就是说ON就是专门用来指定联结条件的,它能起到与WHERE相同的作用。需要指定多个键时,同样可以使用AND、OR。ON子句在进行内联结时是必不可少的。并且ON必须书写在FROM和WHERE之间。
|
内联结-INNER JOIN |
|
-- sql server db2 postgresql mysql 不区分from 后面表的顺序 SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin AS TS INNER JOIN shohin AS S ON TS.shohin_id = S.shohin_id; SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM shohin AS S INNER JOIN tenpoShohin AS TS ON TS.shohin_id = S.shohin_id; -- oracle SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin TS INNER JOIN shohin S ON TS.shohin_id = S.shohin_id; -- sql server db2 postgresql mysql SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin AS TS INNER JOIN shohin AS S ON TS.shohin_id = S.shohin_id WHERE TS.tenpo_id = '000A'; -- oracle SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin TS INNER JOIN shohin S ON TS.shohin_id = S.shohin_id WHERE TS.tenpo_id = '000A'; |
|
法则7-3 |
|
进行联结时需要在FROM子句中使用多张表。 |
|
法则7-4 |
|
进行内联结时必须使用ON子句,并且要书写在FROM和WHERE之间。 |
|
法则7-5 |
|
使用联结时SELECT子句中的列需要按照<表的别名>.<列名>的格式进行书写。 |
外联结还有一点非常重要,那就是要把哪张表作为主表。最终的结果中会包含主表内所有的数据。指定主表的关键字是LEFT和RIGHT。通常,使用LEFT的情况会多一些,但并没有非使用这个不可的理由,使用RIGHT也没有问题。
|
外联结-OUTER JOIN |
|
-- sql server db2 postgresql mysql SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin AS TS RIGHT OUTER JOIN shohin AS S ON TS.shohin_id = S.shohin_id; SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin AS TS LEFT OUTER JOIN shohin AS S ON TS.shohin_id = S.shohin_id; -- oracle SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin TS RIGHT OUTER JOIN shohin S ON TS.shohin_id = S.shohin_id; SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka FROM tenpoShohin TS LEFT OUTER JOIN shohin S ON TS.shohin_id = S.shohin_id; |
|
法则7-6 |
|
外联结中使用LEFT、RIGHT来指定主表。使用二者所得到的结果完全相同。 |
|
3张表以上的联结 |
|
-- DDL :创建表 CREATE TABLE zaikoShohin ( souko_id CHAR(4) NOT NULL, shohin_id CHAR(4) NOT NULL, zaiko_suryo INTEGER NOT NULL, PRIMARY KEY (souko_id, shohin_id) ); -- DML :插入语句 START TRANSACTION; INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0001', 0); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0002', 120); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0003', 200); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0004', 3); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0005', 0); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0006', 99); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0007', 999); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S001', '0008', 200); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0001', 10); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0002', 25); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0003', 34); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0004', 19); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0005', 99); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0006', 0); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0007', 0); INSERT INTO zaikoShohin (souko_id, shohin_id, zaiko_suryo) VALUES ('S002', '0008', 18); COMMIT; -- sql server db2 postgresql mysql SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka, ZS.zaiko_suryo FROM tenposhohin AS TS INNER JOIN shohin AS S ON TS.shohin_id = S.shohin_id INNER JOIN zaikoShohin AS ZS ON TS.shohin_id = ZS.shohin_id WHERE ZS.souko_id = 'S001'; -- sql server db2 postgresql mysql SELECT TS.tenpo_id, TS.ten_mei, TS.shohin_id, S.shohin_mei FROM tenpoShohin AS TS CROSS JOIN shohin AS S; |
|
法则7-7 |
|
那些过时和特定的联结书写方式,虽然我们自己不会使用,但还是希望大家能够读懂。 |
7 SQL 集合运算的更多相关文章
- 详解SQL集合运算
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...
- SQL集合运算参考及案例(一):列值分组累计求和
概述 目前企业应用系统使用的大多数据库都是关系型数据库,关系数据库依赖的理论就是针对集合运算的关系代数.关系代数是一种抽象的查询语言,是关系数据操纵语言的一种传统表达方式.不过我们在工作中发现,很多人 ...
- SQL集合运算 差集 并集 交
SQL-3标准中提供了三种对检索结果进行集合运算的命令:并集UNION:交集INTERSECT:差集EXCEPT(在Oracle中叫做 MINUS).在有些数据库中对此的支持不够充分,如MySql中只 ...
- sql 集合运算
UNION 并运算 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每条 SE ...
- SQL集合运算参考及案例(二):树形节点数量逐级累计汇总
问题描述: 我们经常遇到这样一个问题,类似于面对一个树形结构的物料数据,需要将库存中每一种物料数量汇总到物料上展示出来:或者说组织机构是一棵树,我们需要统计每一个节点上的人员数量(含下级节点的累计数量 ...
- SQL集合运算:差集、交集、并集
1.差集( except ) select a from t_a except select a from t_b -- 也可写作: select a from t_a where a not in ...
- SQL集合运算
注:UserInfo一共29条记录 select * from UserInfo union --并集(29条记录)(相同的只出现一次) select * from UserInfo select * ...
- [SQL] SQL 基础知识梳理(七)- 集合运算
SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...
- SQL Server进阶(七)集合运算
概述 为什么使用集合运算: 在集合运算中比联接查询和EXISTS/NOT EXISTS更方便. 并集运算(UNION) 并集:两个集合的并集是一个包含集合A和B中所有元素的集合. 在T-SQL中.UN ...
随机推荐
- <TLE>奇偶剪枝hdoj1010
(奇偶剪枝)转自百度百科,讲的非常棒: http://baike.baidu.com/link?url=3g5bW7LszRVOVvFDFp6cL0ZZnAaOLUdpaNjc2leHoxkKU9Eh ...
- kettle系列-我的开源kettle调度、管理平台[kettle-manager]介绍
kettle管理工具 专门为kettle这款优秀的ETL工具开发的web端调度.管理工具. 新版本 项目简介 kettle作为非常优秀的开源ETL工具得到了非常广泛的使用,一般的使用的都是使用客户端操 ...
- thinkphp5升级版开源框架tpframe v2.1发布
免费开源框架tpframe是一款以thinkphp5为驱动,在此基础上进行进一步的完善与改进的框架,保持了ThinkPHP5原有的所有特性,优化核心,减少依赖,为个人或企业建站提供高效.快速解决的方案 ...
- php in_array 的 坑
话不多说,直接上代码 $str = '7.php'; var_dump(in_array($str,range(0,100))); die; 是 true 这是因为 php是弱类型语言,会把7.php ...
- SpringBoot | 读取配置文件信息
server.port=8081 #修改端口号 server.servlet.context-path= /SpringBoot #修改URL #自定义配置 tz.name = xiaoming tz ...
- scikit-learning教程(三)使用文本数据
使用文本数据 本指南的目标是探讨scikit-learn 一个实际任务中的一些主要工具:分析二十个不同主题的文本文档(新闻组帖子)集合. 在本节中,我们将看到如何: 加载文件内容和类别 提取适用于机器 ...
- Codeforces Round #324 (Div. 2)
CF的rating设置改了..人太多了,决定开小号打,果然是明智的选择! 水 A - Olesya and Rodion #include <bits/stdc++.h> using na ...
- iphone 开发Categories 、Extensions 区别 --转
Category和Extension这两个概念,即便对于Java程序员,可能也会感到陌生.这是Objective C为程序员提供的两个强大的动态机制——简单地说,它们允许程序员为已有的对象添加新的方法 ...
- T4308 数据结构判断
https://www.luogu.org/record/show?rid=2143639 题目描述 在世界的东边,有三瓶雪碧. ——laekov 黎大爷为了虐 zhx,给 zhx 出了这样一道题.黎 ...
- Vue 2.0入门基础知识之内部指令
1.Vue.js介绍 当前前端三大主流框架:Angular.React.Vue.React前段时间由于许可证风波,使得Vue的热度蹭蹭地上升.另外,Vue友好的API文档更是一大特色.Vue.js是一 ...