UNION和ORDER BY的用法不正确?
我怎么可以在MySQL中使用联合和订单 ?
select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 9 ORDER BY RAND() limit 2 UNION ALL select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 8 limit 3
给我错误
#1221 - Incorrect usage of UNION and ORDER BY
任何人都可以帮忙?
试试:
( select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 9 ORDER BY RAND() limit 2 ) UNION ALL ( select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 8 limit 3 )
虽然,我认为你应该把ORDER BY子句放在第二个查询的末尾
括号内:
( SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner =_member_pts._username WHERE _MEMBER_FACEBOOK._PROMOTE_POINT = 9 ORDER BY RAND() LIMIT 2 ) UNION ALL ( SELECT * FROM _MEMBER_FACEBOOK INNER JOIN _MEMBER_PTS ON _MEMBER_FACEBOOK._FB_OWNER =_MEMBER_PTS._USERNAME WHERE _MEMBER_FACEBOOK._PROMOTE_POINT = 8 LIMIT 3 )
说,MySQL并不强制让内部sorting保留在外部子句中,尽pipe它可能会这样做,因为它需要对行进行sorting来计算相应的LIMIT子句。
说明:
了解这种工作方式以避免类似用例中的“陷阱”是很重要的。 请注意, union的语法有些“特殊”:
子状态
union all子状态union all子状态 [order byclause] [limitclause]
其中“ 子态 ”可以被(和)包围。 一些工作的例子:
-
select 1 union all (select 2); select 1 union all select 2 union all (select 3); select 1 union all (select 2) union all select 3; select 1 union all (select 2) union all (select 3); select 1 union all (select 2) union all (select 3) union all select 4; select 1 union all (select 2) union all select 3 union all (select 4);
但是 ,如果用括号将第一个“ 子状态 ”包围起来,则必须用括号括住所有其他的“ 子状态 ”:
-
(select 1) union all (select 2) union all (select 3);
(请注意, 官方文档中未提及上述内容。)
没有这样做是一个语法错误:
-
mysql> (select 1) union all select 2; -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error in your SQL syntax; check the... mysql> (select 1) union all (select 2) union all select 3; -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error... mysql> (select 1) union all select 2 union all (select 3); -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error...
接下来,每个“ 子状态 ”可以包含where , 哪一 group by , where group by , where group by , where group by , where group by , where group by , where group by , where group by ,
如果您想使用order by ,则包含order by的“ substatement ”必须用大括号包围。 (这意味着他们不再是可选的)
现在,如果我们再看一下语法:
子状态
union all子状态union all子状态 [order byclause] [limitclause]
我们可以看到,整个union声明以一个可选的order by / limit 。 这两个关键字适用于整个union声明,而不仅仅是最后一个“ 子状态 ”:
-
mysql> select 1 -> union all -> select 2 limit 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql>
我们之前曾经提到, limit关键字也可以应用到单个“ 子状态 ”:
-
mysql> select 1 limit 1 -> union all -> select 2; +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql>
如果你想limit最后一个“ 子状态 ”(而不是整个union声明),你必须用括号括住最后一个“ 子状态 ”:
-
mysql> select 1 -> union all -> (select 2 limit 1); +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql>
要对最后的“ 子状态 ” 以及整个union声明应用limit ,请使用:
-
mysql> select 1 -> union all -> (select 2 limit 1)limit 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql>
这与order by :
-
mysql> select 1 -> union all -> (select 2 order by 1)order by 1; +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql>
但是请注意,对“ 子状态 ”使用order by是没有意义的,因为文档已经明确指出 : order by 依赖只有在应用于整个union声明时才能保证( cf )工作:
  对单独的
SELECT语句使用ORDER BY意味着行在最终结果中出现的顺序没有任何意义。
order by的唯一方式在“ 子状态 ”中是有意义的,如果将它与limit相结合:
  在此上下文中使用ORDER BY通常与
LIMIT结合使用,以便用于确定要为SELECT检索的所选行的子集,即使它不一定会影响这些行的顺序最后的UNION结果中的行。
另外,如果你想把select into和union结合起来,就会有更多的“陷阱”。 关于这个问题参见问题32858 。
正确的是:
(SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner=_member_pts._username WHERE _member_facebook._promote_point = 9 LIMIT 2) UNION ALL (SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner=_member_pts._username WHERE _member_facebook._promote_point = 8 LIMIT 3) ORDER BY 1