MySQL Basic Tutorial 15 - Multiple Table Query

MySQL Basic Tutorial 15 - Multiple Table Query

Cartesian Product

mysql> select * from user;
+----+------+--------+---------+
| id | name | gender | user_id |
+----+------+--------+---------+
|  1 | ton  | 男     |       1 |
|  2 | bom  | 女     |       2 |
|  3 | lin  | 男     |       3 |
+----+------+--------+---
mysql> select * from foot;
+----+------+
| id | s    |
+----+------+
|  1 | 苹果 |
|  2 | 香蕉 |
|  3 | 橘子 |
+----+------+
3 rows in set (0.03 sec)

// 笛卡尔积
mysql> select * from user,foot;
+----+------+--------+---------+----+------+
| id | name | gender | foot_id | id | s    |
+----+------+--------+---------+----+------+
|  1 | ton  | 男     |       1 |  1 | 苹果 |
|  2 | bom  | 女     |       2 |  1 | 苹果 |
|  3 | lin  | 男     |       3 |  1 | 苹果 |
|  1 | ton  | 男     |       1 |  2 | 香蕉 |
|  2 | bom  | 女     |       2 |  2 | 香蕉 |
|  3 | lin  | 男     |       3 |  2 | 香蕉 |
|  1 | ton  | 男     |       1 |  3 | 橘子 |
|  2 | bom  | 女     |       2 |  3 | 橘子 |
|  3 | lin  | 男     |       3 |  3 | 橘子 |
+----+------+--------+---------+----+------+
9 rows in set (0.03 sec)
复制代码

Taking these two tables as an example, the Cartesian product phenomenon is that each record in table A matches each record in table B to form a new record. For example, table A has three records and table B has three records combined to form 3*3( 9) records.

inner join

The data displayed by the Cartesian product will have things we don't need, so we can filter out the unwanted conditions with conditions.

implicit inner join

select 字段列表 from 表1,表2 where 条件;

mysql> select * from user as u,foot as f where u.foot_id = f.id;
+----+------+--------+---------+----+------+
| id | name | gender | foot_id | id | s    |
+----+------+--------+---------+----+------+
|  1 | ton  | 男     |       1 |  1 | 苹果 |
|  2 | bom  | 女     |       2 |  2 | 香蕉 |
|  3 | lin  | 男     |       3 |  3 | 橘子 |
+----+------+--------+---------+----+------+
3 rows in set (0.03 sec)
复制代码

explicit inner join

select 字段列表 from 表1 [inner] join 表2 on 连接条件;

mysql> select * from user as u inner join foot as f on u.foot_id = f.id;
+----+------+--------+---------+----+------+
| id | name | gender | foot_id | id | s    |
+----+------+--------+---------+----+------+
|  1 | ton  | 男     |       1 |  1 | 苹果 |
|  2 | bom  | 女     |       2 |  2 | 香蕉 |
|  3 | lin  | 男     |       3 |  3 | 橘子 |
+----+------+--------+---------+----+------+
3 rows in set (0.03 sec)
复制代码

Relatively speaking, implicit connection is easy to understand and write, the syntax is simple, and there are fewer points to worry about. But explicit join can reduce field scan and have faster execution speed. This speed advantage is obvious when 3 or more tables are joined.

outer join

Add a new record to user with a foot_idnull field.

mysql> select * from user;
+----+------+--------+---------+
| id | name | gender | foot_id |
+----+------+--------+---------+
|  1 | ton  | 男     |       1 |
|  2 | bom  | 女     |       2 |
|  3 | lin  | 男     |       3 |
|  4 | ken  | 女     | NULL    |
+----+------+--------+---------+
4 rows in set (0.04 sec)
mysql> select * from user,foot where user.foot_id = foot.id;
+----+------+--------+---------+----+------+
| id | name | gender | foot_id | id | s    |
+----+------+--------+---------+----+------+
|  1 | ton  | 男     |       1 |  1 | 苹果 |
|  2 | bom  | 女     |       2 |  2 | 香蕉 |
|  3 | lin  | 男     |       3 |  3 | 橘子 |
+----+------+--------+---------+----+------+
3 rows in set (0.04 sec)
复制代码

At this time, if the condition field is empty, it will not be queried by using inner join, so we can use outer join to solve it.

Left outer join (the intersection of the left table and the left and right tables)

select 字段列表 from 表1 left [outer] join 表2 on 条件;

mysql> select u.*,f.* from user as u left outer join foot as f on u.foot_id = f.id;
+----+------+--------+---------+------+------+
| id | name | gender | foot_id | id   | s    |
+----+------+--------+---------+------+------+
|  1 | ton  | 男     |       1 |    1 | 苹果 |
|  2 | bom  | 女     |       2 |    2 | 香蕉 |
|  3 | lin  | 男     |       3 |    3 | 橘子 |
|  4 | ken  | 女     | NULL    | NULL | NULL |
+----+------+--------+---------+------+------+
4 rows in set (0.03 sec)
复制代码

Right outer join (the intersection of all the right tables and the left and right tables)

select 字段列表 from 表1 right [outer] join 表2 on 条件;

mysql> select f.*,u.* from user as u right outer join foot as f on u.foot_id = f.id;
+----+------+----+------+--------+---------+
| id | s    | id | name | gender | foot_id |
+----+------+----+------+--------+---------+
|  1 | 苹果 |  1 | ton  | 男     |       1 |
|  2 | 香蕉 |  2 | bom  | 女     |       2 |
|  3 | 橘子 |  3 | lin  | 男     |       3 |
+----+------+----+------+--------+---------+
3 rows in set (0.03 sec)
复制代码

