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 by
clause] [limit
clause]
其中“ 子态 ”可以被(
和)
包围。 一些工作的例子:
-
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 by
clause] [limit
clause]
我们可以看到,整个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