資料表 依亂數順序讀取資料

通常在讀取資料的時候,我們比較常用order by id,
或者order by objName來對資料排序。

有時候,我們可能會需要隨機取得資料。
例如我們現在要從資料表隨機讀取資料做為中獎名單,
或是以亂數順序取得資料當樣本。

在SQL Server,有一個可以直接套用的方法是newid()。
newId()是為了確保每一筆資料在存取時的唯一性(unique)所產生的字串。
這個值在每次sql statement執行時都不一樣。
下面是這些字串的「長相」,
3A934F70-5046-4D3D-9F7C-797EAB13B913
E5AC2F6A-2C8E-4143-B3B9-A21E8B9D4E7C

我們可能會想到,資料表不是已經有id欄位,
不能使用rand()來達到目的嗎?
我跑了不同的語法,結果如圖,

select id from table1 order by rand(id);

select id from table1 order by newid();

從圖中可以發現,使用rand()所產生結果有一定的pattern,
其結果不如newid()。

接下來則是讓我想到在MySQL中如何做到同樣的效果,
MySQL官方文件有一段指出,

you can retrieve rows in random order like this:
mysql> SELECT * FROM tbl_name ORDER BY RAND();

所以目前MySQL並沒有類似newid()的方法。
由於我在MySQL上沒有足夠的資料量可以測試使用rand()的結果,
這邊就不下結論。

如果是使用MS SQL,建議採用newid()來隨機讀取,
因為newid()是每次我們執行sql statement時,資料庫會自動建立的。
或者你也可以設法在rand()的seed上做變化,讓結果更隨機。

最後,如果資料筆數太多,
要提醒的是效能會是值得注意的問題。

參考資料,
1.http://www.sqlhacks.com/index.php/Retrieve/Random-Numbers
2.http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand
3.http://mkruger.cfwebtools.com/index.cfm/2005/9/29/mssql.random.row
4.http://www.chapter31.com/2007/01/30/coldfusion-uuids-and-mssql-newid/