Tutoriel de base MySQL 15 - Requête sur plusieurs tables

Tutoriel de base MySQL 15 - Requête sur plusieurs tables

Produit cartésien

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)
复制代码

En prenant ces deux tables comme exemple, le phénomène de produit cartésien est que chaque enregistrement de la table A correspond à chaque enregistrement de la table B pour former un nouvel enregistrement. Par exemple, la table A a trois enregistrements et la table B a trois enregistrements combinés pour former 3* 3( 9) enregistrements.

jointure interne

Les données affichées par le produit cartésien contiendront des éléments dont nous n'avons pas besoin, nous pouvons donc filtrer les conditions indésirables avec des conditions.

jointure interne implicite

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)
复制代码

jointure interne explicite

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)
复制代码

Relativement parlant, la connexion implicite est facile à comprendre et à écrire, la syntaxe est simple et il y a moins de points à craindre. Mais la jointure explicite peut réduire l'analyse des champs et avoir une vitesse d'exécution plus rapide. Cet avantage de vitesse est évident lorsque 3 tables ou plus sont jointes.

jointure externe

Ajoutez un nouvel enregistrement à l'utilisateur avec un foot_idchamp nul.

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)
复制代码

À ce stade, si le champ de condition est vide, il ne sera pas interrogé à l'aide de la jointure interne, nous pouvons donc utiliser la jointure externe pour le résoudre.

Jointure externe gauche (l'intersection de la table de gauche et des tables de gauche et de droite)

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)
复制代码

Jointure externe droite (l'intersection de toutes les tables de droite et des tables de gauche et de droite)

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)
复制代码

userL'information indiquant que la table idest 4 n'est pas affichée ici car le footchamp de la table n'a pas de valeur nulle idcorrespondant userau champ de la table.foot_id

Essentiellement, la jointure externe gauche et la jointure externe droite sont identiques, tant que la position de la table est modifiée, l'effet peut être le même, par exemple :

//左外连接
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; 
复制代码

L'effet de l'exécution de ces deux instructions SQL est le même.

auto-connexion

Les jointures automatiques peuvent être utilisées avec des jointures internes et externes.

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

t_idLe champ correspondant idreprésente la relation supérieure. Maintenant, si vous avez besoin d'interroger le supérieur correspondant à chaque personne, vous devez utiliser l'auto-connexion.

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)
复制代码

L'auto-jointure est essentiellement une table qui prend deux alias différents et l'utilise comme deux tables.

requête conjointe

Lorsque nous interrogeons plusieurs tables, nous pouvons utiliser la requête union pour collecter des données sur une table.

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

Supposons que nous devions interroger les informations de la personne 2 dans la table et les informations userde la personne 3 dans la table et les résumer dans une 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)
复制代码

Remarque : Le nombre de champs dans la liste de champs après plusieurs sélections doit être le même.

Dans certains cas, les résultats des deux requêtes se chevaucheront . Si nous ne voulons pas avoir de données en double, nous pouvons les supprimer union.all

sous-requête

标量子查询

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;

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

Je suppose que tu aimes

Origine juejin.im/post/7078512878214447135
conseillé
Classement