2016-04-29 46 views
2

我想選擇以隨機順序排排序由group_idORDER BY RAND()和組GROUP_ID

id group_id 
1 1 
2 1 
3 2 
4 2 
5 3 
6 4 

我想將它們進行排序像下面或隨機,但仍分組:

id group_id 
5 3 
3 2 
4 2 
1 1 
2 1 
6 4 

下面會對它們進行排序,但我希望排序是隨機的。如何實現這一目標?

SELECT * FROM table ORDER BY group_id DESC 

以下是我正在計算出的實際應用程序的示例查詢。

SELECT * FROM (SELECT requests.*, accounts.username, accounts.password 
FROM requests LEFT JOIN accounts ON requests.acc_id = accounts.id 
WHERE requests.status NOT IN(1) AND accounts.status=1 ORDER BY RAND() 
) AS subquery GROUP BY acc_id 
+0

花了我一陣子弄明白了,但你基本上想在'group_id'右邊對_randomly_進行排序?換句話說,你想要一個隨機順序,所有具有相同'group_id'的行彼此相鄰? – Rick

+0

你不應該使用'ORDER BY RAND()',因爲它不僅告訴mysql「請扔掉所有索引」,而且「將整個結果集寫出到磁盤並使用filesort」。你的表格現在可能足夠小,以至於不太明顯,但隨着數據集的增長,這將變成*指數級惡化。 – Sammitch

回答

3

您也可以用種子依賴於group_id一個隨機數嘗試訂購,但以隨機因素。 像這樣:

SET @seed = 100*RAND(); 
SELECT * FROM table ORDER BY RAND(group_id*@seed); 
+1

這個很好用!請你解釋一下你背後的邏輯!謝謝 – fawzib

+0

賦予'RAND()'函數一個參數將結果與輸入 - 例如來自RAND的值序列對於相等的初始化器總是相同的。 Plus - (來自MySQL'RAND()'docs)「如果使用非常量初始值設定項(如列名稱)作爲參數,則將使用每次調用」RAND()'。「的值初始化種子。因此,'RAND(group_id)'給出一個基於'group_id'的恆定僞隨機數,我們可以訂購它並獲得預期的結果。對初始化程序的隨機種子只能確保每個查詢執行的結果都不相同。 –

+0

如何重新初始化每行的僞隨機生成器相對於'ORDER BY RAND()'有什麼優勢?對於這個答案中的模式,行的順序基本上由@ seed的初始設置「固定」。 – spencer7593

0

你可以使用一個子查詢隨機的訂單所有的組ID和位置分配給他們一個用戶變量。然後將它與原始表加入並按位置排序。

SELECT t1.id, t1.group_id 
FROM yourTable AS t1 
JOIN (SELECT group_id, @position := @position + 1 as position 
     FROM (SELECT DISTINCT(group_id) AS group_id 
      FROM yourTable 
      ORDER BY RAND()) AS x 
     CROSS JOIN (SELECT @position := 0) AS var) AS t2 
ON t1.group_id = t2.group_id 
ORDER BY position, id 

DEMO

0

我不理解爲什麼其他的答案是爲參與,因爲它們。

如果您需要隨機排序的行,請執行ORDER BY RAND()

SELECT t.id 
    , t.group_id 
    FROM `table` t 
ORDER BY RAND() 

注意RAND()不是真正隨機的,這是一個僞-random發電機。


我不明白你爲什麼需要內聯視圖。您可以在沒有內聯視圖的情況下執行GROUP BY操作。給定GROUP BY,不需要在內聯視圖中執行不必要的ORDER BY操作。

SELECT requests.* 
     , accounts.username 
     , accounts.password 
    FROM requests 
    LEFT 
    JOIN accounts 
    ON requests.acc_id = accounts.id 
    WHERE requests.status NOT IN(1) 
    AND accounts.status=1 
    GROUP 
    BY acc_id 
    ORDER 
    BY RAND()