MySQL查询分为内连接查询和外连接查询,他们的区别在于:内连接查询的两个表示对等关系,根据条件进行匹配;外连接是以某一个表为主,两一个表根据条件进行关联。外连接分为左外连接、右外连接和全外连接。本文重点介绍各外连接的思想,以及如何实现全外连接,并举例。

左外连接

左外连接以左边表为基础,根据条件,将右边表附属到左边表,语法:SELECT * FROM A LEFT JOIN B ON condition。几何图形关系如下图,即查询结果集除了A表所有数据外,还包含满足条件的B表数据:

右外连接

右外连接以右边表为基础,根据条件,将左边表附属到右边表,语法:SELECT * FROM A RIGHT JOIN B ON condition。几何图形关系如下图,即查询结果集除了B表所有数据外,还包含满足条件的A表数据:

全外连接

全外连接是除了能够根据条件匹配得到的数据,还包含左右两表中都不匹配的数据(默认应为null),应用全外连接的情况一般都有一个联系左右两表的主线。几何关系如下图所示,对应A和B的并集(去重):

但不幸的是MySQL不支持全外连接,那在需要全外连接查询的情况下,如何实现呢?最常见的是左连接与右连接合并。

实例

项目中存在这样的场景:某项任务task具有2种不同的状态todo和done,分别存储在todolist和donelist表中,任务存储在task表中,现在需要统计每个task的已处理和未处理情况。首先先到了全外连接,那么如何实现呢?

举例实现表结构如下:

实现四种方法:

1、左连接,右连接,合并;(需保持两个结果集结构一致)

首先是左连接:

1 SELECT

2 A.id ASAid,3 B.id ASBid,4 A.taskid tid5 FROM

6 (7 SELECT

8 *

9 FROM

10 todolist11 WHERE

12 todolist.user = '张三'

13 ) A14 LEFT JOIN(15 SELECT

16 *

17 FROM

18 donelist19 WHERE

20 donelist.user = '张三'

21 ) B ON A.taskid = B.taskid

查询结果:

其次是右连接(注意由于需要合并,故左右连接的结果集结构需一致):

1 SELECT

2 A.id ASAid,3 B.id ASBid,4 A.taskid tid5 FROM

6 (7 SELECT

8 *

9 FROM

10 todolist11 WHERE

12 todolist.user = '张三'

13 ) A14 RIGHT JOIN(15 SELECT

16 *

17 FROM

18 donelist19 WHERE

20 donelist.user = '张三'

21 ) B ON A.taskid = B.taskid

查询结果:

最后进行合并,并与task表进行内连接:

1 SELECT

2 SUM(IF(Aid IS NOT NULL, 1, 0)) todo,3 SUM(IF(Bid IS NOT NULL, 1, 0)) done,4 task.name5 FROM

6 (7 SELECT

8 A.id ASAid,9 B.id ASBid,10 A.taskid tid11 FROM

12 (13 SELECT

14 *

15 FROM

16 todolist17 WHERE

18 todolist.user = '张三'

19 ) A20 LEFT JOIN(21 SELECT

22 *

23 FROM

24 donelist25 WHERE

26 donelist.user = '张三'

27 ) B ON A.taskid =B.taskid28 UNION

29 SELECT

30 A.id ASAid,31 B.id ASBid,32 B.taskid tid33 FROM

34 (35 SELECT

36 *

37 FROM

38 todolist39 WHERE

40 todolist.user = '张三'

41 ) A42 RIGHT JOIN(43 SELECT

44 *

45 FROM

46 donelist47 WHERE

48 donelist.user = '张三'

49 ) B ON A.taskid =B.taskid50 ) ASAB51 INNER JOIN task ON task.id =AB.tid52 GROUP BY

53 task.name

运行结果如下表,实现全外连接:

2、A+B左连接,B-A去除左连接到A的记录,然后合并两个结果集;(需保持两个结果集结构一致)

这是另一种实现全外连接的方式,即先查询A B的左连接,然后查询B中去除左连接到A的记录,最后合并(A代表todolist,B代表donelist):

A+B左连接

1 SELECT

2 1 AStodo,3 CASE

4 WHEN B.id IS NOT NULL THEN

5 1

6 ELSE

7 0

8 END ASdone,9 A.taskid tid10 FROM

