Mysql多表联合查询、连接查询、子查询

前言:理论知识参考https://blog.csdn.net/weixin_39411321/article/details/90602030感谢前辈。

一、连接查询

在用户查看数据的时候,需要显示的数据来自多张表.

1.1内连接查询

内连接查询是最常见的连接查询,内连接查询可以查询两张或两张以上的表

内连接:[inner] join:从左表中取出每一条记录,去右表中与所有的记录进行匹配: 匹配必须是某个条件在左表中与右表中相同最终才会保留结果,否则不保留.

基本语法:左表 [inner] join 右表 on 左表.字段 = 右表.字段;

on表示连接条件: 条件字段就是代表相同的业务含义(如my_student.c_id和my_class.id)

当两个表中存在相同意义的字段的时候,就可以通过该字段来连接查询这两个表,当该字段的值相同时就可以查出该记录。

内连接可以没有连接条件: 没有on之后的内容,这个时候系统会保留所有结果。

SELECT a.userId,a.`password`,b.userName,b.phone
from users a
join student b
on a.userId=b.userId

在这里插入图片描述

1.2外连接查询

以某张表为主,取出里面的所有记录, 然后每条与另外一张表进行连接: 不管能不能匹配上条件,最终都会保留: 能匹配,正确保留; 不能匹配,其他表的字段都置空NULL。

左连接

left join: 左外连接(左连接), 以左表为主表

基本语法: from 左表 left join 右表 on 左表.字段 = 右表.字段;

.左表不管能不能匹配上条件,最终都会保留:能匹配,正确的保留; 若不能匹配,右表的字段都置NULL。

SELECT a.userId,a.`password`,b.userName,b.phone
from users a LEFT JOIN student b
on a.userId=b.userId

在这里插入图片描述
右连接

right join: 右外连接(右连接), 以右表为主表

基本语法: from 左表 right join 右表 on 左表.字段 = 右表.字段;

.右表不管能不能匹配上条件,最终都会保留:能匹配,正确的保留; 若不能匹配,左表的字段都置NULL。

SELECT a.userId,a.`password`,b.userName,b.phone
from users a RIGHT JOIN student b
on a.userId=b.userId

在这里插入图片描述

二、联合查询

联合查询

联合查询结果是将多个select语句的查询结果合并到一块因为在某种情况下需要将几个select语句查询的结果合并起来显示。比如现在需要查询两个公司的所有员工的信息,这就需要从甲公司查询所有员工信息,再从乙公司查询所有的员工信息,然后将两次的查询结果进行合并。
可以使用union和union all关键字进行操作

语法格式如下:

select 语句1
union[all|distinct]
select 语句2
union[all|distinct]
select 语句n

其中union选项有两个选项可选

.all:表示无论重复都输出

.distinct: 去重(整个重复)(默认的)

SELECT * FROM union_1
UNION
SELECT * FROM union_2

在这里插入图片描述

SELECT * FROM union_1
UNION ALL
SELECT * FROM union_2

在这里插入图片描述
联合查询只要求字段一样, 跟数据类型和顺序无关
.表头的顺序和第一个查询条件的列名顺序一样

SELECT id,`name`,phone,sex FROM union_1
UNION ALL
SELECT `name`,phone,sex,id FROM union_2

在这里插入图片描述
联合查询的意义:

1.查询同一张表,但是需求不同 如查询学生信息, 男生身高升序, 女生身高降序
2.多表查询: 多张表的结构是完全一样的,保存的数据(结构)也是一样的.

.联合查询order by的使用:
.在联合查询中: order by不能直接使用(不能出现两次),需要对查询语句使用括号才行;

SELECT * FROM union_1
WHERE sex="男"
ORDER BY score
UNION
SELECT * FROM union_2
WHERE sex="男"
ORDER BY score

这种情况是会报错的。因为语句中不允许出现两个order by。
在这里插入图片描述

SELECT * FROM union_1
WHERE sex="男"
UNION
SELECT * FROM union_2
WHERE sex="男"
ORDER BY score

如果是上边这样只出现一次他的意义就是等合并完成之后再进行排序就没有任何意义了

SELECT * FROM 
(SELECT * FROM union_1
WHERE sex="男"
ORDER BY score
)union_1
UNION
SELECT * FROM 
(SELECT * FROM union_2
WHERE sex="男"
ORDER BY score
)union_2

在这里插入图片描述
.order by不能直接出现在union的子句中,但是可以出现在子句的子句中。

三、子查询

通常我们在查询的SQL中嵌套查询,称为子查询。子查询通常会使复杂的查询变得简单,但是相关的子查询要对基础表的每一条数据都进行子查询的动作,所以当表单中数据过大时,一定要慎重选择

3.1 带in关键字的子查询

使用in关键字可以将原表中特定列的值与子查询返回的结果集中的值进行比较
如果某行的特定列的值存在,则在select语句的查询结果中就包含这一行。

例:查询身高大于170的学生的所有信息,
先在子查询中查出成绩大与170的结果集,然后将原身高表中的身高与结果集进行比较,如果存在,就输出这条学生的记录。

先看下数据表

在这里插入图片描述

SELECT *
FROM n_height
WHERE height IN
(
SELECT height FROM n_height WHERE height>170
)

在这里插入图片描述

3.2 带比较运算符的子查询

如果可以确认子查询返回的结果只包含一个单值,那么可以直接使用比较运算符连接子查询。
经常使用的比较运算符包括等于(=)、不等于(<>或!=)、小于(<)、大于(>)、小于等于(<=)和大于等于(>=)。

比如查询身高高于郝某人的信息。

SELECT *
FROM n_height
WHERE height>
(
SELECT height 
FROM n_height
WHERE name="郝某人"
)

在这里插入图片描述

3.3 带exists的子查询

exists: 是否存在的意思, exists子查询就是用来判断某些条件是否满足(跨表),
exists是接在where之后
exists返回的结果只有0和1.

如果有身高高于185的同学,就列出整个班的信息

SELECT *
FROM n_height
WHERE EXISTS
(
SELECT *
FROM n_height
WHERE height>185
)

在这里插入图片描述

3.4 带any关键字的子查询

any关键字表示满足其中的任意一个条件使用any关键字时,只要满足内层查询语句结果的的任意一个,就可以通过该条件来执行外层查询语句。

SELECT *
FROM n_height
WHERE id <ANY
(
SELECT id FROM n_height
)

在这里插入图片描述

3.5 带all关键字的子查询

all和any刚好是相反的,all关键字表示满足所有结果使用all关键字,要满足内层查询语句的所有结果,才可以通过该条件来执行外层查询语句。

SELECT *
FROM n_height
WHERE id >ALL
(
SELECT id FROM n_height
)

在这里插入图片描述

发布了80 篇原创文章 · 获赞 207 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_43518645/article/details/104861926