SQLUnion实现⼦母单列表展⽰
【需求分析】
系统接⼊ERP,订单会根据商品的发货仓进⾏拆单,所以订单之间不再是单独的关系,⽽有了⼦单母单的概念。在做最⼩的改动的情况下,数据库的改造是在订单表上增加了parent_order_sn字段,所谓的母订单号。如果订单A被拆单,则A应该是母订单,订单状态是‘已拆单’。通过parent_order_sn=‘A订单号’去查询,可以查到对应的⼦订单记录。
【问题再现】
之前我⼀直在负责和ERP系统对接的项⽬,所以对原系统的订单查询改造是另⼀个同事写的。最近和ERP的对接做了⼀些修改,可能母订单A拆除的⼦订单B和⼦订单C会再⼀次进⾏拆分,即订单B可以是⼀个母订单,B下⾯有其他两个⼦订单D和⼦订单E。在进⾏这⼀轮修改的测试,订单列表查询偶尔出现了错位的情况,如下:
正确的展⽰,如下:
但这种错误现象也不是百分百存在,之前都没有发现有问题。看别⼈的代码, 真的是不想做的⼀件事,特别是这种复杂问题的代码,上线前⼀天看了下,觉得代码写的太复杂了,不到问题,还是不动了。⽽就在昨天上线的上午,出现频率⽐较⾼,就乖乖⼜去看代码了,按照代码实现逻辑理了⼀遍,发现其实思路就是不对的,分页查询⼀直是有问题的,也没有⼈注意到。
【代码重写】
原来的代码实现思路是:将所有的母单排除,查询出所有的⼦单,并加上分页⼀页10条。然后循环结果集,从⼦单上获取相关订单信息组装到母单上。
⽽这样的结果,就不对了。如果在10条记录中,有⼦母单的订单,查询到的结果数就⼀直是不确定的。最简单的设想,前10条都是⼦母单的订单,那么其实只会展⽰5个订单,⽽每页的订单数量是根据⼦母单数量的多少⽽改变的,显然是不对的。
既然到问题了,⽽且代码实现完全不对,就直接选择换思路重写代码,不改也逃不过了。
现在的代码实现思路是:将所有的母单查询到,查询完母单后,再去循环,判断如果有⼦单的情况下,去查询订单下所有的⼦单,组装到母订单上。这样不管有多少⼦母单的情况,有⼦单算⼀单,没有⼦单也算⼀单,也不⽤关⼼这个母单是不是由⼀个⼦单继续拆分的,也保证了分页的数量是正确的。
【实现难题】
既然思路确定了,接下来就是写代码了。但是问题来了,我不知道怎么样把所有的母单查询到,⽽且是不重复的所有母单。下⾯是数据库中订单的截图:
总结⼀下,其实就是两种情况:
1. parent_order_sn那⼀列可能是没有值的,也就是算是⼀个母订单;
2. parent_order_sn有值的情况下,⼀定是会有多条的。
我怎么保证⼀个sql能查询到没有问题的分页结果,parent_order_sn有值的情况下,需要Distinct,没有值的情况下,需要查出所有,脑⼦⾥开始想SQL怎么写,GROUP BY,DISTINCT,IF,CASE…WHEN…各种SQL函数,还是不知道这个SQL该怎么写了。
中午吃完饭就开始想,到两点要开始⼯作了,和前端说了句,这⼀个SQL没法写,写不出来,我只能查出正确的结果之后,再⾃⼰去做分页分组的处理。说完,我就想到了既然⼀个SQL不能实现,我就⽤两个SQL去查,然后合并结果集。三两分钟,不重复的母单的SQL查询就写出来了。如下:
SELECT
*
FROM
(
SELECT
t.*, cus.customer_title
FROM
wms_orders t
LEFT JOIN wms_customer cus ON cus.id = t.buyer_id
WHERE
AND tp_id = 8815
AND t.parent_order_sn IS NOT NULL
AND t.parent_order_sn != ''
GROUP BY
parent_order_sn
ORDER BY
t.id_ DESC
) a
UNION
sql中union多表合并
SELECT
*
FROM
(
SELECT
t.*, cus.customer_title
FROM
wms_orders t
LEFT JOIN wms_customer cus ON cus.id = t.buyer_id
WHERE
AND tp_id = 8815
AND (
t.parent_order_sn IS NULL
OR t.parent_order_sn = ''
)
ORDER BY
t.id_ DESC
)
b
ORDER BY
id_ DESC
其实很简单,就是两种分开写,⽤union将两个SQL合并,查询不重复的结果集。
第⼀个SQL对应parent_order_sn有值的情况下,⽤Group By按parent_order_sn字段分组,并且,将第⼆种情况parent_order_sn没有值的排除。
第⼆个SQL对应parent_order_sn没有值的情况,并且将第⼀种情况parent_order_sn有值的排除。
最后⽤union,并且按id倒叙排序。
【⼼得总结】
1. 代码实现前,思路是很重要的,思路是对的,才能保证结果是对的。
同事做之前就和她讨论过该怎么实现,可是结果还是按照她⾃⼰的想法去做的,之前没有发现问题,我也就没有去看她是怎么实现的。看完后,才发现思路是不对的,结果就不⼀定能保证对了。
2. 代码重写,双⽅都不是滋味。
出问题的代码,不是⾃⼰写的,⼀万个不想去看别⼈写的代码。出问题的代码,是⾃⼰写的,结果不对,于是被别⼈推翻重写,⼀万个怀疑我写的代码怎么可能不对。讲真,这应该是这⾏业最真实的⼼理写照。
3. 代码是需要积累的,项⽬经验是宝贵的。
在⼯作中,每⼀个需求,每⼀次代码实现,都是我们积累的财富。代码写的多了,项⽬中遇到的情况多了,总是会有价值的。
4. 不要总想着逃避,其实没有那么困难。
时间长了,⼼态不太好了,总想着问题和我⽆关,少做⼀点,让⾃⼰轻松⼀点。出问题了,就觉得牵扯的东西太多了,不想去碰,等到不得不解决的那⼀刻才去做,⽽不是主动去处理问题。换⼀个⼼态,或许结果还是美好的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。