M6: 复合查询、子查询、正则表达式

6.10 复合查询与子查询
6.10.1 复合查询

定义: 所谓复合查询,就是联表查询时,where多写几个条件。

例子:

select * from student as s,
sbuject as sub
where s.subject_id=sub.id and s.sex='男';

上述语句可以查询出所有的男学生的个人信息,以及专业信息。
6.10.2 子查询

定义: 所谓子查询,就是嵌套多个select,但它本身并不叫嵌套子查询,把一个select的查询结果,作为另一个select的查询条件的范围。

带in关键字的子查询:

语法:

selece * from 表名 where 字段 in 集合;

例子:
select * from student
where subject_id in
(select id from subject);

上面语句也等同于:
select * from student as s
inner join subject as sub
on s.subject_id=sub.id;

注意: 虽然in也可以实现连接的功能,但是,连接效率更高。


带比较运算符的子查询:

语法:

select * from 表名 where 字段 比较运算符 值;

例子:
select * from student
where subject_id=(select id from where `name`='财务管理');

带exists关键字的查询:

定义:使用exists关键字,内层查询不返回结果集,而返回布尔值。子查询语句查询到满足条件的记录,则返回true,此时外层查询将会进行;如果内层子句为查询到满足条件的记录,则返回false。外层查询则不进行。

语法:

select * from 表名 where exists 布尔值;

在实际使用过程中,发现了一些问题

假设有如下,两张表:

表1:student表

namesubject
张三1
李四3
王五2

表2:subject表

idsub_name
1软件工程
2通信工程

执行语句1

select * from student where exists (select * from `subject` where id =1);

返回值:

namesubject
张三1
李四3
王五2

执行语句2

select * from student as s where exists (select * from `subject` as sub where s.`subject`=sub.id);

返回结果:

namesubject
张三1
王五2

分析:

​ 根据exists关键字的定义来说,只要子查询为真,那么外层循环一定会返回所有值,那么两个执行结果,都应该是语句1的结果。但是,从执行结果看来,语句1语句2执行结果并不一样。这里要引入一个知识点,叫做相关子查询与非相关子查询。

定义:非相关子查询就是指,子查询可以自己独立运行,不依赖外层查询,也叫做嵌套子查询。而相关子查询则是需要依赖外层查询。

相关子查询执行步骤:

​ 1.从外层查询的表里,得到第一条记录。

​ 2.将第一条记录放入子查询内,辅助子查询进行。

​ 3.子查询完毕,返回外层查询中,并与where进行判断,满足曾保留,反之排除。

​ 4.从外层查询的表里,得到第二条记录,重复以上过程。

由此可见,上述语句2是相关子查询,所以才会少了一条数据,并且相关子查询并不局限于exists关键字。


带ANY关键字的子查询:

定义: 表示满足内层返回结果的其中一个条件即可,通常与比较运算符联合使用。

例子:现有两张成绩表class3class2,请查询出3班中成绩比2班最低分高的所有学生。

select * from class3 where score >any(select * from class2);

带all关键字的子查询

定义: 表示满足内层返回结果的所有值,通常与比较运算符联合使用。

例子:现有两张成绩表class3class2,请查询出3班中成绩比2班最高分高的所有学生。

select * from class3 where score > all(select score from class2);
6.11 合并查询
6.11.1 简介

​ 所谓合并查询,实则是将几个select的结果集,合并在一起。有两个关键字:Union、Union all,二者的区别在于前者会去掉重复记录,但是后者不会。

6.11.2 语法

Union的使用

select * from 表名
Union
select * from 表名
Union
...


例子:
select * from grade
Union
select * from subject;
此语句可以查询出所有的专业以及年级信息。

Union all的使用:

​ 与Union语法完全一致。

注意: Union与Union all在合并结果集时,多个结果集的列数要一致,否则sql语句将会执行失败。

6.12 正则表达式
6.12.1 语法
select * from 表名 where 字段 regexp '正则表达式';
6.12.2 正则表达式的模式字符
字符含义语句备注
^匹配以特定字符/字符串开头的记录select * from student where name regexp ‘^张’张三、张天佑、张
$匹配以特定字符/字符串结尾的记录select * from student where name regexp ‘西$’陈冠西、刘山西、密西西
.匹配任意单个字符,包括换行与回车select * from student where name regexp ‘a.c’abc、adc、aac
[]匹配集合中的任意一个字符select * from student where name REGEXP ‘[123]’1111,2bghm3,3dsfd
[^]匹配除集合之中的任意一个字符select * from student where name REGEXP ‘[^李四南]’除李四南意外的所有人
s1|s2|s3匹配其中任意一个字符select * from student where name REGEXP ‘李|王’李四南、王伟、刘李浩
*匹配多个字符之前的字符,保包括0与1select * from student where name REGEXP ‘四*南’李四南、王张四南懿
+匹配多个字符之前的字符,保包括1select * from student where name REGEXP ‘四+南’李四南、王张四南懿
{n}匹配字符串连续出现至少N次select * from student where pwd REGEXP ‘1{2}’211,1112
{n,m}匹配字符串连续出现[n,m]次select * from student where pwd REGEXP ‘1{3,6}’21111、311111

注意:

​ 1)“.”对中文的支持很不好, “a.c” 可以查出abcagc,但是**“刘.轩”却查不出 “刘子轩” ,不过“刘.”可以查出刘子轩刘浩**。

​ 2)“[]” 对中文支持更不友好,检索失败。

以上原因未知,数据库版本5.7。

6.12.3 验证邮箱非法
select * from user
where email not regexp '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'

注意: 这是某资料上的写法,但是,这个写法有待改进。


2021.07.25

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值