9:多表查询-MySQL

9.1 union联合查询

UNION关键字用于连接两个以上的SELECT语句的结果组合到一个结果集合中

使用union ,mysql会把结果集中重复的记录删掉

使用union all,mysql会把所有的记录返回,且效率高于union

mysql> select * from stu;
+-------+-------+
| stuId | name  |
+-------+-------+
|     4 | frank |
|     5 | Tom   |
+-------+-------+
2 rows in set (0.01 sec)

mysql>
mysql> select * from eatery;
+----+----------+-------+
| id | money    | stuId |
+----+----------+-------+
|  0 | 999.0000 |     5 |
|  1 |  20.5000 |  NULL |
|  2 |  78.6000 |     4 |
|  3 |  99.9000 |  NULL |
|  4 | 748.4000 |     4 |
|  5 | 748.4000 |  NULL |
|  6 | 999.0000 |     5 |
|  7 | 345.0000 |     4 |
+----+----------+-------+
8 rows in set (0.01 sec)

mysql> select stuId from eatery union all select stuId from stu;
+-------+
| stuId |
+-------+
|  NULL |
|  NULL |
|  NULL |
|     4 |
|     4 |
|     4 |
|     5 |
|     5 |
|     4 |
|     5 |
+-------+
10 rows in set (0.00 sec)

mysql> select stuId from eatery union  select stuId from stu;
+-------+
| stuId |
+-------+
|  NULL |
|     4 |
|     5 |
+-------+
3 rows in set (0.00 sec)

9.2 inner join内联查询

inner joinjoin 是相同的

图片引用自菜鸟教程
在这里插入图片描述

mysql> select * from stu;
+-------+-------+
| stuId | name  |
+-------+-------+
|     4 | frank |
|     5 | Tom   |
+-------+-------+
2 rows in set (0.01 sec)


mysql> select * from eatery;
+----+----------+-------+
| id | money    | stuId |
+----+----------+-------+
|  0 | 999.0000 |     5 |
|  1 |  20.5000 |  NULL |
|  2 |  78.6000 |     4 |
|  3 |  99.9000 |  NULL |
|  4 | 748.4000 |     4 |
|  5 | 748.4000 |  NULL |
|  6 | 999.0000 |     5 |
|  7 | 345.0000 |     4 |
+----+----------+-------+
8 rows in set (0.01 sec)

mysql> select eatery.money, stu.name from eatery inner join stu on eatery.stuId = stu.stuId;
+----------+-------+
| money    | name  |
+----------+-------+
| 999.0000 | Tom   |
|  78.6000 | frank |
| 748.4000 | frank |
| 999.0000 | Tom   |
| 345.0000 | frank |
+----------+-------+
5 rows in set (0.00 sec)

mysql> select id,name,money from eatery  inner join stu on stu.stuId=eatery.stuId;
+----+-------+----------+
| id | name  | money    |
+----+-------+----------+
|  0 | Tom   | 999.0000 |
|  2 | frank |  78.6000 |
|  4 | frank | 748.4000 |
|  6 | Tom   | 999.0000 |
|  7 | frank | 345.0000 |
+----+-------+----------+
5 rows in set (0.00 sec)

9.3 inner join注意事项

必须指定id,例如eatery.stuId = stu.stuId

如果还要连接两张以上的表,可以继续添加Inner join,但是不建议这样操作

9.4 left join 外连接

在某些数据库中,left out称为left outer join

图片引用自菜鸟教程
在这里插入图片描述

在这里插入图片描述

9.5 rigth join 外连接

在某些数据库中,left out 称为right outer join

图片引用自菜鸟教程
在这里插入图片描述

在这里插入图片描述

9.6 cross join 交叉连接

cross join 返回笛卡尔积,使用时须谨慎,可能产生非常大的表

mysql> select * from eatery cross join stu;
+----+----------+-------+-------+-------+
| id | money    | stuId | stuId | name  |
+----+----------+-------+-------+-------+
|  0 | 999.0000 |     5 |     4 | frank |
|  0 | 999.0000 |     5 |     5 | Tom   |
|  1 |  20.5000 |  NULL |     4 | frank |
|  1 |  20.5000 |  NULL |     5 | Tom   |
|  2 |  78.6000 |     4 |     4 | frank |
|  2 |  78.6000 |     4 |     5 | Tom   |
|  3 |  99.9000 |  NULL |     4 | frank |
|  3 |  99.9000 |  NULL |     5 | Tom   |
|  4 | 748.4000 |     4 |     4 | frank |
|  4 | 748.4000 |     4 |     5 | Tom   |
|  5 | 748.4000 |  NULL |     4 | frank |
|  5 | 748.4000 |  NULL |     5 | Tom   |
|  6 | 999.0000 |     5 |     4 | frank |
|  6 | 999.0000 |     5 |     5 | Tom   |
|  7 | 345.0000 |     4 |     4 | frank |
|  7 | 345.0000 |     4 |     5 | Tom   |
+----+----------+-------+-------+-------+
16 rows in set (0.00 sec)

可以通过交叉连接实现内连接

mysql> select id,name,money from eatery  inner join stu on stu.stuId=eatery.stuId;
+----+-------+----------+
| id | name  | money    |
+----+-------+----------+
|  0 | Tom   | 999.0000 |
|  2 | frank |  78.6000 |
|  4 | frank | 748.4000 |
|  6 | Tom   | 999.0000 |
|  7 | frank | 345.0000 |
+----+-------+----------+
5 rows in set (0.00 sec)

