我想在每个UNION ALL查询上使用ORDER BY,但我无法弄清楚正确的语法.这就是我要的:
(
SELECT id, user_id, other_id, name
FROM tablename
WHERE user_id = 123 AND user_in IN (...)
ORDER BY name
)
UNION ALL
(
SELECT id, user_id, other_id, name
FROM tablename
WHERE user_id = 456 AND user_id NOT IN (...)
ORDER BY name
)
Run Code Online (Sandbox Code Playgroud)
编辑:要明确:我需要两个这样的有序列表,而不是一个:
1 2 3 1 2 3 4 5
非常感谢你!
像这样的东西应该在MySQL中工作:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
Run Code Online (Sandbox Code Playgroud)
不过请注意,上不存在的ORDER BY(或GROUP BY)子句的最外层查询,订单被返回的行是不保证的.
如果需要按特定顺序返回的行,则应ORDER BY在最外面的查询中包含一个.在很多用例中,我们可以使用ORDER BY最外层的查询来满足结果.
但是,如果您有一个用例,您需要在第二个查询的所有行之前返回的第一个查询中的所有行,则一个选项是在每个查询中包含一个额外的鉴别器列.例如,,'a' AS src在第一个查询中添加,'b' AS src第二个查询.
然后最外面的查询可以包括ORDER BY src, name,以保证结果的顺序.
跟进
在原始查询中,ORDER BY优化程序会丢弃查询中的查询; 由于没有ORDER BY应用于外部查询,MySQL可以按照自己想要的顺序自由返回行.
我的答案(上面)中查询中的"技巧"取决于某些版本的MySQL特有的行为.
测试用例:
填充表格
CREATE TABLE foo2 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
CREATE TABLE foo3 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
INSERT INTO foo2 (id, role) VALUES
(1,'sam'),(2,'frodo'),(3,'aragorn'),(4,'pippin'),(5,'gandalf');
INSERT INTO foo3 (id, role) VALUES
(1,'gimli'),(2,'boromir'),(3,'elron'),(4,'merry'),(5,'legolas');
Run Code Online (Sandbox Code Playgroud)
询问
SELECT a.*
FROM ( SELECT s.id, s.role
FROM foo2 s
ORDER BY s.role
) a
UNION ALL
SELECT b.*
FROM ( SELECT t.id, t.role
FROM foo3 t
ORDER BY t.role
) b
Run Code Online (Sandbox Code Playgroud)
结果集返回
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Run Code Online (Sandbox Code Playgroud)
行foo2中的"按顺序"返回,然后foo3再次按"按顺序"返回行.
请注意(再次)不保证此行为.(我们观察到的行为是MySQL如何处理内联视图(派生表)的副作用.这种行为在5.5之后的版本中可能会有所不同.)
如果需要按特定顺序返回的行,ORDER BY则为最外层查询指定一个子句.该顺序将适用于整个结果集.
正如我前面提到的,如果我首先需要第一个查询中的行,然后是第二个查询,我会在每个查询中包含一个"discriminator"列,然后在ORDER BY子句中包含"discriminator"列.我也会废除内联视图,并执行以下操作:
SELECT s.id, s.role, 's' AS src
FROM foo2 s
UNION ALL
SELECT t.id, t.role, 't' AS src
FROM foo3 t
ORDER BY src, role
Run Code Online (Sandbox Code Playgroud)
你最后只使用一个ORDER BY.
联盟将两个选项转换为一个逻辑选择.order-by适用于整个集合,而不适用于每个部分.
不要使用任何parens.只是:
SELECT 1 as Origin, blah blah FROM foo WHERE x
UNION ALL
SELECT 2 as Origin, blah blah FROM foo WHERE y
ORDER BY Origin, z
Run Code Online (Sandbox Code Playgroud)
除非与一起使用,否则请勿ORDER BY在中使用单个SELECT语句。UNIONLIMIT
要将ORDER BY或LIMIT应用于单个SELECT,请将子句放在包围SELECT的括号内:
Run Code Online (Sandbox Code Playgroud)(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);但是,对单个SELECT语句使用ORDER BY并不意味着行在最终结果中出现的顺序,因为UNION默认情况下会产生一组无序的行。因此,在这种情况下,ORDER BY的使用通常与LIMIT结合使用,因此,它可以用来确定要为SELECT检索的所选行的子集,即使它不一定影响SELECT中的那些行的顺序。最终的UNION结果。如果ORDER BY在SELECT中没有LIMIT出现,则会对其进行优化,因为它始终无效。
要使用ORDER BY或LIMIT子句对整个UNION结果进行排序或限制,请在各个SELECT语句之间加上括号,然后将ORDER BY或LIMIT放在最后一个语句之后。下面的示例使用两个子句:
Run Code Online (Sandbox Code Playgroud)(SELECT a FROM t1 WHERE a=10 AND B=1) UNION (SELECT a FROM t2 WHERE a=11 AND B=2) ORDER BY a LIMIT 10;
似乎像ORDER BY下面这样的子句将为您提供所需的内容:
ORDER BY user_id, name
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14376 次 |
| 最近记录: |