示例表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]多表关联查询技巧的更多相关文章

  1. MySQL多表关联查询数量

    //多表关联查询数量select user, t1.count1, t2.count2from user tleft join ( select user_id, count(sport_type) ...

  2. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  3. MySQL多表关联查询与存储过程

    --  **************关联查询(多表查询)**************** -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 1.1 交叉连接查询(不推荐.产生笛卡尔乘积 ...

  4. mysql 多表关联查询

    多个表右链接查询 名字,学校名称,学校类型,城市名称,国家地区 左链接查询 子查询 索引 #创建MySQL时添加索引 mysql> create table userIndex( id int ...

  5. 面试官:为什么mysql不建议执行超过3表以上的多表关联查询?

    概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort ...

  6. MyBatis 中两表关联查询MYSQL (14)

    MyBatis 中两表关联查询MYSQL 1.创建数据库表语句 2.插入测试数据 3.pom文件内容 <?xml version="1.0" encoding="U ...

  7. SpringBoot12 QueryDSL02之利用QueryDSL实现多表关联查询

    1 业务需求 有的系统业务逻辑比较复杂,存在着多表关联查询的的情况,查询的内容不仅仅是单张表的的内容而是多张表的字段组合而成的,直接使用SplringDataJPA实现是比较复杂的,但是如果使用Que ...

  8. MySQL如何执行关联查询

    MySQL中‘关联(join)’ 一词包含的意义比一般意义上理解的要更广泛.总的来说,MySQL认为任何一个查询都是一次‘关联’ --并不仅仅是一个查询需要到两个表的匹配才叫关联,索引在MySQL中, ...

  9. JAVA入门[9]-mybatis多表关联查询

    概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入 ...

随机推荐

  1. 细说java系列之泛型

    什么是范型 简言之,范型是Java支持在编译期进行类型检查的机制. 这里面包含2层含义:其一,可以使用范型进行类型检查:其二,在编译期进行类型检查. 那么,什么叫做在编译期进行类型检查?可以在运行时进 ...

  2. impala系列: 时间函数

    --=======================时间函数--======================= --当前时间戳now()current_timestamp() --当前时间戳相对于 li ...

  3. 微信小程序开发(6) SSL证书及HTTPS服务器

    1. 域名 在万网购买,略 2. 云服务器 阿里云购买,略 3. 安装lnmp 使用lnmp.org程序,略 4. 申请证书 阿里云-管理控制台-安全(云盾)-证书服务-购买证书证书类型: 免费型DV ...

  4. jsp 起航 和Servlet通过attribute通信

    @WebServlet(name = "ticketServlet",urlPatterns = {"/tickets"},loadOnStartup = 1) ...

  5. php错误提示 open_basedir restriction in effect 解决

    <VirtualHost *:80> DocumentRoot "D:/www/4w_raaaa_com_2017" ServerName www.raaaa.com: ...

  6. 第20月第29天 cocoa抽象工厂 cocoapods组件化 cocoapods升级

    1. 在 Cocoa Touch 框架中,类簇是抽象工厂模式在 iOS 下的一种实现,以 NSArray 举例,将原有的 alloc+init 拆开写: id obj1 = [NSArray allo ...

  7. Python的集合和元组

    一.元组 元组也是一个list,但它的值不能改变 Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号 ...

  8. Python Django 实用小案例2

    动态导入模块 Django返回序列化数据  动态导入模块 在Django里面,经常会看到一些方法或者类是动态导入,尤其是以settings文件为代表,经常把一些类放在里面动态调配,比如随便拿Djang ...

  9. drawImg、x5浏览器、react

  10. 2017-2018-2 20165234 实验四《Android程序设计》实验报告

    一.实验报告封面 课程:Java程序设计   班级:1652   姓名:刘津甫   学号:20165234 指导教师:娄嘉鹏    实验日期:2018年5月14日 实验时间:13:45 - 3:25 ...