由Oralce的左右连接想到的

本文通过创建两个表并填充数据,详细介绍了SQL中的左右连接概念及其实际应用。文章演示了如何查询所有地区的销售统计,以及如何处理未出现在另一表中的记录。

以前也看了不少关于SQL的左右连接的内容,都是全部显示其中一个表的全部内容。也许是内容太抽象,或是自己平常用的少,具体如何使用?如何去思考如何用这个左右连接?虽然这是一个很简单的问题,由于最近做项目,刚好有了这方面的思考!

以下用的情况是Oracle8i,因为项目关系,其实只要原理一样,不管不用管数据库是不是一样,甚至不用管写法是不是不一样!

先思考一个问题,有两张表。一个地区表tb_area,有2个字段,area_id,aea_name。一个地区销售统计表tb_stat,有3个字段,stat_id,stat_area_id,stat_num。

现在开始建表:

create table tb_area
(
area_id number,
area_name varchar2(20)
);
create sequence seq_tb_area_id;
create table tb_stat
(
stat_id number,
stat_area_id number,
stat_num number
);
create sequence seq_tb_stat_id;

填充数据:tb_area

declare
x number;
begin
x:=1;
while x<=100 loop
insert into tb_area values (seq_tb_area_id.nextval,'area-'||x);
x:=x+1;
end loop;
end;

填充数据:tb_stat (仅插入试验数据,数据随便填写,这里我只插4记录)

insert into tb_stat values(seq_tb_stat_id.nextval,2,20)
insert into tb_stat values(seq_tb_stat_id.nextval,5,11)
insert into tb_stat values(seq_tb_stat_id.nextval,8,22)
insert into tb_stat values(seq_tb_stat_id.nextval,1,52)
...

注意:这里为了方便测试试验,tb_stat的记录仅限制一个地区对应一个数量统计,即一个地区一个记录,且该表记录的地区少于tb_area所含有的所有的地区数。即对于tb_area的地区而言,tb_stat的地区是其的部分分布。

提出需求:查询所有有数量统计的地区及其所在地区的数量

select a.area_name,b.stat_num from tb_area a,tb_stat b where a.area_id = b.stat_area_id
结果如图:

提出需求:要求查看所有地区的统计分布(这里就要求首先必须显示全部的地区数据,并根据地区数据查看tb_stat显示该地区是否有统计,有就显示stat_num,没有就显示0)

select a.area_name,
case when
isnull(b.stat_num) then 0
else then
b.stat_num
end
from tb_area a,tb_stat b where a.area_id = b.stat_area_id(+)

现在如何理解这个结果集?

可这么理解这个查询结果集的组成过程!先查询tb_area的area_name,此时有一列数据,假定为A列,再查询tb_stat的stat_num,此时有一列数据,假定为B列,看到后面的(+)吗?(+)表示的是有(+)那边的那个查询的表的结果即B列会经过一系列处理得到一个C列,然后显示A+C列(此时可看A列的结果集合作为基础列,后面的添加C列仅是对A列进行组合操作)。该处理就是先比对是否a.area_id = b.stat_area_id,如果a.area_id = b.stat_area_id为真,则按照A列area_id的顺序显示该数据,如果出现B列中没有而A列的地区,则显示null,这里我用case处理了下,如果为空,则显示0。

其实上面说了一大堆,说白了,多表查询其实就是将各表的查询结果按照某种条件进行拼接,最后得到一个大的结果集。没有条件,则进行笛卡尔运算,即按照其中一个表的查询结果中的一条记录对应另一个表的所有的记录的形式进行显示。只有条件的,将只显示满足条件的结果集,如果有左右连接,预示着数据库还要考虑某个表的查询结果是否全部显示,还是部分显示。

在一个,如果有多个条件,会按照条件的先后顺序进行左右连接处理。这个时候,你只要注意哪个作为基础列(就是没有(+)那边的表,该表将显示所有的记录)就可以得到自己想要的结果集。例如注意下面的不同

select a.area_name,
case when
isnull(b.stat_num) then 0
else then
b.stat_num
end Num,
case when
isnull(c.stat_num) then 0
else then
c.stat_num
end Num1
from tb_area a,tb_stat b,tb_stat c where a.area_id = b.stat_area_id(+)
and a.area_id = c.stat_area_id(+)


select a.area_name,
case when
isnull(b.stat_num) then 0
else then
b.stat_num
end Num,
case when
isnull(c.stat_num) then 0
else then
c.stat_num
end Num1
from tb_area a,tb_stat b,tb_stat c where a.area_id = b.stat_area_id(+)
and a.area_id(+) = c.stat_area_id

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值