mysql> select eatery.id,name,eatery.money from eatery cross join stu where eatery.stuId = stu.stuId;
+----+-------+----------+
| id | name  | money    |
+----+-------+----------+
|  0 | Tom   | 999.0000 |
|  2 | frank |  78.6000 |
|  4 | frank | 748.4000 |
|  6 | Tom   | 999.0000 |
|  7 | frank | 345.0000 |
+----+-------+----------+
5 rows in set (0.00 sec)

9.7 natural join

自然连接是在两张表中寻找那些数据类型和列名都相同的字段

自动地将他们连接起来,并返回所有符合条件按的结果

mysql> select * from t_1;
+----------+----------+
| number_1 | number_2 |
+----------+----------+
|      2.1 |     2.23 |
|      2.9 |     2.78 |
|      3.0 |     3.00 |
+----------+----------+
3 rows in set (0.00 sec)

mysql> select * from t_2;
+-----------------------+
| number                |
+-----------------------+
| 9.1111111111111100000 |
+-----------------------+
1 row in set (0.00 sec)

mysql> select * from t_1 natural join t_2;
+----------+----------+-----------------------+
| number_1 | number_2 | number                |
+----------+----------+-----------------------+
|      2.1 |     2.23 | 9.1111111111111100000 |
|      2.9 |     2.78 | 9.1111111111111100000 |
|      3.0 |     3.00 | 9.1111111111111100000 |
+----------+----------+-----------------------+
3 rows in set (0.00 sec)

mysql> select * from eatery natural join stu;
+-------+----+----------+-------+
| stuId | id | money    | name  |
+-------+----+----------+-------+
|     5 |  0 | 999.0000 | Tom   |
|     4 |  2 |  78.6000 | frank |
|     4 |  4 | 748.4000 | frank |
|     5 |  6 | 999.0000 | Tom   |
|     4 |  7 | 345.0000 | frank |
+-------+----+----------+-------

9.8 无公共同名字段的自然返回笛卡尔积

mysql> select * from t_1 natural join t_5;
+----------+----------+--------+
| number_1 | number_2 | gender |
+----------+----------+--------+
|      2.1 |     2.23 | man    |
|      2.9 |     2.78 | man    |
|      3.0 |     3.00 | man    |
|      2.1 |     2.23 | woman  |
|      2.9 |     2.78 | woman  |
|      3.0 |     3.00 | woman  |
+----------+----------+--------+
6 rows in set (0.00 sec)

9.9 using

using相当于join操作中的on

根据id字段关联,以下命令的等价的,注意使用using时前面不要加on

on eatery.stuId = stu.stuId
using(stuId)
mysql> select id,money,name from eatery inner join stu on eatery.stuId = stu.stuId;
+----+----------+-------+
| id | money    | name  |
+----+----------+-------+
|  0 | 999.0000 | Tom   |
|  2 |  78.6000 | frank |
|  4 | 748.4000 | frank |
|  6 | 999.0000 | Tom   |
|  7 | 345.0000 | frank |
+----+----------+-------+
5 rows in set (0.00 sec)

mysql> select id,money,name from eatery inner join stu using(stuId);
+----+----------+-------+
| id | money    | name  |
+----+----------+-------+
|  0 | 999.0000 | Tom   |
|  2 |  78.6000 | frank |
|  4 | 748.4000 | frank |
|  6 | 999.0000 | Tom   |
|  7 | 345.0000 | frank |
+----+----------+-------+
5 rows in set (0.00 sec)

9.10 哪一个实用?

看业务需求,实际情况是把查询条件的公共字段写全,用inner join增强可读性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个MySQL多表查询的练习题: 假设有一个学生表(student)、一个课程表(course)和一个选课表(selection),表结构如下: student表: | Field | Type | Null | Key | Default | Extra | |---------|-------------|------|------|---------|----------------| | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | | gender | varchar(2) | NO | | NULL | | | age | int(11) | NO | | NULL | | | address | varchar(50) | NO | | NULL | | course表: | Field | Type | Null | Key | Default | Extra | |---------------|-------------|------|------|---------|----------------| | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | | teacher | varchar(20) | NO | | NULL | | | credit | float | NO | | NULL | | | student_count | int(11) | NO | | NULL | | selection表: | Field | Type | Null | Key | Default | Extra | |------------|-------------|------|------|---------|----------------| | id | int(11) | NO | PRI | NULL | auto_increment | | student_id | int(11) | NO | | NULL | | | course_id | int(11) | NO | | NULL | | | score | int(11) | NO | | NULL | | | selection_time | datetime | NO | | NULL | | 请完成以下查询: 1. 查询所有学生的姓名、性别和选修的课程名称。 2. 查询选修“数学”课程的学生的姓名和成绩,并按照成绩降序排序。 3. 查询每个学生选修的课程数目和平均成绩,并按照平均成绩降序排序。 4. 查询选修课程数目最多的学生的姓名和选修课程数目。 5. 查询每个选修课程的平均成绩和选修学生数目,并按照平均成绩降序排序。 6. 查询选修课程平均成绩排名前三的课程的名称和平均成绩。 7. 查询选修成绩排名前十的学生的姓名、选修课程名称和成绩。 8. 查询选修成绩在80分以上的学生的姓名、选修课程名称和成绩。 9. 查询选修“计算机”课程的学生成绩排名前三的姓名和成绩。 10. 查询选修课程成绩总分排名前三的学生的姓名和成绩总分。 (注:数据仅供练习使用。)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yeats_Liao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值