發現廣告阻擋器!
本站的開銷是靠廣告收入來彌補的。請將本站加入允許名單內。謝謝!
SQL 排名 | |
當我們在用SQL時,有不少情況下我們可以用不同的方式來解決同一個問題。列出每一行的排名就屬於這種情況。我們在這裡用兩種方法來計算排名:第一種是用窗口函數,第二種是不用窗口函數。 用窗口函數計算排名窗口函數本身就有三種計算排名的方式,要用哪一種我們可以按照實際需求來決定。假設我們有以下的表格:Total_Sales 表格
我們可以用以下的窗口函數來算出每一個人的排名: SELECT a1.Name, Sales, RANK() over (ORDER BY Sales DESC) RK
FROM Total_Sales ORDER BY a1.Sales DESC; 結果:
當我們用RANK()函數時,平手的資料會有一樣的排名。下一筆資料的排名只看有多少筆資料在它前面,而不管前面的資料中有沒有任何平手的狀況。所以在這個例子中,有兩筆資料並列第三,而下一筆資料是排第五。 我們也可以用ROW_NUMBER()函數。在這裡,SQL成為: SELECT a1.Name, Sales, ROW_NUMBER() over (ORDER BY Sales DESC) RK
FROM Total_Sales ORDER BY a1.Sales DESC; 結果:
由於Stella跟Jeff是平手,所以其中一筆資料會被列為第三,而另一筆會被列為第四。如果我們有特定的條件來讓平手的資料分出高低,那我們就需要將那個條件列在窗口函數內的ORDER BY。舉例來說,如果平手時我們要照Name的順序來排名,那SQL就成為: SELECT a1.Name, Sales, ROW_NUMBER() over (ORDER BY Sales DESC, Name) RK
FROM Total_Sales ORDER BY a1.Sales DESC; 結果:
不用窗口函數計算排名計算排名沒有一定要用窗口函數。在不用窗口函數的情況下,要以SQL列出排名的基本概念是要做一個表格自我連結 (Self Join),將結果依序列出,然後算出每一行之前 (包含那一行本身) 有多少行數。這樣講讀者聽得可能有點困惑,所以最好的方式是用一個實例來介紹。假設我們延續之前用的表格,我們可以打入以下的 SQL 語句: SELECT a1.Name, a1.Sales, COUNT(a2.Sales) Sales_Rank
FROM Total_Sales a1, Total_Sales a2 WHERE a1.Sales <= a2.Sales OR (a1.Sales=a2.Sales AND a1.Name = a2.Name) GROUP BY a1.Name, a1.Sales ORDER BY a1.Sales DESC, a1.Name DESC; 結果:
我們先來看 WHERE 子句。在字句的第一部分 (a1.Sales <= a2.Sales),我們算出有多少筆資料 Sales 欄位的值是比自己本身的值小或是相等。如果在 Sales 欄位中沒有同樣大小的資料,那這部分的 WHERE 子句本身就可以產生出正確的排名。 子句的第二部分,(a1.Sales=a2.Sales AND a1.Name = a2.Name),則是讓我們在 Sales 欄位中有同樣大小的資料時 (像 Stella 及 Jeff 這兩筆資料),仍然能夠產生正確的排名。在這裡我們的結果跟用窗口函數的RANK()產生的結果一樣。
|
本站的開銷是靠廣告收入來彌補的。請將本站加入允許名單內。謝謝!