2017-07-14 13 views
0

我想一個從表中得到一個隨機行回來,要做到這一點,我可以用FLOOR(1 + rand() * 50)到獲取有效的行ID。 50等於我的表中的記錄數量(我實際上有幾千個,但作爲一個例子,我保持這個小)。有人可以解釋爲什麼這個查詢有時帶回零行其他時間多行的時候,我永遠只能期待1記錄

的SQL最終被這個

<!-- language: lang-sql --> 
SELECT id FROM ids WHERE id = FLOOR(1 + rand() * 50) 

但是當我運行此查詢或者返回

  • 0記錄
  • 1記錄
  • 2+記錄

問題是我總是需要1記錄回來;我可以在那裏放一個LIMIT,但有時我甚至沒有得到一個記錄,加上我不需要FLOOR(1 + rand()* 50)總是會返回一個有效的行ID。

我知道還有其他方法可以做到這一點,但現在我只需要了解爲什麼會發生這種情況。爲了證明這是我的示例表

<!-- language: lang-sql --> 
CREATE TABLE `ids` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

我然後運行下面的50倍

<!-- language: lang-sql --> 
INSERT INTO `ids` (`id`) VALUES (NULL); 

所以現在我的表看起來像這樣(但與其他48個記錄下)

id | 
---| 
1 | 
2 | 
. 
. 

通過設置ID表,我繼續運行第一個查詢,記住FLOOR(1 + rand() * 50)總是返回範圍內的有效ID,我得到

id | 
---| 
25 | 
30 | 
43 | 

id | 
---| 

id | 
---| 
41 | 

聲明你要查找解決此問題,並實際獲得ID。

SET @randomID = FLOOR(1 + rand() * 50); 
SELECT id FROM ids WHERE id = @randomID; 

儘管我仍不理解爲什麼我在原始查詢中返回的記錄超過1條。

+1

我的猜測是,'蘭特()'是inovoked在表中的每一行,這意味着y中的每一行我們的表FLOOR(1 + rand()* 50)'是不同的,並且每次有可能當前行的id等於這個表達式。在第二個例子中,'rand()'僅被一次啓動。否則'按rand()命令不起作用 – fen1x

回答

4

標準文檔說 -

RAND()在WHERE子句的每一行(從一個表中選擇時)

如果你不想來聲明一個變量評估 -

select id from `ids` 
join (select FLOOR(1 + rand() * 50) as id) b using(id); 

DOC LINK

+0

被槍殺,RTFM;)感謝你和一個例子。 –

相關問題