一条SQL实现数值占比计算,拒绝嵌套查询

一条SQL实现数值占比计算,拒绝嵌套查询

提示:在日常的工作项目中,会有需要获取数值占比计算的需求,我们改如何给他做到通用简洁化呢?
我们一般的项目中往往会选择再一次嵌套查询去计算占比值,但是如果我们的项目中需要进行配置、通用起来的情况下,会给我们造成很大的困扰。


前言

提示:
为此,我考虑不以嵌套的形式,一条sql直接输出我们想要的数值占比,通过只需改变字段名称,就可直接获取占比值,一并返回,实现我们的高可用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、通过with rollup函数,进行小计,而后取最后一个值,获取总数。

支持多种数据库,oracle 、vertica ,因其中涉及窗口函数,mysql得在8.0以上的版本。

以下是mysql案例介绍。

  --只针对mysql8.0以上版本,其余数据库正常使用
  select id ,
       count(1)                   as count,
     concat(round(cast(count(1) /
                         last_value(count(1))
                         over (order by count(1) rows between unbounded PRECEDING AND unbounded FOLLOWING) as FLOAT) *
                    100, 2), '%') as radio
from user
where id in (1, 2, 3)
group by id 
with rollup;

解析:我以USER表为例,首先通过分组获取每组count的值,然后通过with rollup函数 获取 (总计),
在通过last_value() over()函数去获取最后一个总计的数值,最后就是一些计算百分比的函数进行返回

注:last_value 函数是对某个字段往下取值 over() 中 rows between unbounded PRECEDING AND unbounded FOLLOWING ;

说明:这是窗口函数,PRECEDING 意为 从第几个开始,FOLLOWING 偏移量是多少。
例 rows between 1 PRECEDING AND 2 FOLLOWING 从第一个值往下走两步,也是是第三列的值。
unbounded 是无界限的意思,
如果单是 unbounded PRECEDING 则就是取第一个值。联合起来也就是上的案例取最后一个值。

针对其他数据库,考虑with rollup替换。例 :vertica 替换为 rollup

二、使用sum() over()高级函数。

需求:统计学生某时间段内,学生阅读了多少本图书及其所有在所有学生中阅读的占比。
直接上例子。

select 
	name 学生名称, 
	sum(read_book) 各学生阅读数, 
	sum(sum(read_book)) over(order by read_book desc rows between unbounded PRECEDING AND unbounded FOLLOWING) 所有学生阅读数 //占比率两者相除即可
from user
group by name //学生名称分组

适用范围:mysql8.0及以上,oracle、vertica等。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值