ORDER BY使用UNION创建的人工行

时间:2016-05-12 07:56:45

标签: mysql

我使用UNION为“所有国家/地区”创建一个人工行:

SELECT '0', 'all countries', '10000000000000' AS users
UNION
SELECT country_id, country_name, country_internet_users AS users
FROM countries
ORDER BY users DESC
LIMIT 10

当我尝试按country_internet_users排序时出现问题。

MySQL似乎没有按预期运行。它根本不排序。在添加“AS用户”之前,它甚至不会运行查询。但尽管它似乎完全忽略了ORDER BY。

当我使用UNION添加人工行时,如何按列排序?

2 个答案:

答案 0 :(得分:1)

一个选项是向每个子选择添加第四列,该第四列对UNION的每个部分出现的顺序进行排序。在您的情况下,您希望UNION的第一部分作为一种表头显示在顶部。然后在外部查询中,仅选择您希望在报告中显示的三列。

SELECT t.country_id, t.country_name, t.users
FROM
(
    SELECT '0' AS country_id, 'all countries' AS country_name, 10000000000000 AS users, 1 AS val
    UNION ALL
    SELECT country_id, country_name, country_internet_users AS users, 0 AS val
    FROM countries
) AS t
ORDER BY t.val DESC, t.users DESC

这种方法是保证UNION的前半部分出现在顶部的一种方法(假设这是你想要的)。正如@KubaWyrostek所指出的,如果你可以依赖ID值的自然排序,那么你就不需要子查询。

答案 1 :(得分:1)

  

MySQL似乎没有按预期运行。它根本不排序。在添加“AS用户”之前,它甚至不会运行查询。

单独运行第一个查询,你会看到,因为你没有对表达式进行别名,MySQL使用这些值作为它在结果集中生成的列的名称。就是这样,第一个查询生成名为0all countries10000000000000的列。当然,MySQL无法按列users对行进行排序,因为结果集中没有users列。

将第三个表达式别名为users后,第一个查询返回列0all countriesusers,现在MySQL知道要用于哪个列排序

  

但尽管它似乎完全忽略了ORDER BY

不,它不会忽略ORDER BY。我无法确定,但我认为,因为您为列users生成的值是一个字符串,ORDER BY对列users的值使用字符串比较,甚至是从中提取的值该表是整数(或者它们也是字符串?)。

如果列userscountry_internet_users的类型是数字类型,您所要做的就是在生成的行中使用数字:

SELECT '0', 'all countries', 10000000000000 AS users
# ... the rest of the query here

如果列userscountry_internet_users的类型是字符串类型,那么您必须选择:

  1. 在查询中将值转换为整数;这使得查询运行速度非常慢;
  2. 将列的类型更改为数字类型(这是您应该首先创建它的方式):

    ALTER TABLE country
    MODIFY country_internet_users INT UNSIGNED NOT NULL;