[英]How to join three tables and count the record with UNION one column
我想加入这些表并计算状态是否为'Y'
table1(date, status)
8/23/2015 Y
8/24/2015 Y
8/24/2015 N
table2(date, status)
8/23/2015 Y
8/23/2015 Y
table3(date, status)
8/23/2015 Y
8/25/2015 N
8/25/2015 Y
我期望的结果就像。 。 。
DATE count(table1.status) count(table2.status) count(table3.status)
--------- -------------------- -------------------- --------------------
8/23/2015 1 2 1
8/24/2015 1 0 0
8/25/2015 0 0 1
也许最简单的方法是将union all
表合并在一起然后聚合:
select date, sum(status1) as status1, sum(status2) as status2,
sum(status3) as status3
from ((select date, 1 as status1, 0 as status2 , 0 as status3
from table1
where status = 'Y') union all
(select date, 0 as status1, 1 as status2 , 0 as status3
from table2
where status = 'Y') union all
(select date, 0 as status1, 0 as status2 , 1 as status3
from table3
where status = 'Y')
) t
group by date
order by date;
如果你想通过full join
来做这件事,你必须非常小心。 你很想写:
select date,
sum(case when t1.status1 = 'Y' then 1 else 0 end) as status1,
sum(case when t2.status1 = 'Y' then 1 else 0 end) as status2,
sum(case when t3.status1 = 'Y' then 1 else 0 end) as status3
from table1 t1 full join
table2 t2
using (date) full join
table3 t3
using (date)
group by date
order by date;
但是,当同一日期在不同的表中有多个计数(日期的笛卡尔积)时,这会出现问题。 所以,下一个诱惑是增加count(distinct)
。 。 。 在这种情况下你可以这样做,因为没有唯一的列。 即使有,这也增加了开销。
最后,如果您想沿着这条路走下去,可以通过预先聚合每个表来解决这个问题。
这是另一种选择:
with table1 as (select to_date('23/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('24/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('25/08/2015', 'dd/mm/yyyy') dt, 'N' status from dual),
table2 as (select to_date('23/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('23/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('26/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual),
table3 as (select to_date('23/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('25/08/2015', 'dd/mm/yyyy') dt, 'Y' status from dual union all
select to_date('25/08/2015', 'dd/mm/yyyy') dt, 'N' status from dual)
select coalesce(t1.dt, t2.dt, t3.dt) dt,
coalesce(t1.cnt, 0) t1_cnt,
coalesce(t2.cnt, 0) t2_cnt,
coalesce(t3.cnt, 0) t3_cnt
from (select dt, count(case when status = 'Y' then 1 end) cnt
from table1
group by dt) t1
full outer join (select dt, count(case when status = 'Y' then 1 end) cnt
from table2
group by dt) t2 on t1.dt = t2.dt
full outer join (select dt, count(case when status = 'Y' then 1 end) cnt
from table3
group by dt) t3 on t1.dt = t3.dt
order by coalesce(t1.dt, t2.dt, t3.dt);
DT T1_CNT T2_CNT T3_CNT
---------- ---------- ---------- ----------
23/08/2015 1 2 1
24/08/2015 1 0 0
25/08/2015 0 0 1
26/08/2015 0 1 0
(它在连接到其他表之前将每行的行聚合到一行,因此您不会在计数中包含重复的行)。
这是一个好玩的问题。
为了得到结果,我们可以通过使用解码函数对其进行“Y”值求和,如下所示。
create table table1(date1 date, status varchar2(2))
insert into table1 values ( to_date( '8/23/2015', 'mm/dd/yyyy'), 'Y');
insert into table1 values ( to_date( '8/24/2015', 'mm/dd/yyyy'), 'Y');
insert into table1 values ( to_date( '8/24/2015', 'mm/dd/yyyy'), 'N');
create table table2(date1 date, status varchar2(2))
insert into table2 values ( to_date( '8/23/2015', 'mm/dd/yyyy'), 'Y');
insert into table2 values ( to_date( '8/23/2015', 'mm/dd/yyyy'), 'Y');
create table table3(date1 date, status varchar2(2))
insert into table3 values ( to_date( '8/23/2015', 'mm/dd/yyyy'), 'Y');
insert into table3 values ( to_date( '8/25/2015', 'mm/dd/yyyy'), 'N');
insert into table3 values ( to_date( '8/25/2015', 'mm/dd/yyyy'), 'Y');
select date1,
sum(decode(x, '1', status, null)), -- table1:x=1
sum(decode(x, '2', status, null)), -- table2:x=2
sum(decode(x, '3', status, null)) -- table3:x=3
from (select 1 x, date1, decode(status, 'Y', 1, 0) status
from table1
union all
select 2 x, date1, decode(status, 'Y', 1, 0) status
from table2
union all
select 3 x, date1, decode(status, 'Y', 1, 0) status
from table3)
group by date1
order by 1
在@Gordon Linoff解决方案中,他创建了3列(status1,status2,status3)来获得结果,在此解决方案中,我直接从数据中获得结果。
通往罗马的所有道路。
检查一下
select t1.DATE,
SUM(NVL(decode(t1.status, 'Y', 1, 0)),0) table1_sum,
SUM(NVL(decode(t2.status, 'Y', 1, 0)),0) table2_sum,
SUM(NVL(decode(t3.status, 'Y', 1, 0)),0) table3_sum
from table1 t1,
join table2 t2,
join table3 t3,
where t1.Date = t2.date and t1.Date = t3.date
group by t1.DATE
order by t1.DATE
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.