MySQL UNION 2查询包含ORDER BY

时间:2011-06-18 17:02:04

标签: mysql sql union

我正在尝试UNION两个包含ORDER BY的查询。 正如我所发现的那样,您无法通过属于UNION的查询进行排序。 我只是不知道如何做这个查询呢。让我解释一下我要做的事情。

  1. 我正在尝试选择40个最新的个人资料,并从该列表中选择一个随机集20个。然后我想将其与:
  2. 结合起来
  3. 选择40个随机配置文件,其中配置文件不属于第一组中查询的原始40个最新配置文件
  4. 随机排序整套60条记录。
  5. 我知道使用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()
    

    更新:这是基于Abhay帮助的解决方案(感谢Abhay):

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

2 个答案:

答案 0 :(得分: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作为别名
  4. 我没有测试过上面的查询,但我希望它能够运行。让我知道你的发现。

答案 1 :(得分:1)

您可以将整个查询包含在另一个选择(要进行子选择)和ORDER BY RAND()结果集中。然而,这很复杂(当你只需要一个时,许多随机ORDER BY语句),因此收集有序数据集(即只UNION profile1可能会减少处理器密集度。和profile3)用您选择的语言编入一个数组,并随机化该数组的顺序。