1.情景再现
分类信息 | 住户 | 租户 | 快递 | 亲友访问 |
花苑 | 138 | 25 | 44 | 89 |
新城 | 34 | 150 | 78 | 34 |
以上的一张表中,假如要分别在两个住宅小区统计各类进出的人数,进出的类型可以分为是住户,租户,快递以及亲友访问四个类型。
但是实际的表设计中,住户以及租户是属于这个小区,可以直接统计出来,但是快递以及亲友访问则需要从进出记录查找。
换言之,就是表中的每个元组的数据是从多个表中查出来的,同时可能是用四条sql语句中查询出来的。使用如下表达:
①: select t.name as comunityName,
count(t.type) as ownerNumber
from ownerTable t
②: select t.name as comunityName,
count(t.type) as rnetNumber
from rentTable t
③: select t.name as comunityName,
count(t.type) as expressNumber
from inviterTable t
where t.inviterType = ‘express‘
④:select t.name as comunityName,
count(t.type) as friendNumber
from inviterTable t
where t.inviterType = friend
以上四条语句查询出来的四个结果,最终我们需要的是一个完整的元组数据类似于:
花苑 | 138 | 25 | 44 | 89 |
2.解决方案
利用Oracle提供的union all函数,进行查询结果的一个全连接,并且构造每一个查询结果的一个元组,sql语句如下
select comunityName,
ownerNumber,
rentNumber,
expressNumber,
friendNumber
from(
select t.name as comunityName,
count(t.type) as ownerNumber,
0 as rentNumber,
0 as expressNumber,
0 as friendNumber
from ownerTable t
group by t.id
union all
select t.name as comunityName,
0 as ownerNumber,
count(t.type) as rentNumber,
0 as expressNumber,
0 as friendNumber
from rentTable t
group by t.id
unoin all
select t.name as comunityName,
0 as ownerNumber,
0 as rentNumber,
count(t.type) as expressNumber,
0 as friendNumber
from inviterTable t
where t.inviterType = ‘express‘
group by t.id
union all
select t.name as comunityName,
0 as ownerNumber,
0 as rentNumber,
0 as expressNumber,
count(t.type) as friendNumber
from inviterTable t
where t.inviterType = friend
group by t.id
) group by comunityName;
3.实现解读
以上的SQL语句中,针对第一步所涉及道德SQL语句,每条都补全了所需要展示的四个维度,住户,租户,快递,亲友。
每条SQL语句都会产生一个元组,但是没有数据的部分会置0,然后针对四条SQL语句的查询结果进行一个unoin操作,根据每个元组共同的一个值
comunityName进行一个元组的联接,并且列出所有的出现过的comunityName的值,如果其后续的数据没有则按照默认值补充。