【数据库】SQL极速入门(多种方式查询用户复借次数)
??最近遇到這樣一個事:許多DBA的小伙伴不太明白金融業務中復借用戶的定義方式以及sql查詢方式,給他們提需求也整不明白,需求如下:
??根據訂單編號,查詢用戶該訂單所對應的復借次數(白話講就是:我有一筆訂單,想看看這筆訂單是用戶在本平臺的第幾筆訂單)
??既然他們整不明白,那就自己寫吧。
??下面簡單介紹下“復借”,再列舉幾種在mysql、oracle數據庫中統計用戶復借次數的方式。sql能力就是一點點提升的,希望能夠拋磚引玉,窺一斑而知全豹。
一、如何定義復借
??復借是指在一個貸款平臺借款訂單還清后繼續申請貸款的行為
??復借次數即為該用戶累計成功借還款的總次數
??在數據庫中,統計復借這個指標,用到的基本為還款表:即每個用戶(user_id)的每一筆訂單(apply_id)對應的還款情況(是否到期,是否成功還款)。
??基本思路:成功還款1次,復貸次數+1
??另外,考慮產品記期方式不同,我們分單期和多期兩種產品來討論
二、單期產品
方法1:Mysql之子查詢計數
??簡單的說,就是兩張相同的表做左外聯,統計user_id相同時,第一張表apply_id比第二張表apply_id大的數據
??內聯子查詢:生成兩張相同的表,然后做左外聯,這樣表2中與表1user_id相同的數據就都會被查詢得到,結果如下:
??再用where做一層判斷,把表1比表2apply_id大的數據篩選出來。效果如下:
:
??對應的sql大致如下:
select * from(SELECT * FROM repayment ) a left join (SELECT * FROM repayment ) b on a.user_id = b.user_id and a.apply_id > b.apply_id??接下來分組統計apply_id計數,即可求得復借次數,下面為實操sql:
select a.user_id,a.apply_id,count(b.apply_id) loan_nfrom (SELECT r.user_id,r.apply_idFROM`repayment` r LEFT JOIN app_user u ON r.user_id = u.id WHERE `repay_status` = '已還' ) a left join (SELECT r.user_id,r.apply_idFROM`repayment` r LEFT JOIN app_user u ON r.user_id = u.id WHERE `repay_status` = '已還' ) b on a.user_id = b.user_id and a.apply_id > b.apply_id group by a.user_id,a.apply_id ORDER BY a.user_id,loan_n??結果如下:
方法2:Oracle之分析函數
??Oracle較mysq而言,增加了許多高級函數,常用的分析函數如下:
??OVER(PARTITION BY… ORDER BY…)的使用說明和意義:
??顧名思義,PARTITION 中文是分割的意思,ORDER 是排序的意思,所以翻譯一下就是先把一組數據按照指定的字段進行分割成各種組,然后組內按照某個字段排序。
??那我們大致的思路,就是先按照user_id對用戶訂單進行分組,再按照apply_id的大小進行一個正序排序,就是這么簡單。
select user_id,apply_id,row_number() over(partition by user_id order by apply_id)-1 loan_n from repayment??和mysql處理后的效果一樣
方法3:Mysql 自定義變量 實現高級分析函數的功能
??Mysql暫不支持lag()、lead()等統計函數,我們用自定義變量的方法來實現這個功能。
??大致思路為: 固定列A(user_id列),定義兩個自變量B(@user_id)、C(@rank),sql執行過程中動態比較A與B(注意細節,實際比的是A(n)與B(n-1)),如果一致,變量C(n)計數+1;如果不一致,變量C(n)重置為0。
??也就是,sql按行執行的過程中,累計統計user_id為相同值的數量(一般實現排序功能,都這么用)
??如下圖,第一行user_id為4,@user_id(自定義變量)為空,rank就為0;第二行user_id為4,@user_id已更新為4,兩數對比相同,rank就+1為1;第三行user_id為4,@user_id更新為4,兩數對比相同,rank就+1為2;第四行user_id為21,@user_id更新為4,兩數對比不同,rank重置為0。以此類推
??sql實現步驟如下:
select b.user_id, b.apply_id, if(@user_id = b.user_id, @rank := @rank , @rank := 0) as loan_n,@user_id:=b.user_id from (SELECT r.user_id,r.apply_id,@user_id := null, @rank := 0#count(apply_id) loan_nFROM`repayment` r LEFT JOIN app_user u ON r.user_id = u.id WHERE `repay_status` = '已還'GROUP BY r.user_id,r.apply_idorder by user_id,r.apply_id )b??效果如下:
??較子查詢而言,這種方法執行效率更高。
三、多期產品
??多期產品需要注意的地方是:
??每一個訂單對應著不同期數的還款記錄。比如:6期的產品,就有6行貸后數據。我們要先把單筆借款的最后一期還款記錄單獨提取后再執行如單期產品相同的sql即可。
四、總結
-
今天,我們針對一個簡單的金融場景需求(統計復借次數)做了一些簡單sql的嘗試,主要成果如下:
- ① 金融產品復借次數的定義方法
- ② mysql、sql_server、oracle等數據庫對應的sql函數有區別。mysql在無法使用oracle的一些高級分析函數的時候,可以通過底層sql來實現一些如組內統計、組內排序的功能。
- ③ 到達一個目的地,往往有多條路徑,我們都想要找最優美的那條。
- ④ 小伙伴們如果還有其他實現這個功能的方式,歡迎評論,或者在公眾號留言。
??其實,sql能力的加強,就在于有效處理這種看起來簡單實際上復雜的問題,一次次的訓練,一次次的提升。
五、番外
??對數據分析、機器學習、數據科學、金融風控等感興趣的小伙伴,需要數據集、代碼、行業報告等各類學習資料,可添加微信:wu805686220(記得要備注喔!),也可關注微信公眾號:風控圏子(別打錯字,是圏子,不是圈子,算了直接復制吧!)
關注公眾號后,可聯系圈子助手加入如下社群:
- 機器學習風控討論群(微信群)
- 反欺詐討論群(微信群)
- python學習交流群(微信群)
- 研習社資料(qq群:102755159)(干貨、資料、項目、代碼、報告、課件)
相互學習,共同成長。
總結
以上是生活随笔為你收集整理的【数据库】SQL极速入门(多种方式查询用户复借次数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据处理】python数据评估常用指标
- 下一篇: 【特征工程】特征分箱