一个关于sql left jion sum汇总数据重复汇总数量变多的问题

假设我们有四张表,他们的关系是A->B->C->D,而依次往下推每个环节都存在一对多的关系,表的关联都是以上一个表的id做关联,假设每个表都有对应的一个数量和物料字段,这样在我们想以a表为主left jion去汇总各个表的数量时会出现这样一种情况,那就是可能出现A汇总的数量重复也就导致A表的数量变多。这样怎么解决呢?

其实我们可以逆向思维一下,不要顺着往下汇总,我们可以从最小的表开始,也就是D表,我们可以先以C表的id去汇总D表的数量,在用C表left jion D 表来以B表的id来汇总C表和再次汇总D表的数量,依次往外推就可以啦。

可能有点绕,我们直接上代码,按错误的写法如下:

--关系销售合同->销售订单->发货通知单->销售出库单,以采购分录id汇总各个表单数量
	SELECT
		b.FSOURCEBILLENTRYID,
		a.FSaleGroupID,
		SUM ( b.FQty ) AS SCSumQty,
		SUM ( d.FQty ) AS PRSumQty,
		sum ( e.FQty ) AS SISumQty
	FROM
		T_SD_SaleContract a
		LEFT JOIN T_SD_SaleContractEntry b ON b.FParentID = a.FID
		LEFT JOIN T_SD_SaleOrderEntry c ON c.FSOURCEBILLENTRYID = b.FID
		LEFT JOIN T_SD_PostRequisitionEntry d ON d.FSaleOrderEntryID = c.FID
		LEFT JOIN T_IM_SaleIssueEntry e ON e.FSourceBillEntryId = d.FID
	GROUP BY
		b.FSOURCEBILLENTRYID,
		a.FSaleGroupID 

以上sql如果是表直接一对一的关系的话就没有问题,一旦他们中间存在一对多的关系时就会出现文章开始说的那个问题。

那么我们按照开始梳理的逻辑来改造这个sql,如下:

	-- (这一部分要从最里层往外看才能理解)
		-- 以采购合同分录id汇总销售合同数量、发货通知单数量和销售出库单数量
		SELECT X.FSOURCEBILLENTRYID,SUM(x.FQty) AS SCSumQty,SUM(y.PRSumQty) AS PRSumQty,SUM (y.SISumQty) AS SISumQty 
		FROM T_SD_SaleContractEntry x 
		LEFT JOIN 
		(
			-- 以销售合同分录id汇总发货通知单数量和销售出库单数量
			SELECT x.FSOURCEBILLENTRYID,SUM(y.PRSumQty) AS PRSumQty,SUM(y.SISumQty) AS SISumQty FROM T_SD_SaleOrderEntry x 
			LEFT JOIN  
			(
				-- 以销售订单分录id汇总发货通知单数量和销售出库单数量
				SELECT a.FSaleOrderEntryID,SUM(a.FQty) AS PRSumQty,SUM(x.SISumQty) AS SISumQty FROM T_SD_PostRequisitionEntry a 
				LEFT JOIN
				( 
					-- 以发货通知单分录id汇总销售出库单数量
					SELECT a.FSourceBillEntryId,SUM(a.FQty) AS SISumQty 
					  FROM T_IM_SaleIssueEntry a 
					 GROUP BY a.FSourceBillEntryId 
				) x ON x.FSourceBillEntryId = a.FID
				GROUP BY a.FSaleOrderEntryID
			)y ON y.FSaleOrderEntryID = x.FID 
			GROUP BY x.FSOURCEBILLENTRYID
		)y ON y.FSOURCEBILLENTRYID = x.FID
		GROUP BY x.FSOURCEBILLENTRYID,x.FQty 

 至此,问题解决,所以我们遇到问题,不要只以一贯的思维去思考,当我们被常用思维卡住时,不妨试着反方向去思考问题,或许问题就能迎刃而解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值