Skip to content

多表关系建立

ff808a108ccc0a570d014b5e8c110cf3_MD5

一对多

5c962d72d3d8fb0ed52fdb91155f6c3b_MD5 48b9554b67eb19889844ed12b6160832_MD5 5a50ea0dbae567621fab3e0f58337494_MD5 9c122b120a0d3036c9344909803410d9_MD5

脏数据

061e3f87fe001183bb2343b20ff66a66_MD5

外键约束

2a337bb490948fa1879cf70a8e97fad3_MD5 5ed1d8cce010dba07755546afe1a861b_MD5 注意外键约束的命名:fk开头_当前表名_键名(是一种规范) 28ef2fdf7f390d712f684ccc3493a1ae_MD5 这个标识表示它是外键了. 这样可以查看可视化界面 2ac436a0a783e52cc15cd22a1b317f6a_MD5 d5d6708b6a1b41804c7fa8ffa645e4bf_MD5 关联之后,如果违反了外键约束,那么就会报错.如删除某个还有员工的部门,就会报错.只能删除没有员工的部门.

图像化

1dc2b9e93eb891de658246b456f737c6_MD5 在这里可以删除.同样的还可以添加

缺点与逻辑外键

cb62f1e3e1947b902d9336c7ec1e1280_MD5 实际上,很多企业都禁止使用物理外键了. 42b6e2f496a761f432e482d41caa3c19_MD5 也就是说我们不要在数据里创建外键,而是应该在业务层就进行处理来保证外键约束了.

一对一

13f281cf45d36fadd16b8434cca5c8ed_MD5 本质上也是一对多.外键可以任意放在任意表里. 7e2fd3e17c7fbb65943a0afbb63b13e8_MD5 注意,我们还是建议不要使用物理建议.

多对多

e18c7334a2d22d69bd077d96e33f5dfd_MD5 图形化 6ae2806b22163be39c10d1ed3b0204f7_MD5

主表附表

在一对多的情况下,多的那些表可以认为是副表.副表的字段当中create_time和update_time是不需要的.因为其依附于主表.

多表查询

查询多张表 18eed7ab343b8c418d9a7c691adb6e35_MD5 这样会进行笛卡尔积. 570e6decf8e6ff919cbf6e1a0100096b_MD5 b9703862439d20109162374bdae7282f_MD5

有效数据

4bc1de4473d48ff66d50d5143791f7d5_MD5 这样就在笛卡尔积的基础上,过滤出有效的条目(也就是员工部门Id等于部门id的条目) 注意,如果某个员工的dept_id为null,那么是不会呈现在结果当中的.

分类

6c05dd0cc0f09bf69847aae1074b2381_MD5 abc704310cffeb41a5b132db34171ffd_MD5

内连接

需求1

b7e52af873f335140f213e3daaf9226e_MD5 注意emp.id:因为两个表都有id字段,因此我们需要加个表名. 实际上,在多表查询的时候都建议把字段加上表名.这样更规范.(即使某个字段只在某一个表中出现,我们还是建议如此) 注意,如果某个员工的dept_id为null,那么是不会呈现在结果当中的. 这是因为,内连接是取两表的交集.既然是交集,那么null自然不会出现在结果当中. c00edbe06d083d18be4663a64adb9d54_MD5 注意,inner关键字是可以省略的.

需求2

4d33a43fa8d01b64a6fb6ba30aaef786_MD5 显式处理查询条件: 1d7f2996c2f4fcc1a062a58620ddf3d7_MD5

起别名

由于有时候sql语句太过长: 3d3fdcb03f683712a441596b56d437d5_MD5 这里as可以省略.这样起别名之后,后面就能直接使用表的别名来进行处理了.(注意,起了别名之后,之前的字段名都不能用了) 这里其别名的方式和之前给字段起别名的方式是类似的. 注意,别名的作用域是整个sql语句,也就是在as之前也有别名的作用的. ed9d8c440188fef92e6e85d08366be79_MD5

