一、子查询

1、使用子查询作为计算字段

子查询:嵌套在其他查询中的查询

现在有两个表,student表和teacher表

创建teacher表,并插入数据:
CREATE TABLE `teacher` (
`teacher_id` varchar(255) DEFAULT NULL COMMENT '老师编号',
`teacher_name` varchar(255) DEFAULT NULL COMMENT '老师姓名',
`gender` varchar(255) DEFAULT NULL COMMENT '性别'
) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT='老师'; INSERT INTO `teacher` VALUES
('T0001','高齐妍','男'),('T0002','李红','女'),
('T0003','李一萱',NULL),('T0004','刘金霞','男'),('T0005','刘思哲','男'),
('T0006','刘兆祥','男'),('T0007','刘哲宇','男'),('T0008','梅艺涵','女'),
('T0009','梅姿君','女'),('T0010','牛雨','女'),('T0011','牛光滢','女'),
('T0012','黄雅','女'),('T0013','任筱','女'),('T0014','吴静婷','男'),
('T0015','习芸颍','女'),('T0016','叶惠燕','女'),('T0017','周纯','男'),
('T0018','周圣杰','男'),('T0019','方焓','女'),('T0020','方杰萍','女'); 比如:
如何同时查询出学生编号、学生姓名、老师编号、老师姓名?
SELECT
student_id,
student_name,
teacher_id,
(
SELECT teacher_name
FROM teacher
-- 使用表名消除字段歧义
WHERE teacher.teacher_id = student.teacher_id
)
FROM student; #可以为表指定别名
SELECT
student_id,
student_name,
teacher_id,
(
SELECT teacher_name
FROM teacher b
WHERE b.teacher_id = a.teacher_id
)
FROM student a; 此时子查询不能返回多条记录;

2、使用子查询过滤数据(IN)

比如:
如何获取姓牛的老师教了哪些学生?
SELECT
student_id,student_name
FROM student
WHERE teacher_id IN ( SELECT teacher_id FROM teacher
WHERE teacher_name like '牛%'); in 后面是一个集合;

3、IN和EXISTS比较

exists 与 in 最大的区别在于 in引导的子句只能返回一个字段;

exists强调的是是否返回结果集,不要求知道返回什么;

exists 是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真否则返回假。not exists则相反。

EXISTS只返回TRUE或FALSE,不会返回UNKNOWN。

IN当遇到包含NULL的情况,那么就会返回UNKNOWN。

exists做为where条件时,是先对where前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,
如果为真则输出当前这一条主查询的结果,否则不输出。 select * from A where id in(select id from B) in()适合B表比A表数据小的情况; exists()适合B表比A表数据大的情况; 当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用;

4、使用子查询过滤数据(EXISTS)

比如:
如何获取姓牛的老师教了哪些学生? SELECT
student_id,student_name
FROM student a
-- 这里的select 1没有具体意义,写成select 2也可以;
WHERE EXISTS ( SELECT 1 FROM teacher b
WHERE a.teacher_id = b.teacher_id
AND b.teacher_name like '牛%'
); ##NO EXISTS 比如:
如何获取除姓牛的老师之外的其他老师教了哪些学生?
SELECT
student_id,student_name
FROM student a
WHERE NOT EXISTS ( SELECT 1 FROM teacher b
WHERE a.teacher_id = b.teacher_id
AND b.teacher_name like '牛%'
);

二、UNION

1、UNION 和UNION ALL

##
比如:
如何同时查询出年龄为10岁或一年级一班的所有学生? SELECT * FROM student WHERE age = 10
UNION ALL
SELECT * FROM student WHERE class_id = 'G0101'; 比如:
如何同时查询出年龄为10岁或一年级一班的所有学生(去除重复)? SELECT * FROM student WHERE age = 10
UNION
SELECT * FROM student WHERE class_id = 'G0101'; UNION ALL 与 UNION:
相同点:都是用来合并多个结果集; 不同点:UNION ALL合并结果集后不去除重复记录;
UNION合并结果集后去除重复记录;

2、合并2个以上的结果集

比如:
如何同时查询出年龄为10岁或一年级一班或性别为男的所有学生? SELECT * FROM student WHERE age = 10
UNION
SELECT * FROM student WHERE class_id = 'G0101'
UNION
SELECT * FROM student WHERE gender = '男';

3、合并来源于不同的表的结果集

比如:
如何同时查询出所有的学生编号、学生姓名和老师编号、老师姓名? SELECT student_id,student_name FROM student
UNION
SELECT teacher_id,teacher_name FROM teacher;

4、不同结果集什么情况下可以合并

需要注意:
 待合并的结果集的字段数量必须一致。 错误写法(字段数量不一致):
SELECT student_id,student_name,age FROM student
UNION
SELECT teacher_id,teacher_name FROM teacher; 其他注意的几点:
 合并后的结果集的title与第一个结果集保持一致。
 待合并的结果集的字段顺序、字段类型的大类及字段值的含义尽量保持一致。 如下,虽然不会报错,但是也应该尽量避免不一样的字段在同一列:
SELECT student_id,student_name,age FROM student
UNION
SELECT teacher_id,teacher_name,gender FROM teacher; 以上注意事项,UNION和UNION ALL都适用;

