浅谈数据库联合查询

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导出):

 

利用以下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 厦门大学 福建 朱崇实 综合
      谢和平  
      陈俊  
      徐显明  

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

时间: 2024-08-02 02:29:13

浅谈数据库联合查询的相关文章

浅谈数据库设计技巧(转)

说到数据库,我认为不能不先谈数据结构.1996年,在我初入大学学习计算机编程时,当时的老师就告诉我们说:计算机程序=数据结构+算法.尽管现在的程序开发已由面向过程为主逐步过渡到面向对象为主,但我还是深深赞同8年前老师的告诉我们的公式:计算机程序=数据结构+算法.面向对象的程序开发,要做的第一件事就是,先分析整个程序中需处理的数据,从中提取出抽象模板,以这个抽象模板设计类,再在其中逐步添加处理其数据的函数(即算法),最后,再给类中的数据成员和函数划分访问权限,从而实现封装. 数据库的最初雏形据说源

浅谈数据库设计

浅谈数据库设计 数据库设计的重要性:好的数据库设计有下面的一些作用: 1.首先充分体现系统的需求,数据库是为应用服务的,好的数据库设计应该首先能满足应用系统的业务需求,准确的表达数据间关系. 2.保证数据的准确性和一致性,通过主外键.非空.限制.唯一索引等保证数据的健壮. 3.提高数据的查询效率,通过合理表结构,安排物理存储分区.增加索引等方式,提高数据的读取速度,提高查询效率. 4.有好的扩展性,在必要时能根据需求扩展数据结构. 在系统设计中对数据库的设计应考虑哪些设计原则  数据库是整个软件

浅谈数据库之存储过程

浅谈数据库之存储过程 什么是存储过程 如果你接触过其他的编程语言,那么就好理解了,存储过程就像是方法一样. 竟然他是方法那么他就有类似的方法名,方法要传递的变量和返回结果,所以存储过程有存储过程名有存储过程参数也有返回值. 存储过程的优点:    存储过程的能力大大增强了SQL语言的功能和灵活性. 可保证数据的安全性和完整性. 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全. 通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性. 在运行存储过程前,

浅谈数据库框架,见笑,请多指正

浅谈数据库框架,见笑,请多指正 http://weibo.com/p/1001603724746155003486 一友说"插件式存储又割裂了SQL引擎的完整逻辑...总体而言在现有框架下MySQL的优化器没有多大改进的价值". 我们且做个技术分析: 1 插件式框架,可以静态/动态加载组件,方便在同类不同属家的模块间切换,这种设计是良好的. 很多软件的设计都采用了"微内核+插件"这样的方式构筑了强大的应用.如Ecplise生态圈. 2 数据库范围内, MySQL的属

浅谈数据库去重

关于sql去重,我简单谈一下自己的简介,如果各位有建议或有不明白的欢迎多多指出.推荐网址:www.4-yecao.com 关于sql去重最常见的有两种方式:DISTINCT和ROW_NUMBER(),当然了ROW_NUMBER()除了去重还有很多其他比较重要的功能,一会我给大家简单说说我自己在实际中用到的. 假如有张UserInfo表,如下图: 现在我们要去掉完全重复的数据:SELECT DISTINCT * FROM dbo.UserInfo结果如下图: 但是现在有个新的需求,要把名字为‘张三

浅谈数据库并发控制 - 锁和 MVCC

在学习几年编程之后,你会发现所有的问题都没有简单.快捷的解决方案,很多问题都需要权衡和妥协,而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制. 如果数据库中的所有事务都是串行执行的,那么它非常容易成为整个应用的性能瓶颈,虽然说没法水平扩展的节点在最后都会成为瓶颈,但是串行执行事务的数据库会加速这一过程:而并发(Concurrency)使一切事情的发生都有了可能,它能够解决一定的性能问题,但是它会带来更多诡异的错误. 引入了并发事务之后,如果不对事务的执行进行控制就会

浅谈数据库的锁

数据库对于程序猿来 并不陌生,但是数据库的锁你知道多少?数据库的锁直接影响数据性能,在大并发的前提下,怎么保证数据不被死锁,提高数据库性能?如何加锁,何时加锁,加什么锁,你可以通过hint手工强行指定,但大多是数据库系统自动决定的.这就是为什么我们可以不懂锁也可以写SQL. 下面我们来简单谈一谈数据库中的锁,以sqlserver 为例: 数据库锁的种类: 1.共享锁(Shared lock) 何为共享锁,顾名思义意思就是资源共享,所以共享锁之间 是没有时间等待的可以同时执行一条或多条查询语句,共

MySQL数据库联合查询与连接查询

联合查询 基本概念 联合查询是可合并多个相似的选择查询的结果集.等同于将一个表追加到另一个表,从而实现将两个表的查询组合在一起,使用为此为UNINO或UNION ALL 联合查询:将多个查询的结果合并到一起(纵向合并):字段数不变,多个查询的记录数合并 应用场景 1.将同一张表中不同的结果(需要对应多条查询语句来实现),合并到一起展示数据 2.最常见:在数据量大的情况下,会对表进行分表操作,需要对每张表进行部分数据统计,使用联合查询来将数据存放到一起显示 基本语法 select 语句 union

浅谈数据库设计二三事

作为程序员,程序设计前的数据库设计非常重要,这将直接关系到紧接着的代码编写工作,这里谈谈有关数据库设计过程中的一些细节问题.  一.数据表主键的字段选择(ID,Code,Number) ID(编号)一般是选择GUID,这种格式的字符串是一串全球唯一的字符串.当程序需要调用不同平台上的相同结构的数据库时,建议使用guid来作为主键.这样做的好处是,当在某一平台上汇总不同平台的数据时,同一表中的数据汇总不会出现因为主键相同而无法正常汇总的情况.Code(编码)一般是一串非全数字的字符串,比如字母混合