解析数据库查询中的外连接
在信息管理系统的开发中,外连接通常用来完成一些复杂特殊的多表查询,虽不常用,但其作用举足轻重。
什么是外连接呢?简而言之,外连接是指它返回查询结果集合中,不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行,共分为左外连接、右外连接、全外连接三种方式,实际开发中使用较多的是左外连接和右外连接,笔者以一实例来解析这两种外连接。
假设某数据库中有两个数据表,表一是客户表costomer,表二是订单表order,表结构及记录如下:
customer表结构:
cno:客户编号
name:客户名称
address:客户地址
age:客户年龄
customer表内容:
cno name address age
1 张三 长沙 25
2 李四 北京 21
3 王五 上海 36
order表结构:
cno:客户编号
ono:订单号
goods:所订货物
order表内容:
cno ono goods
1 101 牙刷
3 301 电风扇
我们现在需要查询输出一个客户列表,如果该客户有订单表中,要求包含订单资料。这个查询能使用内连接吗?我们试试:
select customer.*,order.one,order.goods fromcustomer,order where customer.cno=order.cno
输出结果为:
cno name address age ono goods
1 张三 长沙 25 101 牙刷
3 王五 上海 36 301 电风扇
很显然,这不是我们所要的结果,由于内连接返回查询结果集合中的仅是符合查询条件和连接条件的行,在order表中找不到对应李四这个客户编号的任何订单记录,不满足连接条件,因此李四没有出现在查询结果中。必须使用左外连接才能得到预期结果。
以custmoer为左表,以order表为右表,左外连接的特点是保证左表的满足查询条件的所有记录无论是否符合连接条件,都会出现在查询结果中,那些不满足条件的左表记录的右表相应字段将输出为空值。
下面是完成这个查询功能的左连接SQL语句。实际开发中,Oracle、SqlServer主流数据库管理系统使用较多,因此对本文所有的外连接操作,笔者分别列出了这两种数据库的SQL语句。
Oracle:(Oracle的风格与众不同,可理解为左连接中符号+所在边的表就是右表)
select customer.*,order.one,order.goods fromcustomer,order where customer.cno=order.cno(+)
Sql Server(access与SqlServer相同):
select customer.*,order.one,order.goods from customer leftjoin order on customer.cno=order.cno
运行一下,查询结果如下:
cno name address age ono goods
1 张三 长沙 25 101 牙刷
2 李四 北京 21
3 王五 上海 36 301 电风扇
完全符合要求,上述例子,如果以custmoer为左表,以order表为右表,进行右外连接查询,完成的功能是查询所有订了货的客户名单。
Oracle:(Oracle的风格与众不同,可理解为右连接中符号+所在边的表就是左表)
select customer.*,order.one,order.goods fromcustomer,order where customer.cno(+)=order.cno
Sql Server(access与SqlServer相同):
select customer.*,order.one,order.goods from customerright join order on customer.cno=order.cno
运行后查询结果与使用内连接结果居然一致辞,细想一下,对于右连接而言,右表order中的所有满足查询条件的记录都会在输出结果中,order表中没有不符合连接条件的记录,因此与内连接一样。
外连接虽方便实用,但消耗的资源非常之多,因为它们包含与 NULL(不存在)数据匹配的数据,只能在不可避免的情况下使用它,被过度使用,代价可能非常高。避免使用外连接最简单方法是尽可能多地围绕它们设计数据库,避免数据库的人为设计造成外连接语句的过多使用。