真巧,昨天剛寫了關於資料庫連續問題的解決方案,沒想到今天下午兩點就有朋友在上海拼多多面試非技術崗位中就遇到了相似的問題。下面是原題:
一個最大連續支付失敗的次數 有一張支付流水錶pay;欄位如下
id | uid | time | status |
---|---|---|---|
pay_01 | 1 | 2024-01-15 10:00:00 | fail |
pay_02 | 1 | 2024-01-15 10:00:20 | success |
求每個使用者的最大連續支付失敗次數
輸出欄位:uid,cnt(失敗次數)
如果我朋友看過我昨天寫的資料庫查詢連續資料的文章,那麼至少會有一些思路,而不是寫的一塌糊塗了哈哈哈。
思路
就像我昨天寫的一樣,連續問題,創造一個連續列來和目標判斷是否連續的列相比較是比較簡單的一種辦法。
比如題目中,需要時間連續的某人最大的支付失敗數量,那麼就需要按照時間排序了,那麼如何判斷時間連續,題目中並沒有規定時間的出現頻次,所以直接和時間來做比較判斷連續並不是一個好的解決辦法。
這裡其實最簡單的就是生成兩次行號了。
步驟
1.按照使用者編號開窗,按照時間排序,增加行號,這樣就得到了每個使用者按照時間排序的訂單序號。
2.篩選掉支付訂單成功的,再根據使用者編號開窗,按照時間排序,增加行號,這樣就得到了每個使用者按照時間排序的失敗的訂單的序號。
3.兩個序號相減,相等的數字則表示連續。
4.按照使用者和得到的數字分組,或者最大的組,就是最大的連續支付失敗的訂單數量。
WITH ContinueCustomer AS(
SELECT p1.*, p1.rowNumber - RANK() over(PARTITION by p1.uid ORDER BY p1.time) as diff FROM (
SELECT *,RANK() over(PARTITION by uid ORDER BY time) as rowNumber FROM pay
) p1 WHERE p1.status = 'fail'
),
EveryContinueCustomerCounts AS(
SELECT uid,count(1) as times FROM ContinueCustomer GROUP BY uid,diff
)
SELECT uid,max(times) as cnt FROM EveryContinueCustomerCounts GROUP BY uid
總結
萬變不離其宗,希望大家面試順利。