with t1 as( select l.customer_id,l.overdue_days,c.pay_ability from loan_tb l join customer_tb c on l.customer_id = c.customer_id ), t2 as ( select pay_ability, count(customer_id) as customer_count, count(case when overdue_days is not null then 1 end) as overdue_customer from t1 group by pay_ability order by pay_ability ) select pay_ability, CONCAT(round(overdue_customer / customer_count * 100,1),'%') as overdue_ratio from t2 order by overdue_ratio desc
Your code is solving the problem step by step by using two Common Table Expressions (CTEs), which break down the logic into manageable parts. Let's break it down in detail:
1. CTE t1
: Join Loan and Customer Tables
with t1 as( select l.customer_id, l.overdue_days, c.pay_ability from loan_tb l join customer_tb c on l.customer_id = c.customer_id )
- Purpose: This CTE (
t1
) combines the two tables,loan_tb
andcustomer_tb
, based on thecustomer_id
column. - Columns Selected:l.customer_id: The customer ID from the loan_tb table.l.overdue_days: The number of days the customer is overdue on their loan from the loan_tb table.c.pay_ability: The repayment ability level of the customer from the customer_tb table.
- Join Operation: The
JOIN
clause joins the two tables oncustomer_id
, ensuring that you have theoverdue_days
andpay_ability
for each customer. - Result: The
t1
CTE will output a dataset with each customer'scustomer_id
,overdue_days
, andpay_ability
.
2. CTE t2
: Count Customers and Overdue Customers by Repayment Ability
t2 as ( select pay_ability, count(customer_id) as customer_count, count(case when overdue_days is not null then 1 end) as overdue_customer from t1 group by pay_ability order by pay_ability )
- Purpose: This CTE (t2) aggregates the results from t1 by repayment ability (pay_ability). It calculates two key things:customer_count: The total number of customers in each repayment ability group.overdue_customer: The number of customers in each repayment ability group who have overdue days (overdue_days is not null).
- Logic:count(customer_id) as customer_count: This counts the total number of customers for each pay_ability group.count(case when overdue_days is not null then 1 end) as overdue_customer: This counts the customers who have overdue days, i.e., customers who are overdue on their loan. overdue_days is not null ensures that only customers with overdue days are counted.
- Grouping: GROUP BY pay_ability ensures the count is done separately for each repayment ability group (A, B, C, etc.).
- Ordering: ORDER BY pay_ability orders the results by repayment ability level (this is not necessary for the final output but may help with debugging or clarity).
3. Final Select: Calculate Overdue Customer Percentage
select pay_ability, CONCAT(round(overdue_customer / customer_count * 100, 1),'%') as overdue_ratio from t2 order by overdue_ratio desc
- Columns Selected:pay_ability: The repayment ability level of the customer.CONCAT(round(overdue_customer / customer_count * 100, 1),'%') as overdue_ratio: This calculates the percentage of overdue customers in each repayment ability group.overdue_customer / customer_count * 100: This calculates the ratio of overdue customers to the total number of customers in the group, multiplied by 100 to convert it to a percentage.round(..., 1): The round() function rounds the result to 1 decimal place.CONCAT(..., '%'): The CONCAT() function appends the % symbol to the calculated percentage.
- Result: This gives you the percentage of overdue customers for each repayment ability level, rounded to one decimal place, with the % sign appended.
- Ordering: ORDER BY overdue_ratio desc sorts the final results in descending order based on the overdue percentage, meaning repayment ability levels with higher overdue percentages will be shown first.