[MySQL]多表关联查询技巧
示例表A:
| author_id | author_name |
| 1 | Kimmy |
| 2 | Abel |
| 3 | Bill |
| 4 | Berton |
示例表B:
| book_id | author_id | start_date | end_date |
| 9 | 1 | 2017-09-25 21:16:04 | 2017-09-25 21:16:06 |
| 10 | 3 | ||
| 11 | 2 | 2017-09-25 21:21:46 | 2017-09-25 21:21:47 |
| 12 | 1 | ||
| 13 | 8 |
示例表C:
| order_id | book_id | price | order_date |
| 1 | 9 | 0.2 | 2017-09-24 21:21:46 |
| 2 | 9 | 0.6 | 2017-09-25 21:16:04 |
| 3 | 11 | 0.1 | 2017-09-25 21:21:46 |
在以上表中执行AB表关联
SELECT `authors`.*, `books`.book_id FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
结果
| author_id | author_name | book_id |
| 1 | Kimmy | 9 |
| 3 | Bill | 10 |
| 2 | Abel | 11 |
| 1 | Kimmy | 12 |
| 4 | Berton |
结果出现了2条author_id为1的记录,因为右表中存在了两条关联author_id=1的行
右边出现N条关联左边的记录,结果就会相应出现N条关联了右表出现的记录
在以上表中执行ABC表关联
SELECT `authors`.*, `books`.book_id, `orders`.order_id, `orders`.price FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id
结果
| author_id | author_name | book_id | order_id | order_price |
| 1 | Kimmy | 9 | 1 | 0.2 |
| 1 | Kimmy | 9 | 2 | 0.6 |
| 2 | Abel | 11 | 3 | 0.1 |
| 3 | Bill | 10 | ||
| 1 | Kimmy | 12 | ||
| 4 | Berton |
结果出现了3条author_id=1的记录,因为authors第一次关联了books表book_id为9和12的book关联了author_id为1的作者,而book_id为9的书本则关联了两个orders记录,所以结果集包含3条author_id为1的记录

