查找从三个表的左连接获得的三列的总和

Posted

技术标签:

【中文标题】查找从三个表的左连接获得的三列的总和【英文标题】:finding sum of three columns obtained from left join of three tables 【发布时间】:2019-11-21 17:38:40 【问题描述】:

我有 4 张桌子:

accounts_info
----------------------------------------------
user_id | user_type | user_page | device_type 


hostel_billing (can have duplicate user_id)
-------------------------
user_id | billing_charges

academic_billing (can have duplicate user_id)
-------------------------
user_id | academic_charges

misc_billing (can have duplicate user_id)
-------------------------
user_id | misc_charges

我想创建一个新表,从以上 4 个表中提取数据:

user_expenses 
---------------------------------------------------------------
user_id | user_type | user_page | device_type | total_charges

total_charges 将是total_charges = misc_charges + academic_charges + billing_charges 的总和。 我无法计算总费用。

到目前为止,我已经能够获得 misc_charges、academic_charges 和 billing_charges 的总和 对于使用此查询的每个 user_id,但无法弄清楚如何总结从分别加入 hostel_billing、misc_billing 和 Academic_billing 获得的三列 hostel_charges、misc_charges 和 Academic_charges:

with user_info as (
select 
   user_id, user_type, user_page, device_type 
from accounts_info 
),

academics as (
select user_id, sum(academic_charges) as academic from academic_billing group by 1
),

hostels as (
select user_id, sum(hostel_charges) as hostel from hostel_billing group by 1
),

misc as (
select user_id, sum(misc_charges) as misc from misc_billing group by 1
)

select 
     ui.user_id, 
     ui.user_page, 
     ui.user_type, 
     ui.device_type, 
     sum(a.academic_charges),
     sum(m.misc_charges), 
     sum(h.hostel_charges)
from user info ui left join misc m on ui.user_id=m.user_id
left join hostels h on ui.user_id=h.user_id
left join academics a on ui.user_id=a.user_id
group by 1,2,3,4

【问题讨论】:

【参考方案1】:

应该很简单,你可以试试:

with user_info as (
select 
   user_id, user_type, user_page, device_type 
from accounts_info 
),

academics as (
select user_id, sum(academic_charges) as academic from academic_billing group by 1
),

hostels as (
select user_id, sum(hostel_charges) as hostel from hostel_billing group by 1
),

misc as (
select user_id, sum(misc_charges) as misc from misc_billing group by 1
)

select 
     ui.user_id, 
     ui.user_page, 
     ui.user_type, 
     ui.device_type, 
     sum(a.academic_charges) + sum(m.misc_charges) + sum(h.hostel_charges) as total_charges
from user info ui left join misc m on ui.user_id=m.user_id
left join hostels h on ui.user_id=h.user_id
left join academics a on ui.user_id=a.user_id
group by 1,2,3,4

【讨论】:

谢谢,那行得通,不过应该想通了!! @vijayshanker 。 . .我认为这不会为没有全部三种计费类型的用户返回正确的答案。 @GordonLinoff ...你能解释一下吗【参考方案2】:

假设您在accounts_info, you do not need the outer aggregation. All the aggregation queries return one row peruser_id 中有一行user_id,因此无需在该级别重新聚合。它只会减慢查询速度。

所以:

with user_info as (
      select user_id, user_type, user_page, device_type 
      from accounts_info 
     ),
     academics as (
      select user_id, sum(academic_charges) as academic 
      from academic_billing
      group by 1
     ),
     hostels as (
      select user_id, sum(hostel_charges) as hostel
      from hostel_billing
      group by 1
     ),
     misc as (
      select user_id, sum(misc_charges) as misc
      from misc_billing
      group by 1
     )
select ui.user_id, ui.user_page, ui.user_type, ui.device_type, 
       a.academic_charges, m.misc_charges, h.hostel_charges,
       (coalesce(a.academic_charges, 0) +
        coalesce(m.misc_charges, 0) +
        coalesce(h.hostel_charges, 0)
       ) as total
from user_info ui left join
     misc m
     on ui.user_id = m.user_id left join
     hostels h
     on ui.user_id = h.user_id left join
     academics a
     on ui.user_id = a.user_id;

coalesce() 非常重要。否则,sum() 对于没有全部三种计费类型的用户将不正确。

【讨论】:

coalesce 的使用我明白了,但是你为什么把 SUM() 和 group by 留在这里 你能解释一下不需要外部聚合吗

以上是关于查找从三个表的左连接获得的三列的总和的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以从 NULL 列的左连接中选择一些东西?(用人为的例子在本地重现它,可能是一个错误!)

MySQL 上的左连接 + 计数 + 总和

Linq 和 SQL的左连接右连接内链接

通过 group by 和 joins 获取多个表的多个列的总和

我在 oracle sql 中的左连接没有返回左表的每个元素

如何在pl/sql中获取表的三列的组合?