Mysql从入门到入魔——6. 表联结、组合查询

❤ 系列内容 ❤

Mysql从入门到入魔——1. 数据准备(起航篇)
Mysql从入门到入魔——2. 操纵数据库和表
Mysql从入门到入魔——3. 查询、排序、WHERE过滤
Mysql从入门到入魔——4. 通配符、计算字段、函数
Mysql从入门到入魔——5. 聚集、分组、子查询
Mysql从入门到入魔——6. 表联结、组合查询
Mysql从入门到入魔——7. 插入、更新和删除
Mysql从入门到入魔——8. 视图、存储过程、事务处理
Mysql从入门到入魔——9. 游标、高级SQL特性
Mysql从入门到入魔——10. 知识点速记(完结)


本篇主要内容

自联结、等值联结、内联结、自然联结、外联结及对比图,UNION组合查询。如果对文中表结构不理解的可以查看系列首页。话不多说,进入正题!



1. 表联结

联结是一种机制,用来在一条 SELECT 语句中关联表,因此称为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。联结不是物理实体。换句话说,它在实际的数据库表中并不存在。它只在查询执行期间存在。


1.1 自联结

假如要给与顾客联系名为 Jim Jones 的同一公司的所有顾客发送一封信件。这个查询要求首先找出 Jim Jones 工作的公司名,然后找出在该公司工作的顾客。下面使用子查询和自联结分别实现。

先看一下子查询的方式:

mysql> SELECT cust_id, cust_name, cust_contact
    -> FROM Customers
    -> WHERE cust_name = (SELECT cust_name
    ->                    FROM Customers
    ->                    WHERE cust_contact = 'Jim Jones');
+------------+-----------+--------------------+
| cust_id    | cust_name | cust_contact       |
+------------+-----------+--------------------+
| 1000000003 | Fun4All   | Jim Jones          |
| 1000000004 | Fun4All   | Denise L. Stephens |
+------------+-----------+--------------------+

接下来使用自联结的方式:

mysql> SELECT c1.cust_id, c1.cust_name, c1.cust_contact
    -> FROM Customers AS c1, Customers AS c2
    -> WHERE c1.cust_name = c2.cust_name
    ->  AND c2.cust_contact = 'Jim Jones';
+------------+-----------+--------------------+
| cust_id    | cust_name | cust_contact       |
+------------+-----------+--------------------+
| 1000000003 | Fun4All   | Jim Jones          |
| 1000000004 | Fun4All   | Denise L. Stephens |
+------------+-----------+--------------------+

通常情况下,自联结的方式比子查询的方式要快很多。


1.2 等值联结

为了各种联结的对比效果更佳,下面的示例均使用以下 table1table2 表中的数据。
两表 table1table2 中数据如下:

table1                      table2
+------+------+------+      +------+------+------+
| A    | B    | C    |      | C    | D    | E    |
+------+------+------+      +------+------+------+
|    1 |    2 |    3 |      |    2 |    3 |    4 |
|    4 |    5 |    6 |      |    6 |    7 |    8 |
+------+------+------+      +------+------+------+

现在通过等值联结,获取两个表中的数据。

mysql> SELECT *
    -> FROM table1 AS t1, table2 AS t2
    -> WHERE t1.C = t2.C;
+------+------+------+------+------+------+
| A    | B    | C    | C    | D    | E    |
+------+------+------+------+------+------+
|    4 |    5 |    6 |    6 |    7 |    8 |
+------+------+------+------+------+------+

注意:上例中WHERE 中限制了联结条件,如果没有条件的话,返回的结果就是两表的笛卡尔积,返回 6 × 9 共 54 条数据


1.3 内联结

上面的联结也可以称为内联结,它还有另一种语法。返回的结果以上面相同。

mysql> SELECT *
    -> FROM table1 AS t1 INNER JOIN table2 AS t2
    ->   ON t1.C = t2.C;
+------+------+------+------+------+------+
| A    | B    | C    | C    | D    | E    |
+------+------+------+------+------+------+
|    4 |    5 |    6 |    6 |    7 |    8 |
+------+------+------+------+------+------+

