多表连接的基本语法
多表连接,即将多个表拼接成一个表,然后进行查询
[En]
Multi-table join, that is, several tables are spliced into one table and then queried
select 字段1, 字段2, ...
from 表1 {inner|lift|right} join 表2
on 连接条件;
有两个表:部门表和雇员表。
[En]
There are two tables: the department table and the employee table.
交叉连接和笛卡尔积现象
交叉连接
交叉连接,也称为无条件内部连接/笛卡尔连接
[En]
Cross connect, also known as unconditional inner connection / Cartesian connection
第一张表格的每一项将依次与另一张表格的每一项合并。
[En]
Each item of the first table will be combined with each item of the other table in turn.
select * from employee,department;
上述结果肯定不是我们想知道的。左桌上的每个人都有四个部门。仔细观察这四条记录正是将左表中的每条记录与右表中的每条记录进行匹配的结果。
[En]
The above results are certainly not what we want to know. Everyone in the left table has four departments. Careful observation of these four records is exactly the result of matching each record in the left table with that in the right table.
笛卡尔积现象
笛卡尔积现象产生的原因:两张表没有有效的连接条件。既然你没有连接条件,本表中的第一行肯定是能和另外表中的所有行进行一一匹配,同理,本表中的第二行肯定是能和另外表中的所有行进行一一匹配,以此类推,本表中的最后一行m也可以和另外表中的所有行进行一一匹配。若另外一张表有n行,那么最后显示的行数,肯定就是m*n行了。
如果不想产生笛卡尔积现象,就需要添加有效的表连接条件。拿上述例子来说,左表dep_id只有和右表id相等时,才代表他们的部门。
内连接
内连接(INNER JOIN)是找几张表的交集,即根据条件筛选出来正确的结果。
select emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name
from employee as emp INNER JOIN department as dep
on emp.dep_id=dep.id;
由于部门表中没有 id=5
的部门,所以员工表 dep_id=5
的这条记录没有返回;而由于 行政部
没有员工,所以这条记录也没返回。
外连接
左外连接
左连接(left join)是以 左表为准,如果右表中没有合适的记录,用 NULL
补全;其本质是在内连接的基础上增加左表有结果而右表没有的记录(内连接时,这种情况的记录会忽略)。
select emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name
from employee as emp left join department as dep
on emp.dep_id=dep.id;
右外连接
跟左连接正好相反,右连接(right join)是以右表为准,如果左表中某些字段没有合适的结果,用 NULL
补全;其本质是在内连接的基础上增加右表有结果而左表没有的记录(内连接时,这种情况的记录会忽略)。
select emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name
from employee as emp right join department as dep
on emp.dep_id=dep.id;
全外连接
全外连接,在内连接的基础上,展示左右表的所有的记录,而左右表中缺省记录以 NULL
补全。
MySQL中并没有全外连接的 FULL JOIN
语法,而是借助 UNION/UNION ALL
语句实现。
UNION
和 UNION ALL
的区别, UNION
具有去重功能。
select emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name
from employee as emp left join department as dep
on emp.dep_id=dep.id
union
select emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name
from employee as emp right join department as dep
on emp.dep_id=dep.id;
子查询
子查询是将一条查询语句嵌套到另一条查询语句中的一种方式:
[En]
A subquery is a way of nesting one query statement into another query statement:
- 子查询的内部查询结果可以作为外部查询语句,提供查询条件。
[En]
the inner query result of a subquery can be used as an outer query statement to provide query conditions.*
- 子查询中可以包含
IN
、NOT IN
、AND
、ALL
、EXISTS
、NOT EXISTS
等关键字。 - 子查询中还可以包含比较运算符,如
=
、!=
、>
、<
等。
-- 查询平均年龄在20以上的部门名称select namefrom departmentwhere id in (select dep_idfrom employeegroup by dep_idhaving avg(age) > 20);-- 查询财务部员工姓名select namefrom employeewhere dep_id in (select idfrom departmentwhere name='财务部');-- 查询所有大于平均年龄的员工的年龄和姓名select name,agefrom employeewhere age > (select avg(age) from employee);
Original: https://www.cnblogs.com/pure3417/p/15225630.html
Author: pure3417
Title: MySQL之连接查询和子查询
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508183/
转载文章受原作者版权保护。转载请注明原作者出处!