11 (12 SELECT

13 *

14 FROM

15 todolist16 WHERE

17 todolist.user = '张三'

18 ) A19 LEFT JOIN(20 SELECT

21 *

22 FROM

23 donelist24 WHERE

25 donelist.user = '张三'

26 ) B ON A.taskid = B.taskid

查询结果:

B-A去除左连接到A的记录

1 SELECT

2 0 AStodo,3 1 ASdone,4 donelist.taskid tid5 FROM

6 donelist7 WHERE

8 donelist.user = '张三'

9 AND NOT EXISTS(10 SELECT

11 *

12 FROM

13 todolist14 WHERE

15 todolist.taskid =donelist.taskid16 AND donelist.user = '张三'

17 AND odolist.user = donelist.user

18 )

查询结果:

合并

1 SELECT

2 SUM(AB.todo) todo,3 SUM(AB.done) done,4 task.name5 FROM

6 (7 SELECT

8 1 AStodo,9 CASE

10 WHEN B.id IS NOT NULL THEN

11 1

12 ELSE

13 0

14 END ASdone,15 A.taskid tid16 FROM

17 (18 SELECT

19 *

20 FROM

21 todolist22 WHERE

23 todolist.user = '张三'

24 ) A25 LEFT JOIN(26 SELECT

27 *

28 FROM

29 donelist30 WHERE

31 donelist.user = '张三'

32 ) B ON A.taskid =B.taskid33 UNION

34 SELECT

35 0 AStodo,36 1 ASdone,37 donelist.taskid tid38 FROM

39 donelist40 WHERE

41 donelist.user = '张三'

42 AND NOT EXISTS(43 SELECT

44 *

45 FROM

46 todolist47 WHERE

48 todolist.taskid =donelist.taskid49 AND donelist.user = '张三'

50 AND odolist.user = donelist.user

51 )52 ) AB53 INNER JOIN task ON task.id =AB.tid54 GROUP BY

55 task.name

结果同上

3、以task表为根本,将A和B表左连接,实现查询;

该方法的思想是,不管A和B表有什么关系,他们都跟作为主线的表task相关,只需要将A和B表与task表进行左连接,得到连接后的数据集,即为最后需要查询的结果集。SQL代码如下:

1 SELECT

2 SUM(AB.todo) AStodo,3 SUM(AB.done) ASdone,4 task.name5 FROM

6 (7 SELECT

8 task.name,9 CASE

10 WHEN A.id IS NULL THEN

11 0

12 ELSE

13 1

14 END AStodo,15 CASE

16 WHEN B.id IS NULL THEN

17 0

18 ELSE

19 1

20 END ASdone21 FROM

22 task23 LEFT JOIN(24 SELECT

25 *

26 FROM

27 todolist28 WHERE

29 todolist.user = '张三'

30 ) A ON A.taskid =task.id31 LEFT JOIN(32 SELECT

33 *

34 FROM

35 donelist36 WHERE

37 donelist.user = '张三'

38 ) B ON B.taskid =task.id39 WHERE

40 A.id IS NOT NULL

41 OR B.id IS NOT NULL

42 ) AB43 GROUP BY

44 task.name

查询结果同上,但这种方法存在一定的缺陷,即当主线表(task表)特别大的时候,性能会比较差。

4、A表查a状态,B表查b状态,然后合并;(需保持两个结果集结构一致)

该方法是不管A和B表的关系,现根据条件查询,然后在合并。SQL语句如下:

1 SELECT

2 SUM(A.todo) todo,3 SUM(A.done) done,4 task.name5 FROM

6 (7 SELECT

8 1todo,9 0done,10 todolist.taskid tid11 FROM

12 todolist13 WHERE

14 todolist.user = '张三'

15 UNION ALL

16 SELECT

17 0todo,18 1done,19 donelist.taskid tid20 FROM

21 donelist22 WHERE

23 donelist.user = '张三'

24 ) A25 INNER JOIN task ON task.id =A.tid26 GROUP BY

27 task.name

查询结果同上。

四种方式只是实现功能,具体性能没有考虑,待后续学习。希望看客们多提意见,共同学习。

总结:

理解左连接、右连接和全外连接的思想

四种实现全外连接效果的方法

语法上注意:UNION可以去重,UNION ALL不去重

