浅谈数据库联合查询

Posted zzfx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈数据库联合查询相关的知识,希望对你有一定的参考价值。

http://www.cnblogs.com/Candies/p/4142576.html

本文介绍以下内容:

LFET JOIN、RIGHT JOIN、INNER JOIN、UNION、UNION ALL、FULL JOIN等!

测试数据(以下数据未经考证,非真实有效数据,仅作为本次学习的测试数据!)

全国大学排名TOP20
No. 校名 地区
1 北京大学 北京 周其
2 大学 北京 秉林 理工
3 浙江大学 浙江 杨卫
4 复旦大学 上海 玉良
5 南京大学
6 上海交通大学 上海
7 大学 湖北 晓红
8 中国人民大学 北京 宝成
9 中科技大学 湖北 李培根 理工
10 中山大学 广 宁生
11 吉林大学 吉林 展涛
12 四川大学 四川 和平
13 北京范大学 北京 秉林
14 南开大学 天津
15 中南大学 湖南 黄伯云
16 大学
17 尔滨大学 理工
18 中国科技大学 安徽 侯建国 理工
19 西安交通大学 西 南宁
20 大学 福建 朱崇

 数据库表结构和数据SQL(使用Navicat从mysql导出):

 View Code

 利用以下SQL可以查询出以上的表格并了解表之间的关系:

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

修改部分测试数据:

SCHOOL:
BF8085E385004A5295F950F390C67476 四川大学 四川 1 12
5C354FDA736C4D189C97BEE8DDD0D0E6 山东大学 山东 1 16
-->
BF8085E385004A5295F950F390C67475 四川大学 四川 1 12
5C354FDA736C4D189C97BEE8DDD0D0E7 山东大学 山东 1 16

SCHOOLMASTER:
5496350FC7F0455A96268FC76AE11A01 陈俊 8150DCFA7F6144D6A77A109977538047 
-->
5496350FC7F0455A96268FC76AE11A01 陈俊 8150DCFA7F6144D6A77A109977538046

 继续使用以上SQL查询出高校排名:

查询结果如下表:

01 北京大学 北京 周其
02 大学 北京 秉林 理工
03 浙江大学 浙江 杨卫
04 复旦大学 上海 玉良
05 上海交通大学 上海
06 大学 湖北 晓红
07 中国人民大学 北京 宝成
08 中科技大学 湖北 李培根 理工
09 中山大学 广 宁生
10 吉林大学 吉林 展涛
11 北京范大学 北京 秉林
12 南开大学 天津
13 中南大学 湖南 黄伯云
14 尔滨大学 理工
15 中国科技大学 安徽 侯建国 理工
16 西安交通大学 西 南宁
17 大学 福建 朱崇

 

数据库中查询分为:内连接、外连接、全连接,其中外连接分为左外连接(左连接)、右外连接(右连接)。

以下练习只关注表SCHOOL和表SCHOOLMASTER之间的连接关系,不关注表SCHOOL和表SCHOOLTYPE之间的连接关系,所以表SCHOOL和表SCHOOLTYPE之间使用LEFT JOIN进行联合查询。

左外连接(左连接):

使用以上测试数据,查询所有大学的校名和校长:
SQL:

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
LEFT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

查询结果:

01 北京大学 北京 周其
02 大学 北京 秉林 理工
03 浙江大学 浙江 杨卫
04 复旦大学 上海 玉良
05 南京大学           
06 上海交通大学 上海
07 大学 湖北 晓红
08 中国人民大学 北京 宝成
09 中科技大学 湖北 李培根 理工
10 中山大学 广 宁生
11 吉林大学 吉林 展涛
12 四川大学 四川           
13 北京范大学 北京 秉林
14 南开大学 天津
15 中南大学 湖南 黄伯云
16 大学           
17 尔滨大学 理工
18 中国科技大学 安徽 侯建国 理工
19 西安交通大学 西 南宁
20 大学 福建 朱崇


左连接查询:以左表(LEFT JOIN左边的表:表SCHOOL)为主表,即使右表(LEFT JOIN右边的表:表SCHOOLMASTER)没有匹配的数据,也从左表返回所有行数据。

以上SQL还可以写成

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
LEFT OUTER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT OUTER JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

这也是左外连接简称为左连接的原因。

或者

复制代码
SELECT
    SCHOOL.SORTKEY,
    SCHOOL.SCHOOLNAME,
    SCHOOL.SCHOOLLOCATION,
    SCHOOLMASTER.NAME,
    SCHOOLTYPE.TYPENAME
FROM
    SCHOOL,
    SCHOOLMASTER,
    SCHOOLTYPE
WHERE
    SCHOOL.SCHOOLID = SCHOOLMASTER.SCHOOLID(+)
AND SCHOOL.SCHOOLTYPE = SCHOOLTYPE.TYPEID(+)
ORDER BY
    SCHOOL.SORTKEY
复制代码

