SELECT * FROM Sales.Orders ORDER BY RAND(); -- 錯誤!
原因:`RAND()` 在單一查詢執行期間**僅計算一次**,所有資料列獲得相同的隨機值,`ORDER BY` 失去排序意義,結果順序不定 (通常維持原序)。
-- 1. 全表隨機排序
SELECT * FROM Sales.Orders ORDER BY NEWID();
-- 2. 隨機抽樣 TOP N 筆
SELECT TOP (10) * FROM Sales.Orders ORDER BY NEWID();
-- 3. 百分比抽樣 (TABLESAMPLE 替代方案, SQL 2005+)
SELECT * FROM Sales.Orders TABLESAMPLE (10 PERCENT); -- 頁面層級抽樣,非逐列隨機,效能極佳但統計特性不同
| 函數 | 回傳型別 | 計算頻率 | 唯一性 | 適用場景 |
|---|---|---|---|---|
| RAND([seed]) | FLOAT (0~1) | 每查詢一次 | 全表相同 | 產生單一隨機數、模擬資料、填充測試資料 |
| NEWID() | UNIQUEIDENTIFIER (GUID) | 每資料列一次 | 極高 (128-bit) | 隨機排序、隨機抽樣、分散式主鍵生成 |
| CRYPT_GEN_RANDOM(n) (2008+) | VARBINARY | 每呼叫一次 | 加密級 | 高熵隨機位元組、安全性 Token、鹽值 |
TABLESAMPLE (n PERCENT/ROWS):頁面層級抽樣,不掃描全表,**極快**,但非逐列獨立隨機,同一頁面全選或全不選。WHERE RAND(CHECKSUM(*)) < 0.01:利用 `CHECKSUM(*)` 行雜湊值配合 `RAND(seed)` 產生確定性偽隨機,可配合索引 (若有計算欄位) 或全表掃描但避免排序開銷。-- 將使用者以 1% 機率分入實驗組
SELECT UserID, 'Experiment' AS Bucket
FROM dbo.Users
WHERE ABS(CHECKSUM(NEWID())) % 100 < 1; -- 0~99 隨機分布,<1 即 1%