如何连接三个表并使用UNION一列计算记录

n.f*_*rno 3 sql oracle

我想加入这些表并计算状态是否为'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
Run Code Online (Sandbox Code Playgroud)

我期望的结果就像...

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
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

也许最简单的方法是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;
Run Code Online (Sandbox Code Playgroud)

如果你想这样做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;
Run Code Online (Sandbox Code Playgroud)

但是,当同一日期在不同的表中有多个计数(日期的笛卡尔积)时,这会出现问题.所以,接下来的诱惑是补充count(distinct)...在这种情况下你可以这样做,因为没有唯一的列.即使有,这也增加了开销.

最后,如果您想沿着这条路走下去,可以通过预先聚合每个表来解决这个问题.