2011-06-18 63 views
5

我正在嘗試UNION兩個包含ORDER BY的查詢。 正如我發現的那樣,您不能通過作爲UNION一部分的查詢進行排序。 我只是不知道如何做這個查詢然後。讓我解釋我想要做的事情。包含ORDER BY的MySQL UNION 2查詢

  1. 我想選擇40個最近期的輪廓,然後從列表中選擇一組隨機的20,然後我想工會與:
  2. 選擇40隨機配置文件,其中配置文件不落於在第一組中查詢原始的40個最近的配置文件
  3. 隨機地命令整個60個記錄集。

我知道使用RAND()函數

SELECT profileId 
    FROM (SELECT profileId 
      FROM profile profile2 
     WHERE profile2.profilePublishDate <= Now() 
     ORDER BY profile2.profilePublishDate DESC 
     LIMIT 0,40) AS profile1 
ORDER BY RAND() 
    LIMIT 0,20 
UNION (SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (SELECT profileId 
            FROM profile profile4 
           WHERE profile4.profilePublishDate <= Now() 
           ORDER BY profile4.profilePublishDate DESC 
           LIMIT 0,40)  
    ORDER BY RAND()  
     LIMIT 0,40) as profile3 
ORDER BY RAND() 

UPDATE的效率後果的:這是基於以下阿沛的幫助(感謝阿沛)解決方案:

SELECT * 
FROM 
(
    (
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    ) 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT * FROM 
      (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) AS temp2 
     ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

回答

5

這是您的解決方案:

SELECT * 
FROM 
(
    **(** 
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    **)** 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

,我所做的改變是:

  1. 每個查詢是UNION的一部分,應該用括號包裹的(以粗體顯示的第一個查詢;第二個已經包裝)
  2. 刪除別名profile3爲您的第二個查詢
  3. 爲最終ORDER BY RAND(),您必須創建第將UNION結果集導出到派生表;我給它TEMP作爲別名

我還沒有測試過上面的查詢,但我希望它能工作。讓我知道你的發現。

+1

謝謝 - 您的解決方案解決了我的問題,但出現了一個新錯誤(此版本的MySQL尚不支持'LIMIT&IN/ALL/ANY/SOME子查詢'),我也通過另一個選擇解決了這個問題,並在我的原始文章中發佈了上面的完整查詢。感謝您解決這個問題。 – Cheeky

+0

@ Cheeky:是的,這是解決這個問題的方法,它具有MySQL提出的限制:) –

1

您可以在該結果集中的另一個選擇中包含整個查詢(使其成爲子選擇)並ORDER BY RAND()。然而,這是非常複雜的(當你只需要一個隨機的ORDER BY聲明時),所以它很可能會減少處理器密集度,以便按照您選擇的語言將有序數據集(即UNION的和profile3)收集到一個數組中,隨機化該數組的順序。

+0

他確實需要內部'ORDER BY RAND()' –

+0

@ypercube當整個結果集重新排序時,爲什麼需要內部的ORDER BY? – Andy

+0

,因爲它與'LIMIT 40'組合使用可以從表格的一部分中選擇40個隨機行,從另一個部分選擇20個隨機行(使用'LIMIT 20')。 –