在 mysql 中使用 union 和 order by 子句

我想在 mysql 查询中使用 order by 和 union。 我提取不同类型的记录基于不同的标准从一个基于距离的表在我的网站上搜索。 第一个选择查询返回与确切位置搜索相关的数据。 第2个选择查询返回与搜索地点5公里内的距离有关的数据。 第三个选择查询返回与搜索地点5-15公里内的距离有关的数据。

然后我使用联合合并所有的结果,并显示在一个页面与分页。在适当的标题下,如 ‘精确的搜索结果’「成绩在5公里以内」

现在我想根据 id 或 add _ date 对结果进行排序。但是当我在查询末尾添加 order by 子句时(query1 union query 2 union query 3 order by add _ date)。它会对所有结果进行分类。但我想要的是它应该在每个标题下排序。

214551 次浏览

试试:

SELECT result.*
FROM (
[QUERY 1]
UNION
[QUERY 2]
) result
ORDER BY result.id

其中[ QUERY 1]和[ QUERY 2]是要合并的两个查询。

这是因为您正在对整个结果集进行排序,您应该分别对联合的每个部分进行排序,或者您可以使用 ORDERBY (Something ie。THEN (something ie row id)子句

为此,可以在每个选择中添加一个名为 rank 的伪列,在按照其他条件进行排序之前,可以先按照这个伪列进行排序,例如:

select *
from (
select 1 as Rank, id, add_date from Table
union all
select 2 as Rank, id, add_date from Table where distance < 5
union all
select 3 as Rank, id, add_date from Table where distance between 5 and 15
) a
order by rank, id, add_date desc

联合查询只能有一个主 ORDER BY子句 IIRC。为此,在构成更大的 UNION查询的每个查询中,添加一个字段,该字段将成为对 UNIONORDER BY进行排序的字段。

例如,你可能会有

SELECT field1, field2, '1' AS union_sort
UNION SELECT field1, field2, '2' AS union_sort
UNION SELECT field1, field2, '3' AS union_sort
ORDER BY union_sort

这个 union_sort字段可以是任何您想要排序的内容。在这个示例中,它只是碰巧将第一个表的结果放在第一位,第二个表放在第二位,等等。

您可以使用子查询来完成这项工作:

select * from (select values1 from table1 order by orderby1) as a
union all
select * from (select values2 from table2 order by orderby2) as b

在联合之前,我尝试向每个查询添加订单,如

(select * from table where distance=0 order by add_date)
union
(select * from table where distance>0 and distance<=5 order by add_date)

但是它似乎没有工作。它实际上没有在每个选择的行中进行排序。

我认为您需要保持外部的顺序,并添加列在 where 子句的顺序,类似于

(select * from table where distance=0)
union
(select * from table where distance>0 and distance<=5)
order by distance, add_date

这可能有点棘手,因为您希望按范围进行分组,但我认为这应该是可行的。

我把这个弄成了一个联合加盟工会。

(SELECT
table1.column1,
table1.column2,
foo1.column4
FROM table1, table2, foo1, table5
WHERE table5.somerecord = table1.column1
ORDER BY table1.column1 ASC, table1.column2 DESC
)


UNION


(SELECT
... Another complex query as above
)


ORDER BY column1 DESC, column2 ASC
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)


order by add_date

不要忘记,union all 是一种在不进行排序或合并的情况下向记录集添加记录的方法(与 union 相反)。

例如:

select * from (
select col1, col2
from table a
<....>
order by col3
limit by 200
) a
union all
select * from (
select cola, colb
from table b
<....>
order by colb
limit by 300
) b

它使各个查询更加清晰,并允许您按照每个查询中的不同参数进行排序。然而,通过使用选择的答案的方式,根据复杂性和数据之间的关联程度,可能会变得更加清晰,因为您正在对排序进行概念化。它还允许您将人工列返回给查询程序,这样它就有了一个上下文,可以进行排序或组织。

但是这种方法的优点是速度快,不会引入额外的变量,并且很容易分离出包括排序在内的每个查询。能够增加一个限制只是一个额外的奖金。

当然,您可以将所有联合转换为联合,并为整个查询添加排序。或者添加一个人工标识,在这种情况下,这种方法使得按照每个查询中的不同参数进行排序变得很容易,但是在其他情况下,它与接受的答案是相同的。

当您在子查询中使用 ORDER BY子句时,与 UNION mysql 一起使用的子查询将优化掉 ORDER BY子句。

这是因为在默认情况下,UNION返回一个无序列表,因此 ORDER BY什么也不做。

提到了 在文件里的优化,并表示:

若要将 ORDERBY 或 LIMIT 应用于单个 SELECT,请放置子句 在包括 SELECT 的括号内:

(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 语句使用 ORDERBY 意味着什么 没有关于行在最终结果中出现的顺序 因为 UNION 默认情况下会生成一组无序的行。因此, 在此上下文中使用 ORDERBY 通常与 LIMIT,以便用于确定所选行的子集 检索 SELECT,即使它不一定影响 最终 UNION 结果中这些行的顺序 如果在 SELECT 中没有限制,它将被优化掉,因为它将具有 反正也没用。

这句话的最后一句有点误导,因为它应该有一个效果。当您需要在子查询中排序时,这种优化会导致问题。

要强制 MySQL 不执行这种优化,您可以添加一个 LIMIT 子句,如下所示:

(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)

LIMIT意味着如果您希望执行分页等操作,可以在整个查询上添加 OFFSET

这还使您能够为每个联合使用不同的 ORDER BY列,从而获得额外的好处。

只需按列号排序(不要使用列名)。 每个查询都会返回一些列,因此您可以使用所需的列号对任何所需的列进行排序。

我正在尝试 (工会后的命令)以下查询,但不能:

select table1.*,table2.*
from table1
left join table2 on table2.id=0
union
select table1.*,table2.*
from table2
left join table1 on table2.i=table1.id
order by table1.id;

不管你想问什么,
只需在所有选择的联合查询中的列中添加相同名称的别名
在上面的例子中,它将是:

select table1.id as md,table1.*,table2.*
from table1
left join table2 on table2.id=0
union
select table1.id as md,table1.*,table2.*
from table2
left join table1 on table2.i=table1.id
order by md;

可以对 UNION 结果使用 ORDERBY 子句,经过长时间的研究,终于找到了解决方案。

在 MySQL 中,如果你使用括号,那么查询的范围被限制在括号内,如果你想对来自两个或更多复杂查询的 UNION 结果数据进行排序,那么使用一行中的所有 SELECT 和 UNION 语句,并且在 ORDER BY 子句中使用你想要排序的列的名称。

例子: SELECT * FROM customers UNION SELECT * FROM users ORDER BY name DESC

如果在 SELECT 查询中使用 JOIN,那么只使用列名,而不使用表变量名

例子: SELECT c.name,c.email FROM customers as c JOIN orders as o ON c.id=o.id UNION SELECT u.name,u.email FROM users as u JOIN inventory as i ON u.id=i.id ORDER BY name DESC

我最喜欢的解决方案是创建 CTE

WITH cte as (
(SELECT * FROM table1)


UNION ALL


(SELECT * FROM table2)
)
SELECT *
FROM cte
ORDER BY col1