在很多情況下,你會希望知道一列(或一組列)在總列數所佔的比重。換句話說,即是一列佔總計數的百分比是多少。為了說明這一點,讓我們看看以下顯示在 Navicat Premium 16 中的資料表:

透過將count() 函數和 Group By 子句結合,我們可以很容易地找出每種水果有了多少訂單:

那麼現在我們如何查看每種水果的訂單佔訂單總數的百分比?事實上,在 SQL 中有三種計算列百分比的標準方法。他們是:
- 使用 OVER() 子句
- 使用子查詢
- 使用一般資料表運算式,或 CTE
本文的其餘部分將依次探討其中的每一種。
OVER() 子句
OVER 子句主要與視窗函式一起使用,用於判斷將查詢中的哪些列套用於函式、該函式以什麼順序計算這些列以及何時重新開始函式的計算。
OVER 子句是 SQL 中計算列百分比的最有效方法,因此如果你最著重效率,它應該是你的首選。以下是獲得百分比的公式:
count(*) * 100.0 / sum(count(*)) over()
將上述 SQL 加到原本的查詢中會產生以下結果:

看起來不錯,但稍微四捨五入也沒什麼壞處。不幸的是,使用 over() 子句並不容易做到這一點。也許下一個選項會更適合你。
使用子査詢
並非所有資料庫都支援 OVER() 子句,因此子查詢方法可能是非常有用的後備解決方案。它有時被稱為「通用解決方案」,因為它適用於所有資料庫。這種方法的另一個好處是它是最易與 Round() 等函式合併使用。 以下是我們需要加到查詢中的內容:
count(*) * 100.0 / (select count(*) from <YourTable>)
以下是實行的通用解決方案:

使用一般資料表運算式(CTE)
With common_table_expression 子句指定一個臨時命名結果集,稱為一般資料表運算式(CTE)。然後,我們可以從臨時結果集中進行選取,以將更多函式套用於擷取的欄位。在我們的例子中,我們可以將 sum() 函式套用於計數以得到百分比:

請記住,這種方法效率最低,因為 CTE 基本上針對內部(初始)查詢的結果執行第二個查詢。話雖如此,有時你可能需要使用 CTE 執行無法一次輕鬆完成的額外處理。
總結
在這篇文章中,我們學習了三種方法來表示一列(或一組列)在總列數所佔的比重。每種方法都有自己的優點和缺點,因此你必順根據自己的具體需求選擇。
如果你想試用 Navicat 16,可以在這裡下載 Navicat 的 14 天全功能免費試用版。