SQL笔试题 分组计算比例+保留小数不够补0+连接字符串【cast、round、decimal、concat函数】

蚂蚁的一道笔试题。

本题相关SQL可在线运行:View on DB Fiddle

题面

 drop table if exists  `loan_tb` ; 
 CREATE TABLE `loan_tb` (
 `agreement_id` int(11) NOT NULL,
 `customer_id` int(11) NOT NULL,
 `loan_amount` int(11) NOT NULL,
 `pay_amount` int(11) NOT NULL,
 `overdue_days` int(11),
 PRIMARY KEY (`agreement_id`));
 INSERT INTO loan_tb VALUES(10111,1111,20000,18000,null); 
 INSERT INTO loan_tb VALUES(10112,1112,10000,10000,null); 
 INSERT INTO loan_tb VALUES(10113,1113,15000,10000,38); 
 INSERT INTO loan_tb VALUES(10114,1114,50000,30000,null); 
 INSERT INTO loan_tb VALUES(10115,1115,60000,50000,null); 
 INSERT INTO loan_tb VALUES(10116,1116,10000,8000,null); 
 INSERT INTO loan_tb VALUES(10117,1117,50000,50000,null); 
 INSERT INTO loan_tb VALUES(10118,1118,25000,10000,5); 
 INSERT INTO loan_tb VALUES(10119,1119,20000,1000,106); 
 
 drop table if exists  `customer_tb` ; 
 CREATE TABLE `customer_tb` (
 `customer_id` int(11) NOT NULL,
 `customer_age` int(11) NOT NULL,
 `pay_ability` varchar(2) NOT NULL,
 PRIMARY KEY (`customer_id`));
 INSERT INTO customer_tb VALUES(1111,28,'B'); 
 INSERT INTO customer_tb VALUES(1112,38,'A'); 
 INSERT INTO customer_tb VALUES(1113,20,'C'); 
 INSERT INTO customer_tb VALUES(1114,30,'A'); 
 INSERT INTO customer_tb VALUES(1115,29,'B'); 
 INSERT INTO customer_tb VALUES(1116,21,'C'); 
 INSERT INTO customer_tb VALUES(1117,35,'B'); 
 INSERT INTO customer_tb VALUES(1118,36,'B'); 
 INSERT INTO customer_tb VALUES(1119,25,'C'); 

customer_tb表

customer_idcustomer_agepay_ability
111128B
111238A
111320C
111430A
111529B
111621C
111735B
111836B
111925C

loan_tb表

agreement_idcustomer_idloan_amountpay_amountoverdue_days
1011111112000018000
1011211121000010000
101131113150001000038
1011411145000030000
1011511156000050000
101161116100008000
1011711175000050000
10118111825000100005
101191119200001000106

要求分组计算每个pay_ability中违期还款的比例(overdue_days不为空),并降序排序,输出结果:

pay_abilityoverdue_ratio
C66.7%
B25.0%
A0.0%

答案 & 思路

select pay_ability,
concat(cast( round((cast(count(overdue_days) as double)/cast(count(*) as double)),3)*100 as decimal(10,1)), '%')
as overdue_ratio
from customer_tb join loan_tb on customer_tb.customer_id=loan_tb.customer_id
group by pay_ability
order by overdue_ratio desc;

大致思路就是两表连接,分组,然后比较麻烦的是算比例。

最初始计算方法是count(overdue_days)/count(*),分子选出overdue_days不为空的行,分母选出所有的行。

然后还需要各种细节处理,比如:

  • 使用cast函数转换成double类型
  • 使用round函数进行四舍五入,保留3位之后乘100
    • 格式:round(x, 3),x表示原数字,3表示四舍五入到3位小数
  • 使用decimal函数控制小数个数,不够自动补0。
    • 格式:cast(x) as decimal(10,1),10表示最大位数,1表示小数位数,x表示格式化的数字
  • 使用concat函数连接字符串,加上"%"
    • 格式:concat(str1, str2)

即:concat(cast( round((cast(count(overdue_days) as double)/cast(count(*) as double)),3)*100 as decimal(10,1)), '%')

对于声明语法DECIMAL(M,D),自变量的值范围如下:
M是最大位数(精度),范围是1到65。可不指定,默认值是10。
D是小数点右边的位数(小数位)。范围是0到30,并且不能大于M,可不指定,默认值是0。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nefu-ljw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值