userThe information that the table idis 4 is not displayed here because the footfield in the table does not have a null value idcorresponding userto the field in the table.foot_id

In essence, the left outer join and the right outer join are the same, as long as the position of the table is changed, the effect can be the same, for example:

//左外连接
select * from user as u left outer join foot as f on u.foot_id = f.id; 
//右外连接
select * from foot as f right outer join user as u on u.foot_id = f.id; 
复制代码

The effect of the execution of these two SQL statements is the same.

self-connection

Self joins can be used with inner and outer joins.

mysql> select * from yg;
+----+------+------+
| id | name | t_id |
+----+------+------+
|  1 | 张三 | NULL |
|  2 | 李四 |    1 |
|  3 | 王五 |    1 |
|  4 | 熊大 |    2 |
+----+------+------+
4 rows in set (0.05 sec)
复制代码

t_idThe corresponding field idrepresents the superior relationship. Now, if you need to query the superior corresponding to each person, you need to use self-connection.

mysql> select a.name,b.name from yg as a left outer join yg as b on a.t_id = b.id;
+------+------+
| name | name |
+------+------+
| 李四 | 张三 |
| 王五 | 张三 |
| 熊大 | 李四 |
| 张三 | NULL |
+------+------+
4 rows in set (0.03 sec)
复制代码

Self-join is essentially a table that takes two different aliases and uses it as two tables.

joint query

When we query multiple tables, we can use union query to collect data on one table.

select 字段列表 from 表1 .... union[all] select 字段列表 from 表2 ...;

Suppose we need to query the information of person 2 in the table and the information userof person 3 in the table and summarize them in one table.idygid

mysql> select u.id,u.name,u.gender from user as u where id = 2
    -> union all 
    -> select * from yg where id = 3;
+----+------+--------+
| id | name | gender |
+----+------+--------+
|  2 | bom  | 女     |
|  3 | 王五 | 1      |
+----+------+--------+
2 rows in set (0.03 sec)
复制代码

Note: The number of fields in the field list after multiple selects should be the same.

In some cases, the results of the two queries will overlap. If we don't want to have duplicate data, we can remove unionit all.

subquery

标量子查询

select * from 表1 where a = (select a from 表2 where 条件);

如果我们要查询user表中id为1的人对应foot表中的水果。

mysql> select user.foot_id from user where id = 1; 
+---------+
| foot_id |
+---------+
|       1 |
+---------+
1 row in set (0.03 sec)
mysql> select foot.s from foot where id = 1;
+------+
| s    |
+------+
| 苹果 |
+------+
1 row in set (0.02 sec)

// 标量子查询

mysql>  select foot.s from foot where id = (select user.foot_id from user where id = 1);
+------+
| s    |
+------+
| 苹果 |
+------+
1 row in set (0.04 sec)
复制代码

列子查询

子查询中数据为列。

select * from 表1 where a in (select a from 表2 where 条件)

select * from 表1 where a > all/some/any(select b from 表2 where 条件);

常用in/not in/any/some/all,其中any和some时一样的效果。

查询user表中在foot表有对应信息的信息。

mysql> select * from user where id in (select foot.id from foot);
+----+------+--------+---------+
| id | name | gender | foot_id |
+----+------+--------+---------+
|  1 | ton  | 男     |       1 |
|  2 | bom  | 女     |       2 |
|  3 | lin  | 男     |       3 |
+----+------+--------+---------+
3 rows in set (0.02 sec)
复制代码

行子查询

子查询中数据为行。

select * from 表名 where (a,b) = (select a,b from where 条件);

mysql> select * from user;
+----+------+--------+---------+
| id | name | gender | foot_id |
+----+------+--------+---------+
|  1 | 张三 | 男     |       1 |
|  2 | 李四 | 女     |       2 |
|  3 | 王五 | 男     |       3 |
|  4 | 熊大 | 女     | NULL    |
+----+------+--------+---------+
4 rows in set (0.03 sec)
mysql> select * from yg;
+----+------+------+
| id | name | t_id |
+----+------+------+
|  1 | 张三 | NULL |
|  2 | 李四 |    1 |
|  3 | 王五 |    1 |
+----+------+------+
3 rows in set (0.03 sec)

//行子查询
mysql> select * from user where (id,name) in (select yg.id,yg.name from yg);
+----+------+--------+---------+
| id | name | gender | foot_id |
+----+------+--------+---------+
|  1 | 张三 | 男     |       1 |
|  2 | 李四 | 女     |       2 |
|  3 | 王五 | 男     |       3 |
+----+------+--------+---------+
3 rows in set (0.03 sec)
复制代码

表子查询

select * from 表名 where (a,b) in (select a,b from 表名 where name = 'bom' or name = 'tom');

mysql> select * from user where (user.id,user.name) in (select yg.id,yg.name from yg where name = '张三' or name = '王五');
+----+------+--------+---------+
| id | name | gender | foot_id |
+----+------+--------+---------+
|  1 | 张三 | 男     |       1 |
|  3 | 王五 | 男     |       3 |
+----+------+--------+---------+
2 rows in set (0.04 sec)
复制代码

也可以把查询后的子表当主句查询表,例如:

select e.* , d.* from (select * from 表名 where date > '2006-5-23') e left join dept d on e.dept_id = d.id;

(点击进入专栏查看详细教程)

Guess you like

Origin juejin.im/post/7078512878214447135