查询公寓费发票的SQL多表连接出现重复记录,不使用distinct如何去重
问题原因
你出现重复记录的核心原因是invoicedetails表中,编号20065的发票对应了2条明细行:你直接将主表和明细做关联时,每条明细都会和上游的发票、入住等主记录匹配一次,自然就生成了2条完全重复的主数据记录。
解决方法(不使用DISTINCT)
因为你当前SELECT子句里没有用到任何invoicedetails、reservations表的字段,不需要保留明细的维度,所以可以把这两个表的关联改成EXISTS条件判断,只校验关联关系存在即可,不会触发明细行的笛卡尔积扩展:
select i.inv#, i.condo#, i.guest#, g.rlname, cs.startdate, cs.enddate, c.WeeklyFee from guests g join condostays cs on g.guest# = cs.guest# join condos c on cs.condo# = c.condo# join invoice i on cs.guest# = i.guest# and cs.condo# = i.condo# where i.guest# = 'G5' and i.inv# = 20065 and cs.startdate = '2019-08-03' -- 用EXISTS校验发票和预订、明细的关联关系,不会生成重复行 and exists ( select 1 from reservations r join invoicedetails id on r.rid = id.rid where r.guest# = g.guest# and id.inv# = i.inv# );
如果你后续需要用到invoicedetails的字段做金额计算,可以先对invoicedetails按关联字段聚合去重后再关联,避免使用DISTINCT:
select i.inv#, i.condo#, i.guest#, g.rlname, cs.startdate, cs.enddate, c.WeeklyFee from guests g join reservations r on g.guest# = r.guest# -- 先按inv#、rid分组,确保每个关联维度只有一条记录再join join ( select inv#, rid from invoicedetails where inv# = 20065 group by inv#, rid ) id on r.rid = id.rid join invoice i on id.inv# = i.inv# join condostays cs on i.guest# = cs.guest# and i.condo# = cs.condo# join condos c on cs.condo# = c.condo# where i.guest# = 'G5' and i.inv# = 20065 and cs.startdate = '2019-08-03';
内容的提问来源于stack exchange,提问作者Musk Long
相关产品推荐
相关产品推荐

