如何在mysql中使用 union 和按排序?
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
任何人都可以提供帮助吗?
答案 0 :(得分:74)
尝试:
(
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
子句放在第二个查询的末尾
答案 1 :(得分:28)
括号:
(
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并不强制要求在外部子句中保留内部排序 - 虽然它可能这样做,因为它需要对行进行排序以计算相应的{{ 1}}条款。
答案 2 :(得分:22)
了解这是如何避免"陷阱"这一点非常重要。在类似的用例中。请注意,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);
然而,如果您包围第一个" 子语句"使用大括号,必须包围所有其他" 子语句" s括号:
(select 1) union all (select 2) union all (select 3);
(请注意,official docs中未提及上述要点。)
未能做到这一点是语法错误:
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
,having
,join
,limit
,但不能包含order by
。
如果您想使用order by
,那么" 子语句"包含order by
的{{1}}必须用大括号括起来。 (这意味着它们不再是可选的。)
现在,如果我们再次查看语法:
子语句
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
关键字也可以应用于个别" 子语句" s:
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>
将limit
应用于最后一个" 子语句" 以及到整个union
语句,请使用:
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
应用于" 子语句" s 无意义因为文档已明确声明 order by
只有在应用于整个union
语句时才能保证(cf.):
–§– ..
ORDER BY
个人SELECT
语句的使用并不代表行在最终结果中出现的顺序。
唯一的方式order by
在" 子语句中有意义"如果你将它与limit
结合使用:
–§– ..在此上下文中使用ORDER BY通常与
LIMIT
结合使用,因此它用于确定要为{{1}检索的所选行的子集},即使不必然会影响最终SELECT
结果中这些行的顺序。
此外,如果您想将select into
与UNION
结合使用,那么会有更多"陷阱"要小心。有关此问题,请参阅issue 32858。
答案 3 :(得分:0)
正确的是:
(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
答案 4 :(得分:0)
尝试()我认为
(SELECT CITY,LENGTH(CITY) FROM STATION WHERE LENGTH(CITY)=(SELECT MIN(LENGTH(CITY)) FROM STATION) ORDER BY CITY LIMIT 1)
UNION ALL
(SELECT CITY,LENGTH(CITY) FROM STATION WHERE LENGTH(CITY)=(SELECT MAX(LENGTH(CITY)) FROM STATION) ORDER BY CITY LIMIT 1);
答案 5 :(得分:0)
我认为如果您使用order by或limit或两者同时使用,则必须使用括号。我尝试通过不带括号的方式交替使用限制和顺序来处理查询,但该查询不起作用。只有在加上括号后才能起作用。
答案 6 :(得分:0)
在查询中使用Order by和limit子句时,使用括号解决了我的问题。我的要求是使表的顶部和底部行具有一定条件,并且以下代码对我有用:
(SELECT column1, column2
FROM table1
ORDER BY column1, column2
LIMIT 1)
UNION
(SELECT column1, column2
FROM table2
ORDER BY column1, column2
LIMIT 1)