文章目录
🥝多表关系
概述
在项目开发中,进行数据表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间互相关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
1.一对多(多对一)
2.多对多
3.一对一
🍉一对多(多对一)
例子:
🍉多对多
例子:
🍉一对一
例子:
🥝多表查询
多表查询时需要去掉多余的笛卡尔积【使用WHERE条件句即可】
什么是笛卡尔积
👏示例数据表
🔜 笛卡尔积效果演示
【说明】:运行了标亮的Sql语句后,发现显示的结果是所有人都选了所有课程(数据没截完,太多了),显然,这不是我们想要的设计结果
【使用WHERE条件句即可消除多余的笛卡尔积数据】
Sql语句【未使用WHERE条件句,产生了很多多余的笛卡尔积】:SELECT * FROM course,student;
Sql语句【使用了WHERE条件句,消除了多余的笛卡尔积,得到了正确的结果】:SELECT * FROM course,student WHERE course.id = student.course_id;
🧾多表查询分类
🍋🟩连接查询 - 内连接【内连接查询码的是两张表的交集部分】
隐式内连接🍉
语法
SELECT 字段列表 FROM 表1,表2 WHERE 条件…
举例:只显示该选课学生的名字和所选课程的名字【给course表起了别名a,student表起了别名b】
SELECT a.name,b.name FROM course a,student b WHERE a.id = b.course_id;
显示内连接🍉
语法
SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件…
中括号[ ] 中的内容代表可以省略
举例:【与上面一样】
SELECT a.name,b.name FROM course a INNER join student b ON a.id = b.course_id;
上面的隐式内连接和显示内连接的结果均一样,如下图:
两种连接方式的区别:1.表的连接形式不同 2.连接条件的形式不同
🍋🟩连接查询 - 外连接
温馨提示:外连接查询的结果为主表中所有的记录。如果从表中有和它匹配的,则显示匹配的值,这部分相当于内连接查询出来的结果;如果从表中没有和它匹配的,则显示null。
即:外连接查询的结果 = 内连接的结果 + 主表中有的而内连接结果中没有的记录
左外连接🍉
语法
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件…
1.相当于查询表1(左表)的所有数据,包含 表1和表2交集部分的数据
2.中括号[ ] 中的内容代表可以省略
示例语句:
SELECT a.name,b.name FROM course a LEFT OUTER join student b ON a.id = b.course_id;
右外连接🍉
语法
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件…
1.相当于查询表2(右表)的所有数据,包含 表1和表2交集部分的数据
2.中括号[ ] 中的内容代表可以省略
示例语句:
SELECT a.name,b.name FROM course a RIGHT OUTER join student b ON a.id = b.course_id;
🍋🟩连接查询 - 自连接(把一张表看成两张表来操作)
语法🍉
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B 条件…
自连接查询,可以是内连接查询,也可以是外连接查询
示例代码:【要查询该员工的名字和其领导的名字,而员工信息和领导信息都在同一张表里】
SELECT a.name '员工', b.name '领导' FROM emp a LEFT JOIN emp b ON a.managerid = b.id;
🍋🟩联合查询
对于union查询, 就是把多次查询的结果合并起来, 形成一个新的查询结果
语法🍉
SELECT 字段列表 FROM 表A …
UNION [ ALL ]
SELECT 字段列表 FROM 表B …
特别注意:
- UNION ALL 会将全部数据直接合并到一起(可能存在重复),而 UNION 会对合并后的数据去重
- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致
案例:用一条Sql语句将薪资低于5000的员工和年龄大于50岁的员工全部查询出来(两个条件独立)
SELECT * FROM emp WHERE salary < 5000
UNION ALL
SELECT * FROM emp WHERE age > 50;
运行结果:
【直接把两个语句的查询结果合并到一起来显示了,但是这样出现了重复–>id为11的鹿杖客两个条件都满足,出现了两次,所以我们可以把ALL去掉,这样就不会出现重复了,自动去重】
🍋🟩子查询
概念:SQL语句中嵌套SELECT语句,成为嵌套查询,又称为子查询
语法🍉
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2)
说明:子查询外部的语句可以是INSERT/UPDATE/DELETE/SELECT中的任意一个
子查询类别🧾
1.根据子查询结果的不同,分为:
子查询列别 | 子查询结果 |
---|---|
标量子查询 | 子查询结果为单个值 |
列子查询 | 子查询结果为一列 |
行子查询 | 子查询结果为一行 |
表子查询 | 子查询结果为多行多列 |
2.根据子查询位置,分为:WHERE之后,FROM之前,SELECT之后
🍋标量子查询 (子查询结果为单个值)
概览:子查询返回的结果是单个值(数字、字符串、日期等),常见的操作符:= 、<> 、>、>=、<、<=
示例 — 查询 “销售部” 的所有员工信息
可拆解为两步:
a.查询 “销售部” 的部门ID
b.根据销售部的部门ID,查询员工信息
合并,使用标量子查询,SQL语句:
SELECT * FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name = '销售部');
🍋列子查询 (子查询结果为一列)
说明:IN是确定的集合,而ANY/SOME可以是区间和模糊范围
案例1 — 查询"销售部"和"市场部"的所有员工信息
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE name = '销售部' OR name = '市场部');
案例2 — 查询比 财务部 所有人的工资都要高的员工信息
分解步骤:
a.查询财务部所有的人员工资
b.查询 比所有财务部的人员工资都要高的人员信息
SELECT * FROM emp WHERE salary > ALL( SELECT salary FROM emp
WHERE id = (SELECT id FROM dept WHERE name = '财务部') )
🍋行子查询 (子查询结果为一行)
常用的操作符:= 、<> 、IN 、NOT IN
案例 — 查询与 林七夜的薪资 及 直属领导 相同的员工信息
SELECT * FROM emp WHERE (salary,managerid) = (SELECT salary,managerid FROM emp WHERE name = '林七夜');
🍋表子查询 (子查询结果为多行多列)
常用操作符:IN
案例 — 查询 与 林七夜 或 微微 的职位和薪资相同的员工信息
SELECT * FROM emp WHERE (position,salary) IN (SELECT position,salary
FROM emp WHERE name = '林七夜' OR name = '微微');
如果我的内容对你有帮助,请 点赞 , 评论 , 收藏 。创作不易,大家的支持就是我坚持下去的动力!