UNION和ORDER BY的使用不正确?

Yud*_*ira 56 mysql union sql-order-by

我如何在mysql中使用unionorder

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
Run Code Online (Sandbox Code Playgroud)

给我错误

#1221 - Incorrect usage of UNION and ORDER BY
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮忙吗?

Tud*_*tin 78

试试:

(
  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
)
Run Code Online (Sandbox Code Playgroud)

虽然,我认为您应该将该ORDER BY子句放在第二个查询的末尾


Álv*_*lez 31

括号:

(
    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
)
Run Code Online (Sandbox Code Playgroud)

说,MySQL并不强制要在外部子句中保留内部排序 - 尽管它可能会这样做,因为它需要对行进行排序以计算相应的LIMIT子句.


Pac*_*ier 23

说明:

重要的是要了解这是如何工作以避免类似用例中的"陷阱".请注意,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);
    
    Run Code Online (Sandbox Code Playgroud)

但是,如果用大括号包围第一个" 子语句 ",则必须用括号括所有其他" 子语句 ":

(请注意,官方文档中未提及上述要点.)

不这样做是语法错误:

  • 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...
    
    Run Code Online (Sandbox Code Playgroud)

其次,每个" 子语句 "可以包含where,group by,having,join,limit,但不是order by.

如果您想使用order by,包含的" 子语句 " order by必须用大括号括起来.(这意味着它们不再是可选的.)

现在,如果我们再次查看语法:

union all 语句 union all order by语句[-clause] [limit-clause]

我们可以看到整个union语句以可选的order by/ 结束limit.这两个关键字适用于整个union语句,而不仅仅是最后一个" 语句":

我们之前已经提到limit关键字也可以应用于单个" 子语句 ":

如果要应用于limit最后一个" union语句"(而不是整个语句),则必须用括号括起最后一个" 语句":

要应用于limit最后一个" 语句" 以及 整个union语句,请使用:

它与以下相同order by:

但是请注意,申请order by到" 子语句 " s是毫无意义的,因为该文档已明确表示order by才能得到保证(参见),当应用到整个工作union的语句:

-§-   .. ORDER BY对于单个SELECT语句的使用并不意味着行在最终结果中出现的顺序.

order by在" 子语句 "中唯一有意义的方法是将它与limit以下内容结合起来:

-§-   在此上下文中使用..the ORDER BY的是典型地与结合LIMIT,使得它被用于确定所选择的行的子集来检索SELECT,即使它并不一定会影响那些行的顺序在最后的UNION结果.

此外,如果你想结合使用,还会有更多的"陷阱"需要注意.有关此问题,请参见问题32858.select intounion