以上SQL也是用了左连接,因为(+)在右侧,所以“(+)”所在位置的另一侧为连接的方向,不过这种方式已经过时了。

右外连接(右连接):

使用以上测试数据,查询所有校长管理的学校:
SQL:

复制代码
SELECT
    M.NAME,
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,    
    T.TYPENAME
FROM
    SCHOOL S
RIGHT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

查询结果:

周其 01 北京大学 北京 综合
秉林 02 大学 北京 理工
杨卫 03 浙江大学 浙江 综合
玉良 04 复旦大学 上海 综合
06 上海交通大学 上海 综合
晓红 07 大学 湖北 综合
宝成 08 中国人民大学 北京 综合
李培根 09 中科技大学 湖北 理工
宁生 10 中山大学 广
展涛 11 吉林大学 吉林 综合
秉林 13 北京范大学 北京 师范
14 南开大学 天津 综合
黄伯云 15 中南大学 湖南 综合
17 尔滨大学 黑龙江 理工
侯建国 18 中国科技大学 安徽 理工
南宁 19 西安交通大学 西 综合
朱崇 20 大学 福建
       
       
和平        

右连接查询:以右表(RIGHT JOIN右边的表:表SCHOOLMASTER)为主表,即使左表(RIGHT JOIN左边的表:表SCHOOL)没有匹配的数据,也从右表返回所有行数据。

以上SQL还可以写成

复制代码
SELECT
    M.NAME,
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,    
    T.TYPENAME
FROM
    SCHOOL S
RIGHT OUTER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

这也是右外连接简称为右连接的原因。

或者

复制代码
SELECT
        SCHOOLMASTER.NAME,
    SCHOOL.SORTKEY,
    SCHOOL.SCHOOLNAME,
    SCHOOL.SCHOOLLOCATION,    
    SCHOOLTYPE.TYPENAME
FROM
    SCHOOL,
    SCHOOLMASTER,
    SCHOOLTYPE
WHERE
    SCHOOL.SCHOOLID(+) = SCHOOLMASTER.SCHOOLID
AND SCHOOL.SCHOOLTYPE = SCHOOLTYPE.TYPEID(+)
ORDER BY
    SCHOOL.SORTKEY
复制代码

以上SQL也是用了右连接,因为(+)在左侧,所以“(+)”所在位置的另一侧为连接的方向。

学习完左连接和右连接后,比较一下以下的SQL:

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME
FROM
    SCHOOL S
LEFT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
ORDER BY
    S.SORTKEY
复制代码
复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME
FROM
    SCHOOLMASTER M
RIGHT JOIN SCHOOL S ON S.SCHOOLID = M.SCHOOLID
ORDER BY
    S.SORTKEY
复制代码

运行以上两句SQL后,发现查询结果是一致的。虽然第一句SQL使用的是LEFT JOIN,而第二句使用的是RIGHT JOIN。

根据上文中左连接查询、右连接查询的定义:

左连接查询:以左表为主表,即使右表没有匹配的数据,也从左表返回所有行数据。
右连接查询:以右表为主表,即使左表没有匹配的数据,也从右表返回所有行数据。

分析以上两句SQL。

第一句(LEFT JOIN):因为使用了左连接查询,所以以左表SCHOOL为主表,返回查询结果;

第二句(RITHT JOIN):因为使用了右连接查询,所以以右表SCHOOL为主表,返回查询结果。

所以主表为同一数据表,查询结果相同。

也就是说在软件开发过程中,针对某一功能需求,使用左连接查询或者右连接查询以及其他查询都是可以的,只要查询结果正确即可。

同时,也可以用多种查询方式检查SQL的正确性。

左连接查询、右连接查询等各种查询方式并没有错误,只要符合功能需求即可。这一观点在后文以及以后的工作中也会得到证实。

内连接查询:

使用以上测试数据,查询所有学校和校长,特别指出的是,没有校长的学校、没有领导学校的校长不要显示:

SQL:

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

查询结果:

01 北京大学 北京 周其 综合
02 大学 北京 顾秉林 理工
03 浙江大学 浙江 杨卫 综合
04 复旦大学 上海 杨玉良 综合
06 上海交通大学 上海 综合
07 大学 湖北 李晓红 综合
08 中国人民大学 北京 宝成 综合
09 中科技大学 湖北 李培根 理工
10 中山大学 广 宁生 综合
11 吉林大学 吉林 展涛 综合
13 北京范大学 北京 秉林 师范
14 南开大学 天津 综合
15 中南大学 湖南 黄伯云 综合
17 尔滨大学 王树国 理工
18 中国科技大学 安徽 侯建国 理工
19 西安交通大学 西 郑南宁 综合
20 大学 福建 朱崇 综合

内连接查询:如果表中有至少一个匹配,则返回行数据。

以上SQL还可以写成

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
INNER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
INNER JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

也就是说INNER JOIN 等同于 JOIN,为了方便起见,一般直接使用JOIN。

UNION、UNION ALL:

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

SQL:

