多表查询
内连接
现在有俩表如下图所示,一个employee,com_Id为外键和company中的主键Id关联。employee中只有Id = 5的com_Id为空,数据未关联。
sql
mysql> select * from employee;
+----+----------+--------+--------+
| Id | name | gender | com_Id |
+----+----------+--------+--------+
| 2 | 李四 | 男 | 1 |
| 3 | 王二麻子 | 女 | 3 |
| 4 | 路人甲 | 女 | 2 |
| 5 | 二嫂 | 女 | NULL |
+----+----------+--------+--------+
4 rows in set (0.00 sec)
mysql> select * from company;
+----+------------+------------+
| Id | name | catagory |
+----+------------+------------+
| 1 | 腾讯 | 互联网企业 |
| 2 | 国家电网 | 国企 |
| 3 | 中电十四所 | 研究所 |
+----+------------+------------+
3 rows in set (0.00 sec)
如果直接查询两个表的所有信息,根据笛卡尔积,会查出来3*4共12条有效信息
sql
mysql> select * from company,employee;
+----+------------+------------+----+----------+--------+--------+
| Id | name | catagory | Id | name | gender | com_Id |
+----+------------+------------+----+----------+--------+--------+
| 3 | 中电十四所 | 研究所 | 2 | 李四 | 男 | 1 |
| 2 | 国家电网 | 国企 | 2 | 李四 | 男 | 1 |
| 1 | 腾讯 | 互联网企业 | 2 | 李四 | 男 | 1 |
| 3 | 中电十四所 | 研究所 | 3 | 王二麻子 | 女 | 3 |
| 2 | 国家电网 | 国企 | 3 | 王二麻子 | 女 | 3 |
| 1 | 腾讯 | 互联网企业 | 3 | 王二麻子 | 女 | 3 |
| 3 | 中电十四所 | 研究所 | 4 | 路人甲 | 女 | 2 |
| 2 | 国家电网 | 国企 | 4 | 路人甲 | 女 | 2 |
| 1 | 腾讯 | 互联网企业 | 4 | 路人甲 | 女 | 2 |
| 3 | 中电十四所 | 研究所 | 5 | 二嫂 | 女 | NULL |
| 2 | 国家电网 | 国企 | 5 | 二嫂 | 女 | NULL |
| 1 | 腾讯 | 互联网企业 | 5 | 二嫂 | 女 | NULL |
+----+------------+------------+----+----------+--------+--------+
12 rows in set (0.00 sec)
但是如果在查询语句后面限定条件,就可以查出符合条件的数据,这些数据是两个表的交集,查询这个交集的过程就叫内连接查询。
sql
mysql> select * from company,employee where company.Id = employee.com_Id;
+----+------------+------------+----+----------+--------+--------+
| Id | name | catagory | Id | name | gender | com_Id |
+----+------------+------------+----+----------+--------+--------+
| 1 | 腾讯 | 互联网企业 | 2 | 李四 | 男 | 1 |
| 2 | 国家电网 | 国企 | 4 | 路人甲 | 女 | 2 |
| 3 | 中电十四所 | 研究所 | 3 | 王二麻子 | 女 | 3 |
+----+------------+------------+----+----------+--------+--------+
3 rows in set (0.00 sec)
当然写表的全称太麻烦了,也可以用别称
sql
mysql> select * from company c,employee e where c.Id = e.com_Id;
+----+------------+------------+----+----------+--------+--------+
| Id | name | catagory | Id | name | gender | com_Id |
+----+------------+------------+----+----------+--------+--------+
| 1 | 腾讯 | 互联网企业 | 2 | 李四 | 男 | 1 |
| 2 | 国家电网 | 国企 | 4 | 路人甲 | 女 | 2 |
| 3 | 中电十四所 | 研究所 | 3 | 王二麻子 | 女 | 3 |
+----+------------+------------+----+----------+--------+--------+
3 rows in set (0.00 sec)
也可以不查所有字段,只查自己想要的字段
sql
mysql> select c.Id,e.name from company c,employee e where c.Id = e.com_Id;
+----+----------+
| Id | name |
+----+----------+
| 3 | 王二麻子 |
| 2 | 路人甲 |
| 1 | 李四 |
+----+----------+
3 rows in set (0.00 sec)
隐式内连接
sql
mysql> select * from company,employee where company.Id = employee.com_Id;
上述就是隐式内连接
显式内连接
语法格式:
select * from 表1 join 表2 on 条件;
sql
mysql> select * from company join employee on company.Id = employee.com_Id;
+----+------------+------------+----+----------+--------+--------+
| Id | name | catagory | Id | name | gender | com_Id |
+----+------------+------------+----+----------+--------+--------+
| 1 | 腾讯 | 互联网企业 | 2 | 李四 | 男 | 1 |
| 2 | 国家电网 | 国企 | 4 | 路人甲 | 女 | 2 |
| 3 | 中电十四所 | 研究所 | 3 | 王二麻子 | 女 | 3 |
+----+------------+------------+----+----------+--------+--------+
3 rows in set (0.00 sec)
外连接
不仅查两个表的交集,还查某一边表能查到的所有数据
左外连接
不仅查两个表的交集,还查左边表能查到的所有数据
sql
mysql> select * from employee left join company on employee.com_Id = company.Id;
+----+----------+--------+--------+------+------------+------------+
| Id | name | gender | com_Id | Id | name | catagory |
+----+----------+--------+--------+------+------------+------------+
| 2 | 李四 | 男 | 1 | 1 | 腾讯 | 互联网企业 |
| 3 | 王二麻子 | 女 | 3 | 3 | 中电十四所 | 研究所 |
| 4 | 路人甲 | 女 | 2 | 2 | 国家电网 | 国企 |
| 5 | 二嫂 | 女 | NULL | NULL | NULL | NULL |
+----+----------+--------+--------+------+------------+------------+
4 rows in set (0.00 sec)
右外连接
不仅查两个表的交集,还查右边表能查到的所有数据
sql
mysql> select * from employee right join company on employee.com_Id = company.Id;
+------+----------+--------+--------+----+------------+------------+
| Id | name | gender | com_Id | Id | name | catagory |
+------+----------+--------+--------+----+------------+------------+
| 2 | 李四 | 男 | 1 | 1 | 腾讯 | 互联网企业 |
| 4 | 路人甲 | 女 | 2 | 2 | 国家电网 | 国企 |
| 3 | 王二麻子 | 女 | 3 | 3 | 中电十四所 | 研究所 |
+------+----------+--------+--------+----+------------+------------+
3 rows in set (0.00 sec)
子查询
子查询,又称嵌套查询 ,就是将某一个查询结果作为另外一个查询条件的对象。
现在user如下所示
sql
mysql> select * from user;
+-------+------------+------+
| name | salary | id |
+-------+------------+------+
| zonda | 1000000000 | 1 |
| chris | 3000 | 2 |
| john | 2000 | 3 |
| jack | 10000 | 4 |
+-------+------------+------+
4 rows in set (0.00 sec)
我要在user表中找工资大于zonda的员工信息
首先可以查出名为zonda的员工
sql
mysql> select * from user where name='jack';
+------+--------+------+
| name | salary | id |
+------+--------+------+
| jack | 10000 | 4 |
+------+--------+------+
1 row in set (0.00 sec)
再查出工资大于10000的员工
sql
mysql> select * from user where salary > 10000;
+-------+------------+------+
| name | salary | id |
+-------+------------+------+
| zonda | 1000000000 | 1 |
+-------+------------+------+
1 row in set (0.00 sec)
其实可以两步并一步,用第一步的查询结果作为查询条件
sql
mysql> select * from user where salary > (select salary from user where name='jack');
+-------+------------+------+
| name | salary | id |
+-------+------------+------+
| zonda | 1000000000 | 1 |
+-------+------------+------+
1 row in set (0.00 sec)