模拟完全连接返回错误的值

时间:2016-12-29 10:12:53

标签: mysql join union

我有两张没有关系的桌子,我做了一个左右连接来模拟它们的完整连接并选择一些数据。
显示数据的方式是正确的,但值是错误的,看起来他们选择了不止一次 我的桌子是这样的:
表1(讨价还价)
trade_date ----利润

表2(general_cost)
日期-----费用

这是我写的查询:

select b.trade_date, coalesce(sum(b.profit),0),  coalesce(sum(g.cost),0)  
from bargains as b 
left join general_cost as g on b.trade_date =  g.date group by b.trade_date 
union
select g.date, coalesce(sum(b.profit),0), coalesce(sum(g.cost),0) from
bargains as b
right join general_cost as g on b.trade_date =  g.date  group by g.date  

这是查询的结果:

enter image description here

例如,在日期1395-9-28中,利润列的总和应为440,成本列的总和应为800
如果有帮助你应该知道在交易表中有三行这个日期,在general_cost表中有两行

1 个答案:

答案 0 :(得分:1)

是的,您的查询会复制匹配的记录,因为这些记录包含在左侧和右侧的连接中。您需要从其中一个查询中排除匹配的记录。我通常将它们从联盟的第二个查询中排除:

select b.trade_date, coalesce(sum(b.profit),0),  coalesce(sum(g.cost),0)  
from bargains as b 
left join general_cost as g on b.trade_date =  g.date group by b.trade_date 
union
select g.date, coalesce(sum(b.profit),0), coalesce(sum(g.cost),0) from
bargains as b
right join general_cost as g on b.trade_date =  g.date
where b.date is null //include only the records from general_cost that are not matched 
group by g.date

更新

如果两个表中的多条记录具有相同的日期,则需要在子查询中分别对每个表进行求和,否则匹配的记录会重复:

select b.trade_date, b.profit,  coalesce(g.cost,0)  
from (select trade_date, sum(profit) as profit from bargains group by trade_date) as b 
left join (select date, sum(cost) as cost from general_cost group by date) as g on b.trade_date =  g.date
union
select g.date, 0, sum(g.cost) from //all profits has been summed up in the above query, so here we can use 0 in place of profit
bargains as b
right join general_cost as g on b.trade_date =  g.date
where b.trade_date is null //include only the records from general_cost that are not matched 
group by g.date