作者:刘晨
网名 bisal,具备十年以上的利用运维工作教训,目前次要从事数据库利用研发能力晋升和技术治理相干的工作,Oracle ACE,腾讯云 TVP,领有 Oracle OCM & OCP、EXIN DevOps Master、SCJP 等国内认证,国内首批 Oracle YEP 成员,OCMU 成员,《DevOps 最佳实际》中文译者之一,CSDN & ITPub 专家博主,公众号 ”bisal 的集体杂货铺 ”,长期保持分享技术文章,屡次在线上和线下分享技术主题。
本文起源:原创投稿
* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。
共事提了一个 MySQL 数据库中 SQL 统计数据的问题,我用测试数据模仿一下,如下所示,表 tt 有三个字段,code 是标识名称,cdate 是对应的日期,ctotal 是个统计值
原始的统计语句如下所示,依照 code 和 cdate 进行聚类,统计出每个 code 每个月累加的记录数,
然而他的需要是能依照 code+cdate 的统计值进行累加显示,例如上图中第一行的 total 是 10,第二行的 total 就显示 10+9=19,第三行的 total 就显示 10+9+11=30,以此类推。
他须要的是 total 逐行累加,MySQL 中能够通过定义变量累加来实现,如下所示,利用 @i 逐行累加,
的确看着实现了,然而有个问题,不同的 code,并未做归零解决,例如上图中,code=BBB 的第一行记录,total 应该是 5,以后的 35 则显著是通过 30+ 5 失去的。
此处应该再加个逻辑,即依照 code 聚类的同时做 sum 求和计算,如下所示,此时就能够看到,g_total 依照 code 和 cdate 进行累加,不同的 code,就会归零,从新计算,符合实际需要,
其实这块还能够持续优化,MySQL 8.0 反对 with,如上 SQL 中对 tt 表读了两次,借助于 with,就能够升高为只读一次 tt 表,
另外,结合实际的检索场景需要,思考为相干字段减少索引,进一步晋升数据检索的效率。
当然,以上的 SQL 可能有其余的代替计划或者更好的计划,本文只是给出了其中一种解决的门路。
因而,通过 SQL 实现业务需要,一方面须要充沛了解需要的含意,能精确地映射到具体的 SQL 逻辑上,另一方面则要理解所用数据库反对的函数、性能、个性等,是否有能符合到这个需要的实现,除此之外,非性能的因素,也是不可漠视的,适合的索引、防止反复读数据、防止不必要的排序等都是咱们能够利用的伎俩。