复制代码
(
    SELECT
        S.SCHOOLID ID,
        S.SCHOOLNAME NAME
    FROM
        SCHOOL S
)
UNION
(
    SELECT
        M . ID ID,
        M . NAME NAME
    FROM
        SCHOOLMASTER M
)
UNION
(
    SELECT
        TYPEID ID,
        TYPENAME NAME
    FROM
        SCHOOLTYPE
)
复制代码

查询结果:

0BAEEEBEE1A444EAA33FF61652F80F73 吉林大学
0C0D5616B55E42139242625E58C2D389 中国科技大学
1
12276D26BC4F4197B42D950681F924AB 浙江大学
2 理工
292812F98C394CB5846CFA1448094A24 尔滨大学
2B849F065600462C8D45BC2E781301F2 中科技大学
2BE4929EBA0D4AB983B2279D3C12711D 李培根
3 师范
339616FE14BE4D3282C3AA1BCDD18155 宝成
4 其他
40280309A8784F68ACB786E5B5DE556A 复旦大学
415F43C2F25C4A26BDEADBA1668E8177 宁生
44E4F771356C465DB02AD54A01C2ABDE 上海交通大学
49FBE5183F5A43E4B975B654A3399F61
4A3763D5528B49C299489C151620CD19 大学
4D5FD475D8204070B49944A01DB6F768 展涛
5496350FC7F0455A96268FC76AE11A01
54D90CFD0F104EFCB299D5098BF99386 中山大学
5C354FDA736C4D189C97BEE8DDD0D0E6 大学
5C5E20AEE6B44F9E8042010FB833E2E4 秉林
5FD7213082F14FA9A34B59CA614F6CFA 杨卫
8150DCFA7F6144D6A77A109977538047 南京大学
89381DEB8AFA482B9769DF8F024F04B2
8A17B2CC81B64DF78CCE0D75E21BF77B 中南大学
921BA4BC616244C68AE017BE623EE33A 南宁
977A97CC47C4482BA9A9359AAC4CEF66 大学
9E57F240DF0B4F57BBC20D0FE1CA118C 黄伯云
ACC1B581908D49538DF97E06D15B9EEB 玉良
B45EA8CDE6554555921B7D293BAC36F2 北京范大学
B4E99F17053B4DD9BFF4EA27D3DB9F6B 周其
BF8085E385004A5295F950F390C67476 四川大学
C15BD0AB3EF4468A96557A870293BA88 北京大学
C50259B9240F4C88B38B954575079343 西安交通大学
CA9525B7E1AA41C984E26DEA95381FD9 晓红
CC463BB9D6CB4D2DA8B1687A1138E73E
D1993E4EEB9A4017BA2D46E0EA16D1C6
D27B3A5FB8AA489A987D14288871CC6E 中国人民大学
D49DF755223C442EA99449193D98A465 和平
D49EC73FA4D3470B8F355812B0BD4CA3 朱崇
D4D879DAF2E14E6DA129EC8E46F1E5D4 南开大学
DD0C1777563B49E7B4E98FCBC3A77E0D 侯建国
FA4CE2FB3B264F0A8BFB55B638D46BC1 秉林
FCBB60720A9749B1AE72CBE5BE388E22 大学

以上SQL仅仅为了说明UNION的功能,没有具体意义。

当列数据有重复时,UNION只能查询出一条记录,这时候就需要使用UNION ALL进行查询。

全连接查询:

SQL:

复制代码
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
FULL JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
复制代码

查询结果:

01 北京大学 北京 周其 综合
02 大学 北京 顾秉林 理工
03 浙江大学 浙江 杨卫 综合
04 复旦大学 上海 杨玉良 综合
05 南京大学   综合
06 上海交通大学 上海 张杰 综合
07 武汉大学 湖北 李晓红 综合
08 中国人民大学 北京 纪宝成 综合
09 华中科技大学 湖北 李培根 理工
10 中山大学 广 许宁生 综合
11 吉林大学 吉林 展涛 综合
12 四川大学 四川   综合
13 北京师范大学 北京 钟秉林 师范
14 南开大学 天津 龚克 综合
15 中南大学 湖南 黄伯云 综合
16 大学 山东   综合
17 尔滨大学 理工
18 中国科技大学 安徽 侯建国 理工
19 西安交通大学 陕西 郑南宁 综合
20 大学 福建 朱崇 综合
      和平  
       
       

 

全连接查询:只要其中某个表存在匹配,就返回行数据。

以上是关于浅谈数据库联合查询的主要内容,如果未能解决你的问题,请参考以下文章

浅谈!SQL语句中LEFT JOIN ON WHERE和LEFT JOIN ON AND的区别

浅谈 T-SQL高级查询

尽管未使用接口或联合,但 readFragment 导致 IntrospectionFragmentMatcher 错误

浅谈联合注入

恒源云(GpuShare)_表序编码器的联合实体和关系提取(论文浅谈)

恒源云(GpuShare)_表序编码器的联合实体和关系提取(论文浅谈)