mysql数据库外连_数据库外连接及MySQL实现相关推荐

  1. c语言连接数据库例子,c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual help).doc...

    这是精心收集的精品经典资料,值得下载保存阅读! c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual h ...

  2. mysql select符合查询_数据库select group by 和having语句 多表连接查询 复合查询

    1.SELECT --group by 子句 group by子句按照指定的列column_name对表数据进行分组 group by 后面跟的列也叫分组特性列 使用group by后,能选择的列   ...

  3. 阿里云mysql本地可以连接数据库_本地电脑连接阿里云服务器上搭建的MySQL数据库...

    一.前言 在上一篇博客:在CentOS 7 下安装mysql5.7 我们在阿里云服务器上安装好了MySQL 5.7.那么怎样可以使我们在本地的 navicat for MySQL工具上连接并进行数据库 ...

  4. apch连接mysql数据库连接_配置phpmyadmin连接远程 MySQL数据库

    Mysql 服务器上面安装mysql yum -y install mysql mysql-devel mysql-server mysql-* 首次安装后,执行 #mysql 后,执行修改密码操作 ...

  5. 本地连接linux mysql数据库_在本地连接远程MySQL数据库(Linux)

    尝试了两种在本地连接远程 MySQL 数据库的方式,一种是在本地使用 cmd 进行连接,还有一种就是使用 MySQL 的可视化工具 Navicate for MySQL 进行连接 一.对远程 MySQ ...

  6. MySQL获取数据库连接对象_利用JDBC连接mysql数据库,获取连接对象的通用格式

    String driverName="com.mysql.jdbc.Driver";        //驱动程序名 String userName="root" ...

  7. mysql root远程访问权限_解决Navicat连接MySQL数据库报错问题

    今天在用Navicat连接一台虚拟机上的MySQL时报错: Host is not allowed to connect to this MySQL server 虚拟机中的MySQL是通过PHPSt ...

  8. 【MySQL 第10章_数据库的设计规范】

    第10章_数据库的设计规范 1. 为什么需要数据库设计 2.范式 2.1范式简介 2.2范式都包括哪些 2.3 键和相关属性的概念 2.4第一范式(1st NF) 2.5 第二范式(2nd NF) 2 ...

  9. mysql text 查询速度_数据库学习之让索引加快查询速度(四)

    数据库学习之让索引加快查询速度 目录 索引简介 mysql的索引分类 创建索引 添加与删除索引 索引简介 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构. ...

  10. MySQL删除空值语句_数据库语句sql 删除空记录

    最简单删除SQL Server中所有数据的方法 原文:最简单删除SQL Server中所有数据的方法 最简单删除SQL Server中所有数据的方法   编写人:CC阿爸   2014-3-14 其实 ...

最新文章

  1. python操作文件open_python:open/文件操作
  2. 小米6关闭位置服务器,关闭这6个设置,让你的小米手机从回青春,再战3年
  3. Webpack入门教程三
  4. Run tomcat 5.5 in windows server 2003 x64
  5. go 语言系列(二)基本数据类型和操作符
  6. 如何找到odata服务实现的具体backend 系统
  7. java编写斐波那契数列,实战案例
  8. 深入理解了MySQL,你才能说熟悉数据库
  9. 前端学习(2742):重读vue电商网站52之路由懒加载
  10. Java8————日期时间 API
  11. 你准备好了吗,he is coming
  12. NSMapTable、NSHashTable与NSPointerArray的封装
  13. 基于PHP实现高性能敏感词过滤算法
  14. druid数据库连接池 数据库配置密码加密
  15. 字体反爬-起点网月票榜案例
  16. C++生成0到1之间的随机数
  17. 白嫖党最爱!撸了郭霖大神写的Framework源码笔记,最强技术实现
  18. 如何解除任务管理器被禁用
  19. LeetCode.黑白方格画
  20. 计算机桌面怎么全屏显示,电脑显示器如何设置全屏 把电脑屏幕调成满屏的方法有哪些...

热门文章

  1. electron设置淘宝镜像
  2. 纯代码开发c# ui_UI代码挑战#1-心跳
  3. 蓝蓝算法06--输出链表中倒数第k个结点
  4. 实验十二、十三 配置PPP协议、配置Frame-relay协议
  5. python3打印金字塔_python3 练习题100例 (二十五)打印一个n层金字塔
  6. R、RStudio下载与安装方法
  7. Python爬虫案例:爬取携程评论
  8. xlsx 导出导入excel,xlsx-style 修改excel样式
  9. 痘痘长在不同位置代表什么?
  10. BeatSaber节奏光剑插件开发官方教程1-创建一个插件模板