需求:Student 表含 Class (班級)、Name (姓名),每班隨機抽 3 人。
SELECT Name
FROM (
SELECT
Name,
ROW_NUMBER() OVER (PARTITION BY Class ORDER BY CHECKSUM(NEWID())) AS RN
FROM Student
) t
WHERE RN <= 3;
PARTITION BY Class:按班級分組。ORDER BY CHECKSUM(NEWID()):NEWID() 產生唯一 GUID,CHECKSUM 轉為整數,實現**每行獨立隨機排序** (比 RAND() 更均勻,RAND() 某版本每查詢僅執行一次)。ROW_NUMBER():分組內依隨機順序編號 1,2,3...。WHERE RN <= 3 取前 3 名。| 資料量 | 建議 |
|---|---|
| 小表 (< 10 萬) | 上述寫法足夠 |
| 大表 (> 100 萬) | 建立 INDEX IX_Student_Class (Class) INCLUDE (Name) 避免掃描 |
| 超大表 (億級) | 考慮 TABLESAMPLE SYSTEM (1 PERCENT) 先抽樣再視窗函數,或預先建立隨機排序欄位 |
-- 利用 NEWID() 排序 + 臨時表 + 游標/分組邏輯,極不推薦用於生產 -- 升級資料庫相容性等級至 90+ 即可使用 ROW_NUMBER()
ORDER BY CHECKSUM(NEWID(), '2024-01-15') -- 固定種子,同條件每次結果相同
適用於審計、驗證需可重現的隨機抽樣場景。