业务背景:
下面是一个拣货单查询的部分执行sql:
SELECT sod.stockout_id,sod.spec_id,sodp.position_no,sodp.batch_id,sodp.batch_no,
sodp.expire_date,sum(sodp.num) num FROM stockout_print_batch_detail spbd
LEFT JOIN stockout_order_detail sod ON spbd.stockout_id= sod.stockout_id
LEFT JOIN stockout_order so ON so.stockout_id=sod.stockout_id
LEFT JOIN stockout_order_detail_position sodp ON sodp.stockout_order_detail_id=sod.rec_id
AND sodp.type=0 LEFT JOIN stockout_pick_order_detail spo ON spo.pick_id =411
AND sod.spec_id=spo.spec_id AND spo.position_id=sodp.position_id
WHERE ...
在一个拣货单中的同一个货品、同一个货位上有不同的有效期和批次时,搜索结果会翻倍,执行结果如下:红色圈的都比正常数量多了一倍。
对sql进行分析后发现只连接sodp表的结果是正确的,只连接spo表的结果也是正确的,但是同时连接这两个表数量就会翻倍,所以猜测应该是连表的问题,将一条数据的结果返回了两次。
分析:
在连接spo表之前,搜索到的结果是正确的,连接了spo表之后的结果就变成了两倍。(用tsfw5货位是tsfw-jianhuo-3的这两条数据来举例)这是因为连接完sodp表后有两条结果,如上图所示,分别是有效期为0的和不为0的,接下来连接spo表,由于对spo表的连接条件里没有限制有效期和批次,所以
只要满足spo的货位和sodp的货位一样的结果都会被筛选出来,具体过程如下:
1) sodp表连接后有两条结果(spo表单独查看也是这两条数据):
第一条:tsfw5,tsfw-jianhuo-3货位,有效期为0,数量5
第二条:tsfw5,tsfw-jianhuo-3货位,有效期不为0,数量1
2)取出第一条结果,与spo表对照,spo表中有效期为0和不为0的都满足条件,返回这两条结果
3)取出第二条结果,与spo表对照,spo表中有效期为0和不为0的都满足条件,又一次返回这两条结果
因此这两条结果都被返回了两次,数量变为原先的两倍。由此推测,同一货位上如果有三条数据,返回结果将是原先的三倍。
总结:
在连接表的时候,一定要注意连接条件,连接条件不精准会导致数据量也不准。