1.4 自然联结

自然连接是一种特殊的等值连接,它在两个关系表中自动比较相同的属性列,无须添加连接条件,并且在结果中消除重复的属性列。

mysql> SELECT *
    -> FROM table1 AS t1 NATURAL JOIN table2 t2;
+------+------+------+------+------+
| C    | A    | B    | D    | E    |
+------+------+------+------+------+
|    6 |    4 |    5 |    7 |    8 |
+------+------+------+------+------+

1.5 外联结

1.5.1 左外联结

左外联结,左表( table1 )的记录将会全部表示出来,而右表( table2 )只会显示符合搜索条件的记录。右表记录不足的地方均为 NULL

mysql> SELECT *
    -> FROM table1 AS t1 LEFT JOIN table2 AS t2
    ->   ON t1.C = t2.C;
+------+------+------+------+------+------+
| A    | B    | C    | C    | D    | E    |
+------+------+------+------+------+------+
|    4 |    5 |    6 |    6 |    7 |    8 |
|    1 |    2 |    3 | NULL | NULL | NULL |
+------+------+------+------+------+------+

1.5.1 右外联结

右外联结,右表( table2 )的记录将会全部表示出来,而左表( table1 )只会显示符合搜索条件的记录。左表记录不足的地方均为 NULL

mysql> SELECT *
    -> FROM table1 AS t1 RIGHT JOIN table2 AS t2
    ->  ON t1.C = t2.C;
+------+------+------+------+------+------+
| A    | B    | C    | C    | D    | E    |
+------+------+------+------+------+------+
|    4 |    5 |    6 |    6 |    7 |    8 |
| NULL | NULL | NULL |    2 |    3 |    4 |
+------+------+------+------+------+------+

1.6 四种联结对比图

内联结
自然联结(去重)
左外联结
右外联结


2. 组合查询

2.1 UNION组合查询

假如需要 IllinoisIndianaMichigan 等几个州的所有顾客的报表,还想包括不管位于哪个州的所有 Fun4All 公司的顾客。

mysql> SELECT cust_name, cust_contact, cust_email
    -> FROM Customers
    -> WHERE cust_state IN ('IL', 'IN', 'MI')
    -> UNION
    -> SELECT cust_name, cust_contact, cust_email
    -> FROM Customers
    -> WHERE cust_name = 'Fun4All';
+---------------+--------------------+-----------------------+
| cust_name     | cust_contact       | cust_email            |
+---------------+--------------------+-----------------------+
| Village Toys  | John Smith         | sales@villagetoys.com |
| Fun4All       | Jim Jones          | jjones@fun4all.com    |
| The Toy Store | Kim Howard         | NULL                  |
| Fun4All       | Denise L. Stephens | dstephens@fun4all.com |
+---------------+--------------------+-----------------------+

UNION 默认去重,单独执行两个子查询的结果相加应该有 5 行。

如果实际情况不需要去重,可以使用 UNION ALL 来实现。

mysql> SELECT cust_name, cust_contact, cust_email
    -> FROM Customers
    -> WHERE cust_state IN ('IL', 'IN', 'MI')
    -> UNION ALL
    -> SELECT cust_name, cust_contact, cust_email
    -> FROM Customers
    -> WHERE cust_name = 'Fun4All';
+---------------+--------------------+-----------------------+
| cust_name     | cust_contact       | cust_email            |
+---------------+--------------------+-----------------------+
| Village Toys  | John Smith         | sales@villagetoys.com |
| Fun4All       | Jim Jones          | jjones@fun4all.com    |
| The Toy Store | Kim Howard         | NULL                  |
| Fun4All       | Jim Jones          | jjones@fun4all.com    |
| Fun4All       | Denise L. Stephens | dstephens@fun4all.com |
+---------------+--------------------+-----------------------+

这就是本文所有的内容了,如果感觉还不错的话。❤ 点个赞再走吧!!!❤

在这里插入图片描述
后续会继续分享《Mysql从入门到入魔》系列文章,如果感兴趣的话可以点个关注不迷路哦~。

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dream丶Killer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值