博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL必知必会 -- 联结表
阅读量:4204 次
发布时间:2019-05-26

本文共 5020 字,大约阅读时间需要 16 分钟。

  • 外键(foreign key) 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。

使用联结表的优点:

  • 信息不重复,从而不浪费时间和空间;
  • 如果信息变动,可以只更新表中的单个记录,相关表中的数据不用改动;
  • 由于数据无重复,显然数据是一致的,这使得处理数据更简单。

联结表的使用

MariaDB [test]> select * from users;+-------+--------+------+------+-------+------------+-------+| user  | passwd | sex  | age  | price | math_price | class |+-------+--------+------+------+-------+------------+-------+| user2 | 222    | girl | 23   | 155   | 36         |     1 || user3 | 333    | boy  | 12   | 78    | 66         |     1 || user4 | 444    | boy  | 22   | NULL  | NULL       |     2 || user5 | 555    | boy  | 30   | NULL  | 43         |     2 || user1 | 111    | boy  | 18   | 35    | 88         |     1 || user6 | 666    | girl | 16   | 35    | 43         |     2 |+-------+--------+------+------+-------+------------+-------+6 rows in set (0.01 sec)MariaDB [test]> select * from hour;+-------+-------+| hours | user  |+-------+-------+|    12 | user2 ||     8 | user6 ||     9 | user1 ||    11 | user3 ||    10 | user4 ||    10 | user5 |+-------+-------+6 rows in set (0.00 sec)MariaDB [test]> select class,sex,hours from users,hour where hour.user = users.user order by class;+-------+------+-------+| class | sex  | hours |+-------+------+-------+|     1 | boy  |    11 ||     1 | girl |    12 ||     1 | boy  |     9 ||     2 | boy  |    10 ||     2 | boy  |    10 ||     2 | girl |     8 |+-------+------+-------+6 rows in set (0.00 sec)

这里所指定的两个列(class,sex)在users表中,而另一个列(hours)在 hour表中。这两个表用WHERE子句正确联结,WHERE 就是他们的联结条件.

没有联结条件的表关系返回的结果为笛卡儿积。

检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。

内联结

对于上面的查询语句,我们可以用内联结的方式表示:

在这里插入图片描述
这里使用innor join 的方式联结,用 ON 进行筛选。

多表联结

SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。

首先列出所有表,然后定义表之间的关系。
在这里插入图片描述

创建高级联结

使用表别名

MariaDB [test]> select  u.class,u.sex,h.hours from users as u,hour as h where u.user = h.user;+-------+------+-------+| class | sex  | hours |+-------+------+-------+|     1 | girl |    12 ||     2 | girl |     8 ||     1 | boy  |     9 ||     1 | boy  |    11 ||     2 | boy  |    10 ||     2 | boy  |    10 |+-------+------+-------+6 rows in set (0.00 sec)

这种方式可以缩短SQL语句;并允许在单条SELECT语句中多次使用相同的表

使用不同类型的联结

自联结

一直有一位同学请假,找出同一班中其他的同学是否请假,我们首先要找出这个班的其他同学;

ariaDB [test]> select user,sex,math_price from users where class = (select class from users where user = 'user1');+-------+------+------------+| user  | sex  | math_price |+-------+------+------------+| user2 | girl | 36         || user3 | boy  | 66         || user1 | boy  | 88         |+-------+------+------------+3 rows in set (0.00 sec)

这是第一种解决方案,它使用了子查询,那么我们是用自联结如何解决。

MariaDB [test]> select u1.user,u1.sex,u1.math_price 				from users as u1,users as u2 				where u1.class = u2.class and u2.user =  'user1';-------+------+------------+| user  | sex  | math_price |+-------+------+------------+| user2 | girl | 36         || user3 | boy  | 66         || user1 | boy  | 88         |+-------+------+------------+3 rows in set (0.01 sec)

通常情况下使用自联结的查询速率比使用子查询的速率要快。

自然连接

