需求:從百萬筆樂透模擬資料中,找出出現次數最多的號碼組合。本文示範使用 GROUP BY 搭配 HAVING 過濾重複群組,再以 ORDER BY COUNT(*) DESC 取得最高頻組合,附帶效能優化建議。
CREATE TABLE LottoDraw (
DrawID INT IDENTITY(1,1) PRIMARY KEY,
N1 TINYINT, N2 TINYINT, N3 TINYINT,
N4 TINYINT, N5 TINYINT, N6 TINYINT,
N7 TINYINT
);
-- 假設已填入 1,000,000 筆模擬資料
SELECT TOP 1
N1, N2, N3, N4, N5, N6, N7,
COUNT(*) AS Freq
FROM LottoDraw
GROUP BY N1, N2, N3, N4, N5, N6, N7
HAVING COUNT(*) > 1
ORDER BY Freq DESC;
| 子句 | 作用 |
|---|---|
| GROUP BY | 依 7 個號碼欄位分群,相同組合歸為一列 |
| HAVING COUNT(*) > 1 | 僅保留出現超過 1 次的群組(即重複組合) |
| ORDER BY Freq DESC | 依出現頻率遞減排序 |
| TOP 1 | 取得最高頻組合 |
SELECT TOP 10 N1,N2,N3,N4,N5,N6,N7, COUNT(*) AS Freq
FROM LottoDraw
GROUP BY N1,N2,N3,N4,N5,N6,N7
HAVING COUNT(*) > 1
ORDER BY Freq DESC;
SELECT N1,N2,N3,N4,N5,N6,N7, COUNT(*) AS Freq
FROM LottoDraw
GROUP BY N1,N2,N3,N4,N5,N6,N7
ORDER BY Freq DESC;
CREATE INDEX IX_Lotto_Numbers ON LottoDraw(N1,N2,N3,N4,N5,N6,N7),加速分群排序。DrawID 或日期分區。LottoFreq,查詢時直接讀彙總表,毫秒級回應。MAX SERVER MEMORY 留足給查詢工作區,避免溢寫 TempDB。❌ SELECT DISTINCT * FROM T HAVING COUNT(*) > 1 — DISTINCT 無法搭配 HAVING 使用。
✅ 必須 GROUP BY 所有欄位再 HAVING。