[SQL與PHP] 如何從mysql中亂數取出一筆資料



[SQL與PHP] 如何從mysql中亂數取出一筆資料

在資料集的進階的地方輸入如下的語法

SELECT * FORM tbads ORDER BY RAND() LIMIT 1

這樣每次都會從資料庫中亂數取出一筆資料,即可達到隨機廣告的需求了,不過此法法只適用於Mysql而已。

------------------------------------------------------
sql="select * from tbads ORDER BY RND(數字欄位名稱)";
以上方法就適用於ACCESS及MS SQL

最近由於需要大概研究了一下MYSQL的隨機抽取實現方法。

舉個例子,要從tablename表中隨機提取一條記錄,大家一般的寫法就是 SELECT * FROM tablename ORDER BY RAND() LIMIT 1

但是,後來我查了一下MYSQL的官方手冊,裡面針對RAND()有如下提示:

You can't use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times. In MySQL Version 3.23, you can, however, do: SELECT * FROM table_name ORDER BY RAND()

大概意思就是,在ORDER BY從句裡面不能使用RAND()函數,因為這樣會導致數據列被多次掃瞄。但是在MYSQL 3.23版本中,仍然可以通過ORDER BY RAND()來實現隨機。

然後我試了一下可行性,ORDER BY RAND()在我自己的4.0版本上可以執行,但是在公司的3.x(具體忘了)上不能執行,看來好像和官方手冊上有點不同。

後來在網上找了一些資料瞭解到,

SELECT * FROM tablename ORDER BY RAND() LIMIT 1

會掃瞄整個表,然後再隨機返回一個記錄。對於比較小的表,通常不大於30萬行記錄的表,這種寫法很實用。但是如果一旦記錄大於了30萬行,這個處理過程就會變得非常緩慢!!!

所以,結論是,我建議,能夠不用ORDER BY RAND() 就不用!因為一來可以避免今後表數據量增大後引起的效率低下;二來可以避免某些版本的MYSQL不支持這種寫法。

最後給出一種比較實用的替代方法的主要思想:

假設id是主鍵

首先:SELECT MIN(id), MAX(id) FROM tablename

然後:$id=rand($min,$max); //通過rand返回剛才取到的最大id和最小id之間的一個id號。

最後:SELECT * FROM tablename WHERE id='$id' LIMIT 1

如果是用auto increment產生的id號,也許會出現某個id列曾經刪除過,造成了最大和最小id之間的不連續,在這裡可以先判斷一下隨機生成的這個id號是否存在。
我現在就使用order by rand(),當然數據表還很小很小。

你這種方法也不錯,但是如果我要隨機的10條呢?
最簡單的就是隨便取個連續的範圍,比如

SELECT * FROM tablename WHERE id > '$id' LIMIT 10

但這種方法的隨機是連續的.

然後還有比如生成一個WHERE  id = '{$id['1']}' OR id = '{$id['2']}' OR .....的從句,寫起來會稍微多幾句,$id的值隨機生成數。

但這種方法如果從句多了話,比如上百條?那樣SQL語句會比較大,也會影響效率。

還有,先按照第一種隨機選擇一個範圍,比如

SELECT id FROM tablename WHERE id > '$id' LIMIT 50

然後再在在結果中隨機選擇10個

還有,每次隨機取一個,取10次。


首先:SELECT MIN(id), MAX(id) FROM tablename

然後:$id=rand($min,$max); //通過rand返回剛才取到的最大id和最小id之間的一個id號。

最後:SELECT * FROM tablename WHERE id='$id' LIMIT 1

如果記錄的ID是唯一的,且記錄有過刪除,那很可能取到的這個ID就沒有記錄存在。

所以如果用這個辦法,一定要再select一下,看看這個記錄是否存在了