无论何时对表进行联结,应该至少有一个列出现在不止一个表中(被联结的列)。标准的联结(前一章中介绍的内部联结)返回所有数据,甚至相同的列多次出现。自然联结排除多次出现,使每个列只返回一次。

这项工作,由自己完成。自然联结是这样一种联结,其中你只能选择那些唯一的列。
这一般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集来完成的。

外联结

MariaDB [test]> select * from hour;+-------+-------+| hours | user  |+-------+-------+|    12 | user2 ||     8 | user6 ||     9 | user1 ||    11 | user3 ||    10 | user4 ||    10 | user5 ||    11 | NULL  |+-------+-------+7 rows in set (0.00 sec)MariaDB [test]> select * from users;+-------+--------+------+------+-------+------------+-------+| user  | passwd | sex  | age  | price | math_price | class |+-------+--------+------+------+-------+------------+-------+| user2 | 222    | girl | 23   | 155   | 36         |     1 || user3 | 333    | boy  | 12   | 78    | 66         |     1 || user4 | 444    | boy  | 22   | NULL  | NULL       |     2 || user5 | 555    | boy  | 30   | NULL  | 43         |     2 || user1 | 111    | boy  | 18   | 35    | 88         |     1 || user6 | 666    | girl | 16   | 35    | 43         |     2 || user7 | 777    | boy  | NULL | NULL  | NULL       |  NULL |+-------+--------+------+------+-------+------------+-------+7 rows in set (0.00 sec)MariaDB [test]> select users.user,hour.hours from users left join hour on users.user = hour.user;+-------+-------+| user  | hours |+-------+-------+| user2 |    12 || user6 |     8 || user1 |     9 || user3 |    11 || user4 |    10 || user5 |    10 || user7 |  NULL |+-------+-------+7 rows in set (0.00 sec)MariaDB [test]> select users.user,hour.hours from users right join hour on users.user = hour.user;+-------+-------+| user  | hours |+-------+-------+| user2 |    12 || user3 |    11 || user4 |    10 || user5 |    10 || user1 |     9 || user6 |     8 || NULL  |    11 |+-------+-------+7 rows in set (0.00 sec)

使用了关键字OUTER JOIN来指定联结的类型,outer 可以省略,并且必须加上 LEFT 或RIGHT 指明方向。

左联结会打印出左边表的所有行,二右联结会打印出右边表的所有行。

使用带聚集函数的联结

如果要检索所有客户及每个客户所下的订单数,下面使用了COUNT()函数的代码可完成此工作:

在这里插入图片描述

使用联结和联结条件

  • 注意所使用的联结类型。一般我们使用内部联结,但使用外部联结也是有效的。
  • 保证使用正确的联结条件,否则将返回不正确的数据。
  • 应该总是提供联结条件,否则会得出笛卡儿积。
  • 在一个联结中可以包含多个表,甚至对于每个联结可以采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们前,分别测试每个联结。这将使故障排除更为简单。

转载地址:http://yyxli.baihongyu.com/

你可能感兴趣的文章
MySQL必知必会 -- 数据汇总
查看>>
MySQL必知必会 -- 子查询的使用
查看>>
POJ 3087 解题报告
查看>>
POJ 2536 解题报告
查看>>
POJ 1154 解题报告
查看>>
POJ 1661 解题报告
查看>>
POJ 1101 解题报告
查看>>
ACM POJ catalogues[转载]
查看>>
ACM经历总结[转载]
查看>>
C/C++文件操作[转载]
查看>>
专业计划
查看>>
小米笔试:最大子数组乘积
查看>>
常见的排序算法
查看>>
5.PyTorch实现逻辑回归(二分类)
查看>>
6.PyTorch实现逻辑回归(多分类)
查看>>
8.Pytorch实现5层全连接结构的MNIST(手写数字识别)
查看>>
9.PyTorch实现MNIST(手写数字识别)(2卷积1全连接)
查看>>
hdu 3460 Ancient Printer(trie tree)
查看>>
中间数
查看>>
KMP求前缀函数(next数组)
查看>>