一、子查询

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. win add static arp

    win add static arp > arp -s "192.168.0.2" "00-0a-35-01-fe-c0" > arp -a | f ...

  2. (转) Python3—UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1

    (转)python(三):Python3-UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1 python ...

  3. vue插件(还真是第一次接触)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 【转载】C#中List集合使用Contains方法判断是否包含某个对象

    在C#的List集合中,如果要查找List集合是否包含某一个值或者对象,如果不使用List集合类的扩展方法的话一般会使用for循环或者foreach遍历来查找,其实List集合类中的扩展方法Conta ...

  5. gitlab中clone项目时,IP地址是一串数字

    问题:docker安装后,clone显示ip是一串地址 解决(如果是非docker启动的,自然就是进入gitlab下): 1.进入docker 后台: docker exec -it gitlab / ...

  6. Python学习日记(三十四) Mysql数据库篇 二

    外键(Foreign Key) 如果今天有一张表上面有很多职务的信息 我们可以通过使用外键的方式去将两张表产生关联 这样的好处能够节省空间,比方说你今天的职务名称很长,在一张表中就要重复的去写这个职务 ...

  7. Set,List,Map,Collection

    // JAVA集合主要分为三种类型: // // Set(集) List(列表) Map(映射) Collection 接口 // // Collection是最基本的集合接口,声明了适用于JAVA集 ...

  8. 蓝桥杯-基础练习 :java 数列排序问题

    问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000. 输 ...

  9. vsftpd配置文件

    一.默认配置 1. 允许匿名用户和本地用户登录 anonymous_enable=YES local_enable=YES 2. 匿名用户使用的登录名为ftp或anonymous,密码为空:匿名用户不 ...

  10. HTML&CSS基础-html标签的实体

    HTML&CSS基础-html标签的实体 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTML源代码 <!DOCTYPE html> <html&g ...