5、UNION ALL与UNION混用

比如:
如何同时查询出年龄为10岁或一年级一班(前面两个结果集需要去除重复)或性别为男(合并时不去除重复)的所有学生? SELECT * FROM student WHERE age = 10
UNION
SELECT * FROM student WHERE class_id = 'G0101'
UNION ALL
SELECT * FROM student WHERE gender = '男'; 需要注意的几点:
 UNION ALL与UNION的执行优先级一致,谁在前谁先执行;
 不可以使用括号改变执行优先级; 不建议UNION ALL与UNION混用;

6、合并后的结果集排序

比如:
如何同时查询出年龄为10岁或一年级一班的所有学生(按姓名升序排序)? SELECT * FROM student WHERE age = 10
UNION ALL
SELECT * FROM student WHERE class_id = 'G0101'
ORDER BY student_name; 会先执行UNION ALL,再执行ORDER BY

7、union all&or&in的使用

union all 也不一定就比 or及in 快,要结合实际情况分析到底使用哪种情况。

对于索引列来最好使用union all,因复杂的查询【包含运算等】将使or、in放弃索引而全表扫描,除非你能确定or、in会使用索引;

对于只有非索引字段来说你就老老实实的用or 或者in,因为 非索引字段本来要全表扫描而union all 只成倍增加表扫描的次数;

对于既有索引字段【索引字段有效】又包含非索引字段来时,按理你也使用or 、in或者union all 都可以,但是我推荐使用or、in。

以上主要针对的是单表,而多表联合查询来说,考虑的地方就比较多了,比如连接方式,查询表数据量分布、索引等,再结合单表的策略选择合适的关键字;

SQL基础-子查询&EXISTS&UNION的更多相关文章

  1. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  2. C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法

    C#构造方法(函数)   一.概括 1.通常创建一个对象的方法如图: 通过  Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...

  3. MySQL 子查询 EXISTS 和 NOT EXISTS(转)

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  4. SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]

    --====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...

  5. SQL Fundamentals: 子查询 || 分析函数(PARTITION BY,ORDER BY, WINDOWING)

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  6. SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  7. SQL的子查询操作

    对于表中的每一个记录,我们有时候需要提取特殊的或者你需要的记录,要提前做一个表的筛选,之后再对你选出的记录做一个修改,此时你必须使用SQL的子查询操作.如:修改id=5的记录的strContent字段 ...

  8. SQL关联子查询

    SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...

  9. SQL 子查询 EXISTS 和 NOT EXISTS

    MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT … FROM table WHERE EXISTS (subquery) 该语法可以理解为:将主查询的数据,放到子查 ...

随机推荐

  1. RSA非对称 私钥加密

    RSA生成公钥和私钥对 /// <summary> /// RSA生成公钥和私钥 /// </summary> /// <returns></returns& ...

  2. C# vb .net图像合成-合成文字

    在.net中,如何简单快捷地实现图像合成呢,比如合成文字,合成艺术字,多张图片叠加合成等等?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码 ...

  3. Python的字符串函数

    今天用了将近一天的时间去学习Python字符串函数 上午学了17个,下午学了23个(共计40) 详细内容请见菜鸟教程--Python3字符串--Python的字符串内建函数

  4. python基础知识(二)

    python基础知识(二) 字符串格式化 ​ 格式: % 类型 ---- > ' %类型 ' %(数据) %s 字符串 ​ print(' %s is boy'%('tom')) ----> ...

  5. Assignment 2: UDP Pinger[课后作业]

    Computer Networking : A Top-Down Approach 的课后作业. 要求: 基于UDP协议,实现一个Pinger工具. 服务端代码已经提供了,自己实现客户端的代码. 完整 ...

  6. 正则表达式修饰符 i、g、m、s、U、x、a、D、e 等。

    正则表达式中常用的模式修正符有i.g.m.s.U.x.a.D.e 等. 它们之间可以组合搭配使用. i 不区分(ignore)大小写: 例如: /abc/i 可以匹配 abc.aBC.Abc g 全局 ...

  7. 基于webpack的前端工程化开发解决方案探索(三):webpack-dev-server

    前两篇中我们使用webpack完成了静态资源(css/js/img)等自动写入HTML模板中,同时还可以为静态资源添加hash版本号,既满足了我们对于静态资源的打包要求,同时又无需开发人员介入打包过程 ...

  8. kubeadm部署高可用K8S集群(v1.14.2)

    1. 简介 测试环境Kubernetes 1.14.2版本高可用搭建文档,搭建方式为kubeadm 2. 服务器版本和架构信息 系统版本:CentOS Linux release 7.6.1810 ( ...

  9. JavaScript: 详解正则表达式之三

    在上两篇文章中博主介绍了JavaScript中的正则常用方法和正则修饰符,今天准备聊一聊元字符和高级匹配的相关内容. 首先说说元字符,想必大家也都比较熟悉了,JS中的元字符有以下几种: / \ | . ...

  10. select下拉框小DemoA

    <html> <head> <meta charset="utf-8"> <script src="jquery-1.9.1.m ...