您的位置:首页 > 数据库

SQL联合查询

2014-09-19 10:08 148 查看

SQL联合查询

联合查询是根据每个表之间的逻辑关系从两个或多个表中检索数据,而这逻辑关系则是每个表之间共同的列的关联性,这也是关系数据库查询的最主要的特征.

联合查询分为内连接,外连接和自连接查询. 外连接又可分为左外连接left outer join 、右外连接right outer join 、全外连接full outer join 查询.

联合查询效率较高,以下例子来说明联合查询(内联、左联、右联、全联)的好处:

表T1
UserId
Name
Password
1
dong
pdong
2
hai
phai
表T2
UserId
SID
Grade
1
1
2
3
2
3

内连接(inner join):仅显示两个连接表中匹配的行

如果想把用户信息、姓名、年级等都列出来,那么一般会这样写:select * from T1 ,T2 where T1.UserId = T2.UserId(其实这样的结果等同于select * from T1 inner join T2 on T1.UserId=T2.UserId )。

把两个表中都存在UserId 的行,将符合条件的行拿出来拼成一行(即内联),但后者的效率会比前者高很多,建议用后者(内联)的写法。

SQL语句:select * from T1 inner join T2 on T1.UserId=T2.UserId

运行结果
T1.UserId
Name
Password
T2.UserId
SID
Grade
1
dong
pdong
1
001
2
内连接将不符合连接条件的数据丢弃,只保留满足连接条件的行,连接表出现的顺序是无关紧要的,而在外连接中,连接双方有左右之分,如上边Sql语句"T1"为"左"表,"T2"为"右"表.根据左右表外连接分为左外连接,右外连接和全外连接.

左外连接(left outer join)列出左表所有行,和右表中符合条件的行

显示左表T1中的所有行,并把右表T2中符合条件加到左表T1中;右表T2中不符合条件,就不用加入结果表中,并且NULL表示。

SQL语句:select * from T1 left outer join T2 on T1.UserId=T2.UserId

运行结果
T1.UserId
Name
Password
T2.UserId
SID
Grade
1
dong
pdong
1
001
2
2
hai
phai
NULL
NULL
NULL

右外连接(right outer join)列出右表中所有行,和左表中符合条件的行

显示右表T2中的所有行,并把左表T1中符合条件加到右表T2中;左表T1中不符合条件,就不用加入结果表中,并且NULL表示。

SQL语句:select * from T1 right outer join T2 on T1.UserId=T2.UserId

运行结果
T1.UserId
Name
Password
T2.UserId
SID
Grade
1
dong
pdong
1
001
2
NULL
NULL
NULL
3
002
3

全外连接(full outer join)左联结果表+右联结果表

显示左表T1、右表T2两边中的所有行,即把左联结果表+右联结果表组合在一起,然后过滤掉重复的。

SQL语句:select * from T1 full outer join T2 on T1.UserId=T2.UserId

运行结果
T1.UserId
username
password
T2.UserId
SID
Grade
1
dong
pdong
1
001
2
2
hai
phai
NULL
NULL
NULL
NULL
NULL
NULL
3
002
3

总结,关于联合查询,效率的确比较高.但是这也是有前提条件的,效率比较高也是相对的,适用于两个表联合查询,或者多表小数据量的查询.看下边的例子.

假设我们有三个表,A表,B表,C表.其数据量分别都为200条记录.并且假设每次都是遍历一半也就是100条的记录找到结果(一半情况下有较大的浮动,只是举例说明),并且假设每次查询都查出10个结果.

一般我们的查询语句是这样的:

select * from A,B,C where A.id=B.id and B.id=C.id

它相当于先将这三表进行组合,再遍历查询,查询量为100*100*100=100万.也就是从100万条数据中检索10条数据,听到一百万有什么感想,这仅是每个表中只有200条数据,如果每个表中有200万条数据呢?那会是一个多个大的负担(对于计算机).

那我们要如何来优化呢,上面其实已经说过了,那就是使用联合查询的前提条件,两个表的联合就没这问题,我们将三个表的联合查询拆分成两个两个的表的联合查询这样就大量减少了遍历的次数.

方式1: 将三表联合分成两个2表联合查询,如:先进行AB联合查询,再将结果与C联合. 这样查询遍历次数为:100*100+10*100 =1.1万.(只是检索10条数据)

SQL为:

select * from (select * from A , B where A.id = B.id) as ab, C where ab.id=C.id

方式2:先对各表进行过滤,再进行三表联合,或者2表联合: 这样查询的遍历次数为:100+100+100+10*10*10=1300.,或者:100+100+100+10*10+10*10=500.

SQL为:

select * from (select * from a where ...)as a,(select * from b where ....) as b, (select * from c where ....) as c where a.id=b.aid and b.id=c.bid

或者:

select * from (select * from (select * from a where ...)as a ,(select * from b where ....) as b where a.id = b.aid) as ab, (select * from c where ....) as c where ab.id=c.bid

这个时候或许数据就有比较的价值了,三个表联合查询和拆分开两个表联合遍历的数据条数100万,1.1万,0.13万,0.05万.我想着数字很值得我们深思考吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: