2020-09-03Oracle左连接(+)踩的坑

tech2024-12-12  6

今天在处理一个统计报表,统计的是用户的还款金额(当然是给我自己看的)

有我们自己的订单表:

订单号 order_no订单时间 order_date操作金额 order_amount

处理付款的表

订单号 order_no订单时间 order_date

但是凑巧啊。。。 这张付款处理表实际上是有其他业务类型的,有一个字段bus_type,没想到有个不是我们业务的订单与我们的订单号一样,所以报表多算了金额。

原sql

SELECT T.POST_AC_DT STAT_DT, T1.CORP_SNM CCP_CAP_CORG, T.CCP_CNL CCP_CNL, COUNT(T.CCP_ORD_NO) CCP_CNT_COUNT, SUM(T.CCP_ACT_AMT) CCP_AMT_SUM, NVL(T2.RUT_CORG, ' ') RUT_CORG --付款银行 FROM CCPTORDR T, (SELECT CORP_SNM, CORP_ORG FROM CMMTORGN) T1, --银行名称表 WDCTORDR T2 WHERE T.ORD_STS <> 'W1' --订单状态 : W1 预授权成功(商户收款) AND T1.CORP_ORG = T.CAP_CORG --银行编号 AND T.POST_AC_DT = V_DATE --时间,这个是在存储过程里面的值 AND T.CCP_ORD_NO = T2.RP_ORD_NO(+) --订单号 AND T.ORD_DT = T2.ORD_DT(+) --订单时间 (懒所以后面都不加了) GROUP BY T.POST_AC_DT, T1.CORP_SNM, T.CCP_CNL, T2.RUT_CORG;

这个没加业务区分,好我给他整上

SELECT T.POST_AC_DT STAT_DT, T1.CORP_SNM CCP_CAP_CORG, T.CCP_CNL CCP_CNL, COUNT(T.CCP_ORD_NO) CCP_CNT_COUNT, SUM(T.CCP_ACT_AMT) CCP_AMT_SUM, NVL(T2.RUT_CORG, ' ') RUT_CORG --付款银行 FROM CCPTORDR T, (SELECT CORP_SNM, CORP_ORG FROM CMMTORGN) T1, WDCTORDR T2 WHERE T.ORD_STS <> 'W1' --订单状态 : W1 预授权成功(商户收款) AND T1.CORP_ORG = T.CAP_CORG AND T.POST_AC_DT = V_DATE AND T.CCP_ORD_NO = T2.RP_ORD_NO(+) AND T.ORD_DT = T2.ORD_DT(+) AND T2.RP_ORD_TYP = '06' GROUP BY T.POST_AC_DT, T1.CORP_SNM, T.CCP_CNL, T2.RUT_CORG;

结果。。。。。服务台的老哥发邮件给我说算错了。。。,后面我找到原因后比正确的少算了几百块。

大佬看了一样就发现了问题给我的sql进行了改正

SELECT T.POST_AC_DT STAT_DT, T1.CORP_SNM CCP_CAP_CORG, T.CCP_CNL CCP_CNL, COUNT(T.CCP_ORD_NO) CCP_CNT_COUNT, SUM(T.CCP_ACT_AMT) CCP_AMT_SUM, NVL(T2.RUT_CORG, ' ') RUT_CORG --付款银行 FROM CCPTORDR T, (SELECT CORP_SNM, CORP_ORG FROM CMMTORGN) T1, (select * from WDCTORDR where RP_ORD_TYP = '06') T2 WHERE T.ORD_STS <> 'W1' --订单状态 : W1 预授权成功(商户收款) AND T1.CORP_ORG = T.CAP_CORG AND T.POST_AC_DT = V_DATE AND T.CCP_ORD_NO = T2.RP_ORD_NO(+) AND T.ORD_DT = T2.ORD_DT(+) GROUP BY T.POST_AC_DT, T1.CORP_SNM, T.CCP_CNL, T2.RUT_CORG;

为啥会出现漏算 的情况呢? 后面我看了资料才知道,我那种错误的把条件写在(+)后面的是需要也加上(+)的,不然这个左连就失效了,这样我就漏算了一笔用户已经付款,但是我们还没来得及进行对商户划款的钱,他会多过滤掉这笔还没有登记付款表的钱,这也怪我没有看懂这个报表的统计意图。

我的错误sql是在左连之后,把那一笔我们订单表没有登记付款的钱给过滤了。。因为添加了过滤条件,其实是先执行连接,再过滤的。 下面是连接之后的假设情况:

订单号A 时间A 钱 订单号B 时间B 业务类型 01 2020/9/3 100 01 2020/9/3 06 02 2020/9/3 100 02 2020/9/3 05 03 2020/9/3 100

这个是连接后的3种情况,业务匹配、业务不匹配、付款表没有记录 其中01和03其实是我们要算的钱。 如果我加了过滤条件,那么03这种情况就会别 业务 = ‘06’的过滤掉了,导致我们少算了一笔钱。 所以应该要先做判断,把业务 = ‘06’ 的取出来,再进行连接这样就不会漏掉这笔没付款登记的钱了。

这种问题也是我这种菜鸡可能会经常碰到并且忽略的问题,做个记录希望自己以后碰到这种情况,能够主要到这个细节问题。

最新回复(0)