需求: 多张表(个数不定,需求不是非常明确,只有一个大致需求)根据业务需求统计出一些数据 (按天统计,数据有多条校验规则)进行上传。
注意: 校验数据是否正确是需要第三放来反馈的,而且第三方的测试环境是忽略校验规则。
1. 由于需求字段的来源本身就不是很明确, 加上我们库里的数据 本身就有错误,可能需要手动调整。加之第三发的测试环境是忽略规则校验的,也就是说你没法知道你写的对不对,只能在
生产环境看反馈 。 所以如果你用程序去写生成数据过程,多次修改bug 是基本上会发生的事情,而正式环境显然没法让你来回多次发版(坑爹的三方)。所以建议优先考虑使用sql 直接写(过程,函数。总之直接操作数据库),
sql 比较难,用程序一定要多注意下面的几个问题。
2. 数据不可能一次全部正确,那么就要报错,这个时候必要的冗余字段就能帮你快速定位错误原因。 建议多冗余一些表的主要字段和关联字段。
1. 比如被统计的表的主键(或者数据唯一的某列),便于以后数据对比。
2. 比如我们统计的依据(我是根据修改时间统计的,那就最好记录这个时间,否则到时候时间变了,你说是你统计的时候出错了,还是别人把时间改了呢,无法判定。)
3 比如需要计算得出的数据,最好把你计算的依据也一并保存,即使这些数据以后发生了变化,我也能用这些冗余数据来佐证我的计算没有问题,是别人改了这些数据。
4. 预留一些状态字段,并在操作时使用一些默认值。如我只认为状态是1 的是正常数据(可以把1设为默认)。 这样,如果对数据有疑问,可以先修改状态为0 。
3. 数据按天生成的,每天有很多数据,上报之前我并不知晓其有错误,上报后发现有几条有小错误。 但是我们任务比较急,就先把错误的给删掉了,把正确的先传上去。
删除一时爽,但是这些错误数据后续还是要补上的,这就郁闷了。我们是备份然后删除,如何恢复?导入 然后修改。 然后所有数据重新上传(为什么不只上传错误的?错误的每天都有,而且导入后也没有特定错误标识,
而且上传也是程序按天上传)。
这里有两个问题: 1. 备份删除导入, 2. 重新 全部 上传
想到一个办法: 就是表加个标识,标识未校验通过, 校验通过 ,已上传, 没有有错误的数据,我们sql 命令 处理为校验通过,然后上传后改为已上传。 当然如果是错误很多还是全部上传吧。。
这个主要功能还是为了解决删除备份的问题。
4. 常规想法,由于我一次没有把所有需要的值都查出来(可以认为已经查出来是主要数据),那么剩下的字段我就循环主要数据,然后每次去查表获取次要数据进行更新。
那么有一个问题:我是否需要循环每次去查次要表。如果次要表数据不多的话,建议直接对主数据做关联次表做update . 当然如果次表较大就不行了,因为两表关联update 真的很慢,最好还是循环每条去update .
5. 写存储过程时应尽量少的增删改操作,尤其对较大的表操作,耗时实在太长。
6. 必要的状态字段(很重要),这个是程序设计的方面。没经验,以为一次成功,没有任何状态相关字段,但是现实每次生成数据都要很长时间,发现数据有问题,没有修改的处理,删了吧再生成有很慢,而且错误数据
并不一定是程序问题,也有一部分是原始数据本身就有问题,比如这部分数据不上报,那就需要状态标识了。。 设计很重要。
7. sql 中的坑:
需求: 查询A表中字段c的值 不等于 B表中 统计的条数值。 (或者换个明了的需求: A说我有50 个学生, B是学生表,但是一统计发现 A 只有49个学生。)
1. 使用exist ,先统计B 表,然后根据关联字段 关联,判断不相等。
select * from A where EXISTS ( select 1 from (select PROJECT_NO,count(id) as c from B GROUP BY PROJECT_NO) x1 where t.project_no = x1.project_no and t.BORROWER_NUM!=x1.c);
坑来了,如果B有相关记录,不管几条,只要有就行。这个sql 没问题。 但是如果B 中一条记录都没有呢:
t.project_no = x1.project_no 这一句判断就已经是false ,这样后边的 t.BORROWER_NUM!=x1.c 被忽略, 结果就是不存在。而这条错误数据也被排除掉了。 然而这显然是一条数据错误,B 为空,这个A 没有学生。
总结: exists 是存在判断,建议where 条件中一定是 相等判断。 如果条件中有不等判断,可以使用not exists . 亲历不建议使用exist 太绕了。。
2. 使用left join on + 非等号的条件:
select a.* from a left b on a.x = b.x and a.y!=b.y; 看这个条件: 我想查询x相等并且 y 不相等的记录。。 但是最后发现不管y 是否相等,都被查出来了。这个是因为on 后面只对b有筛选作用。
使用inner join 也是不对的: 会把a 中比b 多的条数直接过了的,因为连x 都找不到相等。
可以使用where a.y!=b.y ..先关联然后筛选。
总结: 如果on 后有多个条件要慎重,最好使用同样比较符号,如都是用= 。 最好不要混着用。很容易出错。
综上: 关联条件尽量单一,如果实在有多个也建议使用同类比较符号。 如果还不行,建议结合where ..
20190316 今天需求又提了个要求,要计算提前还款,逾期等,又是一个坑。。
查了下表 : 还款明细在一列存着,,是个拼接字符串。每期一条: 包含金额,还款情况等。 没法查啊。
所以, 虽然存到一个列里,查询的时候很简单。。但是要去分析里面的内容的时候就坑了。。以后遇到这种可以考虑加张表 ,分多条存储,然后关联主表。
今天写sql 语句的时候还遇到一个问题 就是字符格式的 数字 : 如果是sum 是可以进行正常计算使用。 但是在进行 order by , min , max 时候要注意,可能出来的结果并不是你想要的。 可以使用to_number 转换为数字再使用。
20190425 补充:
由于该统计数据是直接报送到第三方,所以并没有涉及相关可视页面,并且是由技术和三方直接对接,所以既没有需求人员也没有测试人员。
做的时候并没有觉得问题,但后续发现有些内容直接需求理解错误。这种情况如果有需求人员确认,加上后来的测试人员测试提出,完全是可能避免发生的。
所以请尽量配有相关需求人员,不应直接有程序员和其他业务沟通,即使没有可视化页面,也应有相关测试人员参与。(你很难看到自己的错误)