表結構:salesorder(orderid, region, sales, total),主鍵 orderid。
需求:查詢每個地區銷售金額最少的那筆記錄(即銷售額最低的業務員)。
現代 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 進階必備技能。