2011-06-18 10 views
5

両方ともORDER BYを含む2つのクエリを結合しようとしています。 私が発見したように、UNIONの一部であるクエリでは注文できません。 私はこのクエリを他にどのように行うのか分かりません。私がしようとしていることを説明しましょう。ORDER BYを含むMySQL UNION 2のクエリ

  1. 私は40個の最新のプロファイルを選択しようとすると、そのリストから午前私はその後にすることを労働組合にしたい20のランダムなセットを選択:
  2. するプロファイルがに該当しない40個のランダムなプロファイルを選択します元の40個の最新のプロファイルが最初のセットで照会されました
  3. 60個のレコード全体をランダムに注文します。これは、以下のアブヘイのヘルプ(感謝アブヘイ)に基づいたソリューションです:

    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(); 
    
    私は

    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ランド()関数を使用しての効率波及効果を認識してい

答えて

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. が最終ORDER BY RAND()のためのあなたの第二のクエリ
  3. のエイリアスprofile3を削除し、あなたは目を作成する必要がありますe UNION結果は派生テーブルになります。私はそれにTEMPエイリアスとして与えました

私は上記のクエリをテストしていませんが、私はそれが動作することを願っています。あなたの所見を教えてください。

+1

Thanks - あなたのソリューションは私の問題を解決しましたが、新しいエラーが発生しました(このバージョンのMySQLでは 'LIMIT&IN/ALL/ANY/SOME subquery ')、私は別のselectで解決して、上記の完全な質問を私の元の投稿に投稿しました。これを解決するお手伝いをありがとう。 – Cheeky

+0

@Cheeky:はい、これはMySQLの問題点を解決する方法です:) –

1

問合せ全体を別のselect(副選択)にして、結果セットにORDER BY RAND()を入れることができます。しかし、これはかなり複雑です(多くのランダムORDER BYステートメントが必要な場合)ので、ご注文のデータセット(つまりUNIONprofile1profile3)を選択した言語の配列に集めるのは、その配列の順序をランダム化する。

+0

結果セット全体が並べ替えられたときに内側の 'ORDER BY'が必要なのはなぜですか? –

+0

@ypercubeの内側の' ORDER BY RAND()が必要ですか? – Andy

+0

は、 'LIMIT 40 'と組み合わせて、テーブルのある部分から40個のランダムな行を選択し、別の行から20個のランダムな行を(LIMIT 20で)選択するためです。 –