SQL基础-子查询&EXISTS&UNION
一、子查询
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的更多相关文章
- SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句
SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...
- C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法
C#构造方法(函数) 一.概括 1.通常创建一个对象的方法如图: 通过 Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...
- MySQL 子查询 EXISTS 和 NOT EXISTS(转)
MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...
- SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]
--====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...
- SQL Fundamentals: 子查询 || 分析函数(PARTITION BY,ORDER BY, WINDOWING)
SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...
- SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)
SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...
- SQL的子查询操作
对于表中的每一个记录,我们有时候需要提取特殊的或者你需要的记录,要提前做一个表的筛选,之后再对你选出的记录做一个修改,此时你必须使用SQL的子查询操作.如:修改id=5的记录的strContent字段 ...
- SQL关联子查询
SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...
- SQL 子查询 EXISTS 和 NOT EXISTS
MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT … FROM table WHERE EXISTS (subquery) 该语法可以理解为:将主查询的数据,放到子查 ...
随机推荐
- Maven的仓库和settings.xml配置文件
(尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/83549846冷血之心的博客) 快速导航: Maven基础概念和安 ...
- .Net MVC如何渲染带有网页标签的字符串
有时候我们在解析一段文字时,可能文字中会包含网页上的标签,如div.p等等.那么如果将这种文字渲染成对应的标签效果呢?如图,最近博主就拿到了这么一段字符串(如图) 由于中间带有很多特殊字符,用Html ...
- 一个牛逼的 Python 调试工具PySnooper
原文转自:https://mp.weixin.qq.com/s/OtLr-cNethboMgmCcUx2pA PySnooper 使用起来十分简单,开发者可以在任何庞大的代码库中使用它,而无需进行任何 ...
- 解决vue-cli项目开发中跨域问题
一.开发环境中跨域 使用 Vue-cli 创建的项目,开发地址是 localhost:8080,需要访问非本机上的接口http://10.1.0.34:8000/queryRole.不同域名之间的访问 ...
- swiper-动态更改数据后轮播点击或拖动失效
出现的问题: 1.swiper不能自动切换(设置了autoplay). 2.数据不匹配(需要加载的数据以改变,但是swiper里面的数据出现错误). 3.数据匹配过后,永远切换不到第一条数据. 4.根 ...
- Linq Left Join;linq左连接 (转载)
来源 https://www.cnblogs.com/xinjian/archive/2010/11/17/1879959.html 准备一些测试数据,如下: use Test Create tabl ...
- 基于GDI显示png图像
intro 先前基于GDI已经能够显示BITMAP图像:windows下控制台程序实现窗口显示 ,其中BMP图像是使用LoadImage()这一Win32 API函数来做的.考虑到LoadImage( ...
- linux中container_of
linux 驱动程序中 container_of宏解析 众所周知,linux内核的主要开发语言是C,但是现在内核的框架使用了非常多的面向对象的思想,这就面临了一个用C语言来实现面向对象编程的问题,今天 ...
- 【笔记】Reptile-一阶元学习算法
目录 论文信息 Nichol A , Achiam J , Schulman J . On First-Order Meta-Learning Algorithms[J]. 2018. 一.摘要 本文 ...
- Cloudera Manager 5.15.1忘记密码怎么破?
Cloudera Manager 5.15.1忘记密码怎么破? 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.登陆CM修改默认密码 1>.使用默认密码登陆CM界面 2&g ...