前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IT咨询顾问:group by与join引发的项目救火

IT咨询顾问:group by与join引发的项目救火

作者头像
intsmaze-刘洋
发布2018-08-29 17:29:04
3910
发布2018-08-29 17:29:04
举报

我又一次进行了项目救火,这次的原因是group by与join胡乱的堆彻导致的整个业务系统审核流程发生严重的错误。基础的sql表关联,group by,子表都理不清。

 很简单的一对多表关联

用户表,customerId代表用户的唯一id,insertTime代表这条数据何时存入的。与之对应的是表单表,外键customerId表明这个保单是哪个客户的,同时unit表明出该保单的机构,insertTime也是插入时间。

业务背景

前端列表显示出每一天投保的客户信息(客户连续两天投保,则显示两条该客户数据,如上面intsmaze客户),点击每条记录的详情可以查看该客户当天的保单详情。

审核权限划分:一个客户一天投保的多个保单可能会来自多个出单机构,比如上面intsmaze,06-21的三个保单出自上海,北京,深圳,那么怎么划分,借助group by的"随缘法则",intsmaze 06-21号就取数据插入顺序最前的上海,特朗普 06-21 就取杭州。

他们的原产sql

代码语言:javascript
复制
SELECT * from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='0'
GROUP BY c.customerId

查询的结果是两条数据,很显然少了一条intsmaze 06-22号的

虽然有问题,但是感觉很难爆出给用户的,它是怎么出现的了?

这要说审核流程了,默认数据进来是初审,用户表的flow是0。

当用户审核intsmaze的这一条数据后,数据变得如下

 我们可以看到flow='0'初审,intsmaze的unit由上海变成了北京,那是因为这条问题sql隐藏的数据终于出现了。

此时flow='1'复审的数据如下

然后有趣的事情来了,审核人员此时又将初审的intsmaze 北京 提交到复审,这个时候复审应该有两条数据,但是他到复审那里还是就看到一条数据。然后就出大事了,最后我就马革裹尸过来救火了。

解决方案

join的时候是几个字段,group by就几个字段,加上insertTime即可

代码语言:javascript
复制
SELECT * from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
GROUP BY c.customerId,c.insertTime

unit判断,导致同一条数据两个机构均可审核

他的unit的判断放在join后的where条件上

代码语言:javascript
复制
SELECT * from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='1' and i.unit='北京'
GROUP BY c.customerId

这导致一个有趣的问题就是,比如intsmaze 06-21 这个客户,它分别能被北京,上海,深圳三个机构看到,其他机构是看不到。然后就出现一个有趣的现象:"谁动了我的数据,我明明没有审核,为什么到复审了,北京复审页面看到这条数据初审提交人事上海,这是怎么一回事嘛?"。

这个问题我只显示结果,不想解释,最后附上解决方案。

代码语言:javascript
复制
SELECT * from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='1'
GROUP BY c.customerId

这个客户本来是该上海机构去审核

可是我发现,如果北京机构人登录,也是可以看到这条记录进行审核

代码语言:javascript
复制
SELECT * from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='1' and i.unit='北京'
GROUP BY c.customerId
如何解决,子表呗
代码语言:javascript
复制
SELECT * from (
SELECT c.customerId,c.insertTime,unit,money from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='1' 
GROUP BY c.customerId
)temp 
where temp.unit='北京'

最终我提供的sql模板如下:

代码语言:javascript
复制
SELECT * from (
SELECT c.customerId,c.insertTime,unit,money from customer c LEFT JOIN insurance i
on c.customerId=i.customerId and c.insertTime=i.insertTime
where c.flow='1'
GROUP BY c.customerId,c.insertTime
)temp where temp.unit='北京'

模板提供后,剩下的事情当然不是我去改了,毕竟我已经吐了几口血了。我只负责找出问题,提供解决方案,然后功能顾问就全方位的改自己的sql。我则一旁陪伴直至改完后,系统没有出现他们无法解决的毛病后就离场修身养性咯。

ps:救了几次火后,我晓得当初为什么我被面试,别人问我你开发中遇到什么奇怪的bug没,我当时真的没有啊,我确实没有遇到什么奇怪的bug,因为你如果真的按照语法规则开发,其实很多问题都是不会出现的。之所以会出现,往往是基础太薄弱,然后也不理解上来就模仿,然后就会出错。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •  很简单的一对多表关联
  • 业务背景
    • 虽然有问题,但是感觉很难爆出给用户的,它是怎么出现的了?
      • 解决方案
      • unit判断,导致同一条数据两个机构均可审核
        • 如何解决,子表呗
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档