Oracle SQL:合并两个独立SELECT查询的结果行
解决多表聚合查询:计算每个Job的营收、成本与利润
嘿,作为SQL新手碰到这种多表关联加聚合的问题太正常了,我来给你拆解清楚怎么搞定!
你说得没错,直接把三张表全join在一起然后聚合很容易踩坑——因为一个Job可能对应多条营收记录和多条成本记录,直接join会产生笛卡尔积,导致聚合出来的金额被重复计算,结果肯定不对。所以正确的思路就是先分别对营收、成本按Job聚合,再把聚合结果和Job表关联,这样就不会有数据重复的问题了。
具体实现步骤
- 先单独聚合营收数据:按
job_unid分组,计算每个Job的总营收 - 再单独聚合成本数据:同样按
job_unid分组,计算每个Job的总成本 - 用LEFT JOIN关联Job表和两个聚合结果:这样即使某个Job没有营收或成本记录,也能保留该Job的信息,不会被过滤掉
- 用COALESCE处理NULL值:把没有营收/成本的NULL转成0,让利润计算更合理
完整SQL语句
SELECT j.unid AS `Job No`, COALESCE(r.total_revenue, 0) AS `Total Revenue`, COALESCE(c.total_cost, 0) AS `Total Cost`, COALESCE(r.total_revenue, 0) - COALESCE(c.total_cost, 0) AS `P&L (Rev-Cost)` FROM job j LEFT JOIN ( -- 子查询:计算每个Job的总营收 SELECT job_unid, SUM(amount) AS total_revenue FROM revenue GROUP BY job_unid ) r ON j.unid = r.job_unid LEFT JOIN ( -- 子查询:计算每个Job的总成本 SELECT job_unid, SUM(amount) AS total_cost FROM cost GROUP BY job_unid ) c ON j.unid = c.job_unid;
关键细节解释
- 为什么用LEFT JOIN?:如果某个Job还没有产生营收或者成本记录,INNER JOIN会直接把这个Job过滤掉,而LEFT JOIN会保留它,并用NULL填充对应的金额,再通过
COALESCE转成0,更符合实际业务逻辑。 - 为什么要先聚合再关联?:假设一个Job有3条营收记录、2条成本记录,直接join会生成3×2=6条记录,此时SUM营收会把每条营收算2次,SUM成本会把每条成本算3次,结果完全错误。先聚合再关联就只会有1条对应记录,避免了重复计算。
- 字段名替换:如果你的营收/成本表中存储金额的字段不是
amount,记得把SQL里的amount改成你实际的字段名(比如revenue_amount、cost_amount)。
内容的提问来源于stack exchange,提问作者p.yee
相关产品推荐
相关产品推荐

