mysql数据库外连_数据库外连接及MySQL实现
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实现相关推荐
- c语言连接数据库例子,c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual help).doc...
这是精心收集的精品经典资料,值得下载保存阅读! c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual h ...
- mysql select符合查询_数据库select group by 和having语句 多表连接查询 复合查询
1.SELECT --group by 子句 group by子句按照指定的列column_name对表数据进行分组 group by 后面跟的列也叫分组特性列 使用group by后,能选择的列 ...
- 阿里云mysql本地可以连接数据库_本地电脑连接阿里云服务器上搭建的MySQL数据库...
一.前言 在上一篇博客:在CentOS 7 下安装mysql5.7 我们在阿里云服务器上安装好了MySQL 5.7.那么怎样可以使我们在本地的 navicat for MySQL工具上连接并进行数据库 ...
- apch连接mysql数据库连接_配置phpmyadmin连接远程 MySQL数据库
Mysql 服务器上面安装mysql yum -y install mysql mysql-devel mysql-server mysql-* 首次安装后,执行 #mysql 后,执行修改密码操作 ...
- 本地连接linux mysql数据库_在本地连接远程MySQL数据库(Linux)
尝试了两种在本地连接远程 MySQL 数据库的方式,一种是在本地使用 cmd 进行连接,还有一种就是使用 MySQL 的可视化工具 Navicate for MySQL 进行连接 一.对远程 MySQ ...
- MySQL获取数据库连接对象_利用JDBC连接mysql数据库,获取连接对象的通用格式
String driverName="com.mysql.jdbc.Driver"; //驱动程序名 String userName="root" ...
- mysql root远程访问权限_解决Navicat连接MySQL数据库报错问题
今天在用Navicat连接一台虚拟机上的MySQL时报错: Host is not allowed to connect to this MySQL server 虚拟机中的MySQL是通过PHPSt ...
- 【MySQL 第10章_数据库的设计规范】
第10章_数据库的设计规范 1. 为什么需要数据库设计 2.范式 2.1范式简介 2.2范式都包括哪些 2.3 键和相关属性的概念 2.4第一范式(1st NF) 2.5 第二范式(2nd NF) 2 ...
- mysql text 查询速度_数据库学习之让索引加快查询速度(四)
数据库学习之让索引加快查询速度 目录 索引简介 mysql的索引分类 创建索引 添加与删除索引 索引简介 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构. ...
- MySQL删除空值语句_数据库语句sql 删除空记录
最简单删除SQL Server中所有数据的方法 原文:最简单删除SQL Server中所有数据的方法 最简单删除SQL Server中所有数据的方法 编写人:CC阿爸 2014-3-14 其实 ...
最新文章
- python操作文件open_python:open/文件操作
- 小米6关闭位置服务器,关闭这6个设置,让你的小米手机从回青春,再战3年
- Webpack入门教程三
- Run tomcat 5.5 in windows server 2003 x64
- go 语言系列(二)基本数据类型和操作符
- 如何找到odata服务实现的具体backend 系统
- java编写斐波那契数列,实战案例
- 深入理解了MySQL,你才能说熟悉数据库
- 前端学习(2742):重读vue电商网站52之路由懒加载
- Java8————日期时间 API
- 你准备好了吗,he is coming
- NSMapTable、NSHashTable与NSPointerArray的封装
- 基于PHP实现高性能敏感词过滤算法
- druid数据库连接池 数据库配置密码加密
- 字体反爬-起点网月票榜案例
- C++生成0到1之间的随机数
- 白嫖党最爱!撸了郭霖大神写的Framework源码笔记,最强技术实现
- 如何解除任务管理器被禁用
- LeetCode.黑白方格画
- 计算机桌面怎么全屏显示,电脑显示器如何设置全屏 把电脑屏幕调成满屏的方法有哪些...