外连接

9fc9815cc5a4e5688a94f957eead23e6_MD5 注意outer可以省略 表1就是左表,表2就是右表

需求1

04229aef0410307224022ada64c9a2f1_MD5 注意,这里即使是null也会加进来,因为这里不再是交集了.

需求2

41a548367dfecaf0eddf16df3c691042_MD5

需求3

a2e6ae0fd21a4108f37745b0eed5ea92_MD5 这个其实也可以变成右链接 7af07125b65015bf3521531b0e16ffdc_MD5 注意两个表是可以互换位置的. 左外连接会包含左表的所有数据,右外链接会包含右表的所有数据.左外连接更常用.甚至有时候我们会专门把右连接转化成左连接来处理.

子查询

分类

3b1e555acb756d93d9a4b3280cd88808_MD5 - 标量子查询 50ba011a80d46cd2e6df3fbd3608a6d0_MD5 - 列子查询 5538592bddd620ccc8a2d0524ef29025_MD5 - 行子查询 702b86b4ea539283e38183dd02e266ed_MD5 - 表子查询 83ec858986cdd67bdb9cb26f682157b4_MD5

要领

4982647e515f268c4ba2b1107be3f0ac_MD5

样例

标量子查询

db3e75546c0b11690d39e63d24b5200e_MD5 结果: 0a4b7ed6f41d36bdafdc36d8a8b0957f_MD5 第二步: 99d121f9533682ad21fb1daa34af9371_MD5 合并: a61936f4605ec0e7a0fc692771a9c979_MD5

  • 示例2
  • 081c028b449e22ea32c497dd8028b9b9_MD5
列子查询

3bbb60532a8146f227963c7238c48231_MD5 合并: 6d1be858fbf95278fa9c32f6db222d2d_MD5

行子查询

f9bbb541ce6630136e831ba19f9245e3_MD5 合并: 5250c0ac21c4fca693deba3dd1a8225f_MD5 由于嵌套的子查询会降低性能,因此这里两个子查询就很慢了 如何优化? 原本其实还有种写法: afd754918a4414afda658fa3dc9293b0_MD5 因此可以这样: 6f62ffa930b43e9d99df378830d07175_MD5 本质上:行子查询返回的是一个行.因此可以通过()来接受一个行

表子查询

da0cc85be21d07af5183fcf1877058c9_MD5 注意需要分组.分组之后,select后面的字段就只有分组字段和聚合函数了. 我们写的时候,可以先写select * from emp 由于要分组处理,求里面的数据:group by dept_id 然后处理select后面,看看究竟需要加什么 c764af4c50f661b1052009d46f9fcdb6_MD5 把查询结果当成一张表,然后处理.(起个别名) 95748e0253490126ef4a361693dffed7_MD5

案例

需求拆分1

我们首先定位需要哪些表: 26d833367edc11bf03fc13f23167d80d_MD5 由于我们不需要查询整张员工表或者部门表,因此,内连接.(内外连接的判断方式) 163e360215e9aabf6e4cbe23af947392_MD5 这个e.*注意一下.

需求2

3ff047fbee970233dc43d8e84ee3bf5d_MD5

需求3

b97715bb7bc82ecf6bcb4c62dda62a43_MD5 这个是怎么写出来的? 先看看每个员工在什么部门:(很常见的操作了) select * from emp e ,dept d where e.dept_id=d.id; 再按照部门分组,那么就很有结果了. 也就是说,实际上是对上面的新表进行操作.所以,使用count(*)即可. 最终: bc06bf6d5a606e14d8d98b8046c1bdf7_MD5

需求4

9673a8b2a39e0a40b3ab0b939a8b56c9_MD5

需求5

16f4114ed57eb090cb725eae9376fad4_MD5 注意,这里null也会当作一个部门来统计薪资. 31aa35464c4decd8228583979c4815dc_MD5 接下来可见tlias3