首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

SQL 窗口函數實戰:查詢各地區銷售額最低的業務員

     編輯:程式設計綜合問答

問題描述

表結構:salesorder(orderid, region, sales, total),主鍵 orderid。
需求:查詢每個地區銷售金額最少的那筆記錄(即銷售額最低的業務員)。

核心解法:ROW_NUMBER / RANK / DENSE_RANK

現代 SQL (支援窗口函數的資料庫:MySQL 8.0+, PostgreSQL, SQL Server, Oracle, SQLite) 推薦使用 ROW_NUMBER():

SELECT orderid, region, sales, total
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY region ORDER BY total ASC) AS rn
    FROM salesorder
) t
WHERE rn = 1;

原答案寫法解析

SELECT * FROM (
    SELECT RANK() OVER (PARTITION BY region ORDER BY total) AS rid,
           orderid, region, sales, total
    FROM salesorder
) t WHERE t.rid = 1
  • 使用 RANK() 而非 ROW_NUMBER():若同一地區有多筆相同最低金額,RANK() 會產生相同排名(如 1,1,3),導致回傳多筆記錄;ROW_NUMBER() 則強制唯一編號(1,2,3),僅回傳第一筆。視業務是否允許「並列最低」決定選用哪個。
  • 子查詢別名 t、欄位別名 rid 命名清晰。
查詢結果示意圖
圖:各地區最低銷售額記錄結果示例

不支援窗口函數的舊版資料庫寫法

MySQL 5.7 或更舊版本可用關聯子查詢:

SELECT s1.*
FROM salesorder s1
JOIN (
    SELECT region, MIN(total) AS min_total
    FROM salesorder
    GROUP BY region
) s2 ON s1.region = s2.region AND s1.total = s2.min_total;

注意:若最低值重複,此寫法會回傳所有並列記錄(類似 RANK() 行為)。

效能提示

  • 確保 (region, total) 有複合索引,窗口函數排序與分組才能高效執行。
  • 大資料量下,窗口函數通常比雙層巢狀子查詢效能更優、計劃更穩定。

總結

掌握 PARTITION BY ... ORDER BY 配合 ROW_NUMBER/RANK 的模式,即可輕鬆解決「各群組 Top-N」類問題,是 SQL 進階必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved