SQL99语法下的多表连接
1、引入
例题:
现在有三张表:
第一张表:t_emp(储存人物基本信息)
ID | NAME | AGE | DEPTID | EMPNO |
---|---|---|---|---|
1 | 风清扬 | 90 | 1 | 100001 |
2 | 岳不群 | 50 | 1 | 100002 |
3 | 令狐冲 | 24 | 1 | 100003 |
4 | 洪七公 | 70 | 2 | 100004 |
5 | 乔峰 | 35 | 2 | 100005 |
6 | 灭绝师太 | 70 | 3 | 100006 |
7 | 周芷若 | 20 | 3 | 100007 |
8 | 张三丰 | 100 | 4 | 100008 |
9 | 张无忌 | 25 | 5 | 100009 |
10 | 韦小宝 | 18 | null | 100010 |
第二张表:t_dept(储存人物帮派信息)
ID | DEPTNAME | ADDRESS |
---|---|---|
1 | 华山 | 华山 |
2 | 丐帮 | 洛阳 |
3 | 峨眉 | 峨眉山 |
4 | 武当 | 武当山 |
5 | 明教 | 光明顶 |
6 | 少林 | 少林寺 |
第三张表:t_arts(储存人物掌握的功夫信息)
ID | KONGFU |
---|---|
1 | 独孤九剑 |
2 | 辟邪剑法 |
3 | 华山剑法 |
4 | null |
5 | 打狗棒法 |
6 | 峨嵋剑法 |
7 | 九阴真经 |
8 | null |
9 | 九阳神功 |
10 | 神行百变 |
题目:查询出“令狐冲”所对应的所有信息。
1.1一张表上查询
将所有信息储存在一张表上
实现代码:
SELECT *
FROM t_all
WHERE `name`='令狐冲';
优点:①只与数据库有一次交互,故查询耗时短。
②只有一句查询语句,操作简单。
缺点:浪费内存,明显的以空间换时间。
1.2子查询
方法:①用子查询先查询出“令狐冲”所对应的ID和DEPTID
②根据ID从t_arts表上查询出对应的功夫;根据DEPTID从t_dept查询出对应门派和地址。
③将所有信息整合后完整表示出来。
实现代码:
SELECT *
FROM t_emp ,t_arts ,t_dept
WHERE t_emp.`name`='令狐冲'
AND t_arts.id = (
SELECT id
FROM t_emp
WHERE `name`='令狐冲'
)
AND t_dept.id = (
SELECT deptId
FROM t_emp
WHERE `name`='令狐冲'
);
优点:储存表的内存空间浪费的少。
缺点:①如果不保证子查询的条件唯一,会返回多个值。
②子查询类似于循环嵌套。
2、连接查询
思路:将数据分开储存在多个表中,在要使用的时候将多个表进行连接整合储存在临时表中(关闭连接时自动删除),再对临时表进行查询操作。
优点:查询效率高,内存空间浪费少;
缺点:①数据库的不同,语法的选择不同。
②数据的有效利用率低。
2.1、多表连接查询下的sql99语法与sql92语法的区别
sql92:
优点:语法简单,结构简单易懂。
缺点:①MySQL数据库不支持SQL92语法的多表连接。
②SQL92语法不支持全外连接。
sql99:
优点:①支持全外连接。
②某些数据库(MySQL等)支持sql99语法的左外、右外连接。
缺点:①某些数据库(MySQL等)不支持sql99语法的全外连接。
2.2、sql99语法的七种多表连接。
2.2.0、内连接
内连接:将两表能匹配的部分连接起来。
图解:
代码实现:
SELECT *
FROM t_emp e JOIN t_dept d
ON e.deptId = d.id;
2.2.1、左外连接(LEFT关键字)
图解:
左外连接:将左边表全部展示,不管右表是否与之匹配。
代码实现:
SELECT *
FROM t_emp e LEFT JOIN t_dept d
ON e.deptId = d.id;
2.2.2、右外连接(RIGHT关键字)
右外连接:将右边表全部展示,不管左边表是否与之匹配。
图解:
代码实现:
SELECT *
FROM t_emp e RIGHT JOIN t_dept d
ON e.deptId = d.id;
2.2.3、全外连接(FULL关键字——sql99)
全外连接:将两表所有部分全部展示出来。
图解:
注意:sql99有全外连接的语法,但MySQL不支持sql99的全外连接。
SELECT *
FROM t_emp e FULL JOIN t_dept d
ON e.deptId = d.id;
UNION介绍:
可以将SELECT返回的查询结果进行合并。
1、UNION 操作符:返回两个查询的结果集的并集,去除重复记录。
2、UNION ALL操作符:返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。
注意:
①UNION 内部的 SELECT 语句必须拥有相同数量的列。(会报错)
②列也必须拥有相似的数据类型。(不会报错)
③同时,每条 SELECT 语句中的列的顺序必须相同。(不会报错)
代码实现:
UNION:
SELECT *
FROM t_emp e LEFT JOIN t_dept d
ON e.deptId = d.id
UNION
SELECT *
FROM t_emp e RIGHT JOIN t_dept d
ON e.deptId = d.id;
UNION ALL:
SELECT *
FROM t_emp e LEFT JOIN t_dept d
ON e.deptId = d.id
UNION ALL
SELECT *
FROM t_emp e RIGHT JOIN t_dept d
ON e.deptId = d.id
WHERE e.deptId IS NULL;
或者
SELECT *
FROM t_emp e RIGHT JOIN t_dept d
ON e.deptId = d.id
UNION ALL
SELECT *
FROM t_emp e LEFT JOIN t_dept d
ON e.deptId = d.id
WHERE e.deptId IS NULL;
或者
SELECT *
FROM t_emp e JOIN t_dept d
ON e.deptId = d.id
UNION ALL
SELECT *
FROM t_emp e RIGHT JOIN t_dept d
ON e.deptId = d.id
WHERE e.deptId IS NULL
UNION ALL
SELECT *
FROM t_emp e LEFT JOIN t_dept d
ON e.deptId = d.id
WHERE e.deptId IS NULL;
2.2.4、其他连接
代码实现:
SELECT * FROM t_emp e LEFT JOIN t_dept d ON e.deptId = d.id WHERE e.deptId IS NULL;
代码实现:
SELECT * FROM t_emp e RIGHT JOIN t_dept d ON e.deptId = d.id WHERE e.deptId IS NULL;
代码实现:
SELECT * FROM t_emp e RIGHT JOIN t_dept d ON e.deptId = d.id WHERE e.deptId IS NULL UNION ALL SELECT * FROM t_emp e LEFT JOIN t_dept d ON e.deptId = d.id WHERE e.deptId IS NULL;
综上所述: