(转)sql多表查询,Oracle、mysql的用法区别

news/2024/7/6 1:37:50

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1.前言:上篇讲到Mysql中关键字执行的顺序,只涉及了一张表;实际应用大部分情况下,查询语句都会涉及到多张表格 :

1)多表连接有哪些分类;

2)针对这些分类有哪些连接方法?

3)这些连接方法分别作用于哪些应用场景?

这篇针对这三个点通过实例来讲述,目的是穷尽所有的场景和所有的方法,并且对每个方法的使用做实例。

首先先列举本篇用到的连接方法:

内链接:join,inner join

外连接:left join,left outer join,right join,right outer join,union

交叉连接:cross join

2.假设有两张表格A和B,把表格当作一个集合,那么表格中的记录就是集合中的一个元素。

两张表格如下:

TableA:

TableB:

 

1)分类:内连接(只有一种场景)

inner join 或者join(等同于inner join)

select a.*, b.* from tablea a  
inner join tableb b  
on a.id = b.id  

select a.*, b.* from tablea a  
join tableb b  
on a.id = b.id  

结果如下:

应用场景:

这种场景下得到的满足某一条件的是A,B内部的数据;正因为得到的是内部共有数据,所以连接方式称为内连接。

2)分类:外连接(六种场景)

A)left   join 或者left outer join(等同于left join)

select a.*, b.* from tablea a  
left join tableb b  
on a.id = b.id  

或者

select a.*, b.* from tablea a  
left outer join tableb b  
on a.id = b.id  

结果如下,TableB中更不存在的记录填充Null:

应用场景:

这种场景下得到的是A的所有数据,和满足某一条件的B的数据;

B)[left   join 或者left outer join(等同于left join)]  +  [where B.column is null]

select a.id aid,a.age,b.id bid,b.name from tablea a  
left join tableb b  
on a.id = b.id  
Where b.id is null  

 

结果如下:

应用场景:

这种场景下得到的是A中的所有数据减去 和B满足同一条件 的数据,然后得到的A剩余数据;
C)right join 或者fight outer join(等同于right join)

select a.id aid,a.age,b.id bid,b.name from tablea a  
right join tableb b  
on a.id = b.id  

结果如下,TableB中更不存在的记录填充Null:

 

应用场景:


这种场景下得到的是B的所有数据,和满足某一条件的A的数据;

D)[left   join 或者left outer join(等同于left join)]  +  [where A.column is null]

select a.id aid,a.age,b.id bid,b.name from tablea a  
right join tableb b  
on a.id = b.id  
where a.id is null  

结果如下:

 

应用场景:

这种场景下得到的是B中的所有数据减去 和A满足同一条件 的数据,然后得到的B剩余数据;
E)full join (mysql不支持,但是可以用 left join  union right join代替)

select a.id aid,a.age,b.id bid,b.name from tablea a  
left join tableb b  
on a.id = b.id  
union  
select a.id aid,a.age,b.id bid,b.name from tablea a  
right join tableb b  
on a.id = b.id  

union过后,重复的记录会合并(id为2,3,4的三条记录),所以结果如下:

 

应用场景:

这种场景下得到的是满足某一条件的公共记录,和独有的记录

F)full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+is null)代替)

select a.id aid,a.age,b.id bid,b.name from tablea a  
left join tableb b  
on a.id = b.id  
where b.id is null  
union  
select a.id aid,a.age,b.id bid,b.name from tablea a  
right join tableb b  
on a.id = b.id  
where a.id is null  

结果如下:

 

应用场景:

这种场景下得到的是A,B中不满足某一条件的记录之和

注:上面共有其中七(2^3-1)种应用场景,还有一种是全空白,那就是什么都不查,七种情形包含了实际应用所有可能的场景:

3)分类:交叉连接 (cross join)

A)实际应用中还有这样一种情形,想得到A,B记录的排列组合,即笛卡儿积,这个就不好用集合和元素来表示了。需要用到cross join:

select a.id aid,a.age,b.id bid,b.name from tablea a  
cross join tableb b  

是A记录数*B记录数,结果如下:

 


B)还可以为cross  join指定条件 (where):

select a.id aid,a.age,b.id bid,b.name from tablea a  
cross join tableb b  
where a.id = b.id  

结果如下:

 


注: 这种情况下实际上实现了内连接的效果

3.上面仍然存在遗漏,那就是mysql对sql语句的容错问题,即在sql语句不完全符合书写建议的情况,mysql会允许这种情况,尽可能解释它:

1)一般cross join后面加上where条件,但是用cross join+on也是被解释为cross join+where;

2)一般内连接都需要加上on限定条件,如上面场景一;如果不加会被解释为交叉连接;

3)如果连接表格使用的是逗号,会被解释为交叉连接;

注:sql标准中还有union join和natural  inner join,mysql不支持,而且本身也没有多大意义,其结果可以用上面的几种连接方式得到.

总结:总结了mysql所有连接方法,其中有一些是之前没有注意到的问题,平时开发也都不外乎这些。下篇总结写sql提供的函数

转载于:https://my.oschina.net/githubhty/blog/912254


http://www.niftyadmin.cn/n/4588605.html

相关文章

Linux Kernel Development -- 设置当前进程的状态

首先查看内核源码中是如何定义的 #define __set_task_state(tsk, state_value) \ do { (tsk)->state (state_value); } while (0) #define set_task_state(tsk, state_value) \ set_mb((tsk)->state, (state_value)) /* * set_current_state() includes a barrier …

4种Java解析xml

xml文件<?xml version"1.0" encoding"GB2312"?> <RESULT> <VALUE>    <NO>A1234</NO>    <ADDR>四川省…

android抓包工具

下载 http://gdown.baidu.com/data/wisegame/2158469c63492e89/Tcpzhuabao_2.apk

桌面项后就出现了阴影

设置了一个桌面项后就出现了阴影 “对着桌面单击 -属性-桌面-自定义桌面-WEB-选掉锁定了桌面项目、对着我的电脑图标单击右键-属性-高级-性能-设置-钩选在桌面上为图标标签使用阴影 ”都用过了,又不想删了桌面项怎么办? 最佳答案如果是手动误操作造成的 …

EditText会自动获取焦点并弹出输入法的问题

其实真正烦人的就是一到页面就弹出来一个输入法,输入法之所以会弹出是因为EditText获取了焦点,而让EditText获取焦点是android默认的,哪怕你没设置它获取焦点 一个解决的方法就是让别的控件获取焦点,这样EditText就不会自动获取焦…

(([0-9]+[a-zA-Z]+)这样就可以了。

(([0-9][a-zA-Z])这样就可以了。(([0-9][a-zA-Z])|([a-zA-Z][0-9])) ;^(([0-9][a-zA-Z])|([a-zA-Z][0-9]))$ ;([/d][a-zA-Z])

约翰·康威的 生命游戏

2019独角兽企业重金招聘Python工程师标准>>> 今天偶然翻阅了霍金的大设计,在第八章提到了一个生命游戏,感觉很有意思,贴在这里和大家分享下。 这个游戏是英国的数学家约翰何顿康威在1970年发明的,详情可以参见百度百科…

spket插件的安装与使用完整图文版

下载最新破解版的spket1.6.18(见下面附件) 对于目前的MyEclipse的插件安装是很简单的,把spket1.6.18破解版.zip解压后直接复制到MyEclipse安装目录的dropins文件夹下即可。如图: 安装完成后,启动MyEclipse&#xff0c…