蚂蚁的一道笔试题。
本题相关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。