可以运用
count(),sum()
等函数通过
group by
来统计结果
SELECT `authors`.*, sum(`orders`.price) FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id
GROUP BY `books`.book_id
结果集会基于book_id来统计每一本书的订单总额
| author_id | author_name | book_id | sum(order_price) |
| 4 | Berton | ||
| 1 | Kimmy | 9 | 0.80 |
| 3 | Bill | 10 | |
| 2 | Abel | 11 | 0.10 |
| 1 | Kimmy | 12 |
book_id为9的订单总额为0.80,并且9的记录从多条合并为1条。
多条件join
SELECT `authors`.*, `books`.book_id, `orders`.order_id, sum(`orders`.price) FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id AND `orders`.order_date >= `books`.start_date AND `orders`.order_date <= `books`.end_date
GROUP BY `books`.book_id
选取在一定时间区间范围内的order订单,可以看到订单order_id为1的订单不再纳入book_id为9的统计当中,因为它的时间区间不符合join条件
| author_id | author_name | book_id | order_id | sum(`order`.price) |
| 4 | Berton | |||
| 1 | Kimmy | 9 | 2 | 0.60 |
| 3 | Bill | 10 | ||
| 2 | Abel | 11 | 3 | 0.10 |
| 1 | Kimmy | 12 |
关于where的使用,看下面示范
SELECT `authors`.*, `books`.book_id, `orders`.order_id, sum(`orders`.price) AS prices FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id AND `orders`.order_date >= `books`.start_date AND `orders`.order_date <= `books`.end_date
WHERE prices is not NULL
GROUP BY `books`.book_id
以上语句假设选取price不为空的记录,导致了一个错误的出现
[Err] 1054 - Unknown column 'prices' in 'where clause'
因为where不能用于选取列的AS别名判断,MYSQL的处理机制是先进行选取,再进行筛选,在选取阶段就启用了where条件,因为这时并不存在prices的筛选结果后才产生的字段,所以这里会抛出错误
我们可以这样做
SELECT `authors`.*, `books`.book_id, `orders`.order_id, sum(`orders`.price) AS prices FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id AND `orders`.order_date >= `books`.start_date AND `orders`.order_date <= `books`.end_date
WHERE `orders`.price is not NULL
GROUP BY `books`.book_id
选取阶段order表是存在price字段的,所以只有price不为空的记录才会被选取
| author_id | author_name | book_id | order_id | prices |
| 2 | Abel | 11 | 3 | 0.10 |
| 1 | Kimmy | 9 | 2 | 0.60 |
运用
having
对那些无法进行 WHERE 的AS别名的字段进行一些筛选查询
SELECT `authors`.*, `books`.book_id, sum(`orders`.price)AS prices FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id
GROUP BY `books`.book_id
HAVING prices > 0.1
这时只有sum为0.8的结果被选中
| author_id | author_name | book_id | sum(order_price) |
| 1 | Kimmy | 9 | 0.80 |
对于组合其他语法查询,也是没问题的
SELECT `authors`.*, `books`.book_id, sum(`orders`.price)AS prices FROM `authors`
LEFT JOIN `books` ON `authors`.author_id = `books`.author_id
LEFT JOIN `orders` ON `books`.book_id = `orders`.book_id
GROUP BY `books`.book_id
HAVING prices >= 0.1
ORDER BY prices asc
LIMIT 1,1
[MySQL]多表关联查询技巧的更多相关文章
- MySQL多表关联查询数量
//多表关联查询数量select user, t1.count1, t2.count2from user tleft join ( select user_id, count(sport_type) ...
- JDBC MySQL 多表关联查询查询
public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...
- MySQL多表关联查询与存储过程
-- **************关联查询(多表查询)**************** -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 1.1 交叉连接查询(不推荐.产生笛卡尔乘积 ...
- mysql 多表关联查询
多个表右链接查询 名字,学校名称,学校类型,城市名称,国家地区 左链接查询 子查询 索引 #创建MySQL时添加索引 mysql> create table userIndex( id int ...
- 面试官:为什么mysql不建议执行超过3表以上的多表关联查询?
概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort ...
- MyBatis 中两表关联查询MYSQL (14)
MyBatis 中两表关联查询MYSQL 1.创建数据库表语句 2.插入测试数据 3.pom文件内容 <?xml version="1.0" encoding="U ...
- SpringBoot12 QueryDSL02之利用QueryDSL实现多表关联查询
1 业务需求 有的系统业务逻辑比较复杂,存在着多表关联查询的的情况,查询的内容不仅仅是单张表的的内容而是多张表的字段组合而成的,直接使用SplringDataJPA实现是比较复杂的,但是如果使用Que ...
- MySQL如何执行关联查询
MySQL中‘关联(join)’ 一词包含的意义比一般意义上理解的要更广泛.总的来说,MySQL认为任何一个查询都是一次‘关联’ --并不仅仅是一个查询需要到两个表的匹配才叫关联,索引在MySQL中, ...
- JAVA入门[9]-mybatis多表关联查询
概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入 ...
随机推荐
- Objects类的静态方法
提供了几个静态方法,比如进行对象之间的比较等,而又因为Object是任何对象的超类,因为每个对象都可以调用这几个方法. 1.equals方法 可以防止空指针异常 String s1 = null; S ...
- 细说shiro之七:缓存
官网:https://shiro.apache.org/ 一. 概述 Shiro作为一个开源的权限框架,其组件化的设计思想使得开发者可以根据具体业务场景灵活地实现权限管理方案,权限粒度的控制非常方便. ...
- Kudu系列-基础
Apache Kudu 支持Insert/Update/Delete 等写操作(Kudu 随机写效率也很高, 实测对一个窄表做全字段update, 其速度达到了Insert速度的88%, 而verti ...
- Java集合操作精华总结
一.Set1.HashSet boolean add(E e) 添加 访问 boolean remove(E e) 删除 Iterator<E> iterator 遍历 int size( ...
- SpringBoot入门笔记(一)、HelloWorld
本文是一篇SprintBoot学习入门笔记 1.打开Eclipse,版本为Oxygen 4.7.0 2.新建项目NewProject->MavenProject->Next->Nex ...
- Java8新特性_日期时间新类 LocalDate、LocalTime、LocalDateTime
import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeForma ...
- 【bzoj 2527】[Poi2011]Meteors
Description Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby gala ...
- 'webpack'提示 不是内部或外部命令
使用webpack命令行,报错:'webpack' 不是内部或外部命令,也不是可运行的程序 或批处理文件. 解决办法: 卸载nodejs,按照默认设置从新安装一遍 Nodejs 转载:https:// ...
- wordpress网站分类目录怎么排序
1.插件实现分类目录排序.安装插件My Category Order 启用插件,在控制面板的文章菜单下就出现如下图所示的目录调整选项,可以用鼠标随意拖曳调整目录排列顺序. 2.修改代码完成wordpr ...
- cpp #,##
#define语句中的#是把参数字符串化,##是连接两个参数成为一个整体. #define FACTORY_REF(name) { #name, Make##name } 中#name就是将传入的na ...