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_id customer_age pay_ability
1111 28 B
1112 38 A
1113 20 C
1114 30 A
1115 29 B
1116 21 C
1117 35 B
1118 36 B
1119 25 C

loan_tb表

agreement_id customer_id loan_amount pay_amount overdue_days
10111 1111 20000 18000
10112 1112 10000 10000
10113 1113 15000 10000 38
10114 1114 50000 30000
10115 1115 60000 50000
10116 1116 10000 8000
10117 1117 50000 50000
10118 1118 25000 10000 5
10119 1119 20000 1000 106

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

pay_ability overdue_ratio
C 66.7%
B 25.0%
A 0.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。

你可能感兴趣的:(从零开始学数据库,sql,数据库,mysql)