MySQL 多表查询
MySQL——多表查询
连接查询:
交叉连接:
结果:返归第一个表中复合查询条件的数据行数乘以第二个表中复合查询条件的行数
语法格式:select 查询内容 from 表1 cross join 表2;
mysql> select * from boy;
+------+--------+
| hid | bname |
+------+--------+
| A | apple |
| B | banana |
| C | pear |
+------+--------+
3 rows in set (0.00 sec)
mysql> select * from girl;
+------+-----------+
| hid | gname |
+------+-----------+
| B | lurry |
| C | aliea |
| D | 死宅女 |
+------+-----------+
3 rows in set (0.00 sec)
mysql> select * from boy cross join girl;
+------+--------+------+-----------+
| hid | bname | hid | gname |
+------+--------+------+-----------+
| A | apple | B | lurry |
| B | banana | B | lurry |
| C | pear | B | lurry |
| A | apple | C | aliea |
| B | banana | C | aliea |
| C | pear | C | aliea |
| A | apple | D | 死宅女 |
| B | banana | D | 死宅女 |
| C | pear | D | 死宅女 |
+------+--------+------+-----------+
9 rows in set (0.00 sec)
交叉连接的结果是两个表中所有数据的组合
内连接:又称为简单连接或自然连接
在内连接查询中,只有满足条件的记录才会出现在查询结果中
语法格式:select 查询内容 from 表1 join 表2 on 表1.关系字段 = 表2.关系字段
mysql> select * from con;
+------+------+
| id | name |
+------+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
+------+------+
4 rows in set (0.00 sec)
mysql> select * from com;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | b |
| 5 | c |
| 7 | d |
+------+------+
4 rows in set (0.00 sec)
mysql> select con.name, com.name from con join com on con.id = com.id;
+------+------+
| name | name |
+------+------+
| A | a |
| B | b |
+------+------+
2 rows in set (0.02 sec)
还可以使用where语句实现同样功能
mysql> select con.name, com.name from con, com where con.id = com.id;
+------+------+
| name | name |
+------+------+
| A | a |
| B | b |
+------+------+
2 rows in set (0.00 sec)
外连接:
结果:不仅包含符合查询条件和连接条件的数据,而且还包含左表,右表,或两个表中的所有数据。
语法格式:select 查询内容 from 表1 left|right join 表2 on 表1.关系字段 = 表2.关系字段 where 条件;
左连接:返回结果为左表中的所有记录和右表中符合条件的记录
右连接:返回结果为右表中的所有记录和左表中符合条件的记录
左连接:如果左表中的某条记录在右表中不存在,则为空
mysql> select con.name, com.name from con left join com on con.id = com.id;
+------+------+
| name | name |
+------+------+
| A | a |
| B | b |
| C | NULL |
| D | NULL |
+------+------+
4 rows in set (0.01 sec)
右连接:如果右表中的某条记录在左表中不存在,则为空
mysql> select con.name, com.name from con right join com on con.id = com.id;
+------+------+
| name | name |
+------+------+
| A | a |
| B | b |
| NULL | c |
| NULL | d |
+------+------+
4 rows in set (0.00 sec)
可以通过添加限制条件,使结果更加准确
子查询:
一个查询语句嵌套在另一个查询语句内部
mysql> select * from dep;
+-----+-------+
| did | dname |
+-----+-------+
| 1 | A |
| 2 | B |
| 3 | c |
| 5 | D |
+-----+-------+
4 rows in set (0.00 sec)
mysql> select * from emp;
+----+-------+------+-----+
| id | name | age | did |
+----+-------+------+-----+
| 1 | may | 20 | 1 |
| 2 | hfda | 22 | 1 |
| 3 | saef | 20 | 2 |
| 4 | qwedd | 20 | 4 |
+----+-------+------+-----+
4 rows in set (0.00 sec)
where 型子查询:内层sql的返回值在where后作为条件表达式的一部分
例句: select * from tableA where colA = (select colB from tableB where ...);
mysql> select * from emp where did = (select did from dep where dname='A');
+----+------+------+-----+
| id | name | age | did |
+----+------+------+-----+
| 1 | may | 20 | 1 |
| 2 | hfda | 22 | 1 |
+----+------+------+-----+
2 rows in set (0.00 sec)
from 型子查询:内层sql查询结果,作为一张表,供外层的sql语句再次查询
例句:select * from (select * from ...) as tableName where ....
mysql> select * from (select * from emp where age = 20) as emps where did = 1;
+----+------+------+-----+
| id | name | age | did |
+----+------+------+-----+
| 1 | may | 20 | 1 |
+----+------+------+-----+
1 row in set (0.00 sec)
带in关键字的子查询:
将内层查询语句返回值与外层查询语句进行比较操作
语法结构:select 查询内容 from表1 where did [not] in (select did from 表2 where 限制条件)
示例:
mysql> select * from dep where did in (select did from emp where age=20);
+-----+-------+
| did | dname |
+-----+-------+
| 1 | A |
| 2 | B |
+-----+-------+
2 rows in set (0.10 sec)
首先将emp表中age=20的数据查出,然后根据did作为外层查询的查询条件
mysql> select * from dep where did not in (select did from emp where age=20);
+-----+-------+
| did | dname |
+-----+-------+
| 3 | c |
| 5 | D |
+-----+-------+
2 rows in set (0.08 sec)
not in关键字与使用in关健字的查询结果正好相反
带exists关键字的子查询:
exists关健字后可以是任意一个子查询,这个子查询的作用相当于测试,它不产生任何数据,只返回true或
者false,只有当返回值为true时,外层查询才会执行。
语法结构:select 查询内容 from表1 where exists (select did from 表2 where 限制条件)
mysql> select * from dep where exists (select * from emp where age > 21);
+-----+-------+
| did | dname |
+-----+-------+
| 1 | A |
| 2 | B |
| 3 | c |
| 5 | D |
+-----+-------+
4 rows in set (0.00 sec)
由于在表emp中存在age>21的数据,则返回true,执行外层查询
由于exists关键字比in关键字运行效率高,所以在大数据量查询时,推荐使用exists
带any的关键字子查询:
any关键字表示满足其中的任意一个条件,它允许创建一个表达式对子查询的返回值列表进行比较,只要满足内
层子查询的任意一个比较条件,就返回一个结果作为外层查询条件。
语法结构:select 查询内容 from表1 where 字段1 关系运算符 any(select 字段1 from 表2)
mysql> select * from dep where did > any(select did from emp);
+-----+-------+
| did | dname |
+-----+-------+
| 2 | B |
| 3 | c |
| 5 | D |
+-----+-------+
3 rows in set (0.03 sec)
先在表emp中查出所有的did,再将dep表中所有的,只要did大于已查询出的did中任意一个,就将改数据查出
带all关键字的子查询:
all关键字与any关键字类似,但all关键字表示需要满足所有子查询返回结果
语法结构:select 查询内容 from表1 where 字段1 关系运算符 all(select 字段1 from 表2)
mysql> select * from dep where did > all(select did from emp);
+-----+-------+
| did | dname |
+-----+-------+
| 5 | D |
+-----+-------+
1 row in set (0.01 sec)
union查询:显示所有子查询结果的并集,一般不再union查询的子查询中使用order by
mysql> select * from boy;
+------+--------+
| hid | bname |
+------+--------+
| A | apple |
| B | banana |
| C | pear |
+------+--------+
3 rows in set (0.00 sec)
mysql> select * from girl;
+------+-----------+
| hid | gname |
+------+-----------+
| B | banana |
| C | aliea |
| D | 死宅女 |
+------+-----------+
3 rows in set (0.00 sec)
mysql> select * from boy
-> union
-> select * from girl;
+------+-----------+
| hid | bname |
+------+-----------+
| A | apple |
| B | banana |
| C | pear |
| C | aliea |
| D | 死宅女 |
+------+-----------+
5 rows in set (0.00 sec)