日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sql decimal函数例子_leetcode题库-sql练习精讲系列--三、经典排名问题

發布時間:2025/3/12 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql decimal函数例子_leetcode题库-sql练习精讲系列--三、经典排名问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是一個系列文章,這個系列的理念是通過一道題,搞懂一類題。涵蓋了SQL面試最常考的知識點。搞懂這些題,面試時工作中sql不可能有問題。

文章分為引入問題-完整解析-答案-leetcode題和答案-知識點拓展-BAT等大廠面試真題幾個部分。

希望能幫你全方位的弄懂。有問題可以留言,碼字不易,寫一篇要好幾個小時,希望能得到點贊收藏哦。

一、問題

下圖是"01課程成績"表中的內容,記錄了每個學生學生編號,課程編號和成績。

現在需要根據成績來排名,如果兩個分數相同,那么排名要是并列的。

比如題目中的成績從大到小排序應該是80,80,76,70,50,31。分數相同排名并列,那么6位同學的排序應該是1,1,3,4,5,6。

二、數據準備

create table 成績 (`學生編號` varchar(10), `課程編號` varchar(10), `成績` decimal(18,1));insert into `成績` values('01' , '01' , 80); insert into `成績` values('02' , '01' , 70); insert into `成績` values('03' , '01' , 80); insert into `成績` values('04' , '01' , 50); insert into `成績` values('05' , '01' , 76); insert into `成績` values('06' , '01' , 31);

【解答】

[解題思路]

  • 處理分組排名問題,可以使用窗口函數
  • 根據題干的要求兩個分數相同,那么排名要是并列的。我們根據 rank, dense_rank, row_number 這三個窗口函數的結果看一下它們的區別。
  • select *,rank() over (order by 成績 desc) as `rank`,dense_rank() over (order by 成績 desc) as dese_rank,row_number() over (order by 成績 desc) as row_num from 成績

    從上面的結果圖中的紅色框可以看出:

    • rank():跳躍排序;同分并列,但會占用下一個排名名額。
    • dense_rank():連續排序;單詞直譯為密集排序。同分并列,不占用下一個排名名額。
    • row_number():沒有重復值的排序(記錄相等也是不重復的),可以進行分頁使用。

    3.根據題目中要求的分數相同,排名并列,且占用下一個名額。所以我們使用rank()函數。

    [代碼]

    select *,rank() over (order by 成績 desc) as `rank` from 成績

    [leetcode題庫問題-178. 分數排名]

    編寫一個 SQL 查詢來實現分數排名。

    如果兩個分數相同,則兩個分數排名(Rank)相同。請注意,平分后的下一個名次應該是下一個連續的整數值。換句話說,名次之間不應該有“間隔”。

    例如,根據上述給定的 Scores 表,你的查詢應該返回(按分數從高到低排列):

    [參考答案]

    select score, dense_rank() over(order by Score desc) as Ranking from Scores;

    [知識點講解]

    [窗口函數是什么]

    窗口的概念非常重要,它可以理解為記錄集合,或者理解為分區。窗口函數也就是在滿足某種條件的記錄集合上執行的特殊函數。對于每條記錄都要在此窗口內執行函數,有的函數隨著記錄不同,窗口大小都是固定的,這種屬于靜態窗口;有的函數則相反,不同的記錄對應著不同的窗口,這種動態變化的窗口叫滑動窗口。

    窗口函數和普通聚合函數也很容易混淆,二者區別如下:

    • 聚合函數是將多條記錄聚合為一條;而窗口函數是每條記錄都會執行,有幾條記錄執行完還是幾條。
    • 聚合函數也可以用于窗口函數中。

    [窗口函數語法]

    函數名([expr]) over 子句 :

    over是關鍵字,用來指定函數執行的窗口范圍,如果后面括號中什么都不寫,則意味著窗口包含滿足where條件的所有行,窗口函數基于所有行進行計算;如果不為空,則支持以下四種語法來設置窗口:

    ?```sql select * from( select row_number()over w as row_num,order_id,user_no,amount,create_datefrom order_tabWINDOW w AS (partition by user_no order by amount desc))t ; ?```
    • window_name:給窗口指定一個別名,如果SQL中涉及的窗口較多,采用別名可以看起來更清晰易讀。上面例子中如果指定一個別名w,則改寫如下:
    • partition子句:窗口按照那些字段進行分組,窗口函數在不同的分組上分別執行。上面的例子就按照用戶id進行了分組。在每個用戶id上,按照order by的順序分別生成從1開始的順序編號。
    • order by子句:按照哪些字段進行排序,窗口函數將按照排序后的記錄順序進行編號。可以和partition子句配合使用,也可以單獨使用。上例中二者同時使用,如果沒有partition子句,則會按照所有用戶的訂單金額排序來生成序號。
    • frame子句:frame是當前分區的一個子集,子句用來定義子集的規則,通常用來作為滑動窗口使用。比如要根據每個訂單動態計算包括本訂單和按時間順序前后兩個訂單的平均訂單金額,則可以設置如下frame子句來創建滑動窗口:

    [窗口函數匯總]

    • CUME_DIST(): 函數計算一組值中的值的累積分布。
    • LAG(): 對當前行之前的指定物理偏移量的行的訪問。
    • LEAD(): 對當前行之后的指定物理偏移量的行的訪問。
    • NTILE(): 有序分區的行分配到指定數量的大致相等的組或桶中。
    • PERCENT_RANK(): 函數計算結果集的分區中值的相對位置。
    • DENSE_RANK()
    • RANK()
    • ROW_NUMBER()

    四、大廠面試真題

    [支付寶面試真題] 找出支付金額在累計前20%的用戶

    現有交易數據表user_sales_table如下:

    user_name 用戶名

    pay_amount 用戶支付額度

    找出支付金額在累計前20%的用戶。

    輸出要求如下:

    user_name 用戶名(前20%的用戶)

    /* ntile(5) over(order by sum(pay_amount) desc) as level 按照支付金額累計倒序排列后分成大致相同的5組。 */select b.user_name from(selectuser_name,ntile(5) over(order by sum(pay_amount) desc) as level -- 分成5組from user_sales_table group by user_name ) bwhere b.level = 1

    總結

    以上是生活随笔為你收集整理的sql decimal函数例子_leetcode题库-sql练习精讲系列--三、经典排名问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。