2010-08-20 46 views
85

我想在union查询中使用order by。 我根据不同的标准从基于距离的表格中获取不同类型的记录,以便在我的网站上进行搜索。 第一个选择查询返回与确切地点搜索相关的数据。 第二个选择查询返回距离搜索地点5公里内距离的数据。 第三个选择查询返回距离搜索地点5-15公里内距离的数据。在mysql中使用union和order by子句

然后,我使用union来合并所有结果并在页面上显示分页。在适当的标题为“精确搜索结果”“结果内5公里”

现在我想根据ID或add_date到结果排序。但是,当我在我的查询(查询1联合查询2联合查询3由add_date顺序)的末尾添加order by子句时。它对所有结果进行排序。但是我想要的是它应该在每个标题下排序。

+0

您想在每个表格中排序的字段是什么类型? – user151841 2010-08-20 13:32:52

回答

163

您可以通过添加一个伪列命名等级给每个做这个选择,你可以通过先进行排序,通过你的其他标准进行排序之前,例如:

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 
+0

嗨,谢谢你,我正是用这种方式。但我想要的是,我想按降序排列选择基于add_date的查询结果。 – Aditya 2010-08-20 16:40:14

+0

你可以使用'desc'关键字。我更新了上面的查询。 – RedFilter 2010-08-20 16:46:28

+0

我只是对代码进行了快速更改,结果非常棒。你让我今天一整天都感觉很好。谢谢 – Aditya 2010-08-21 04:52:57

0

尝试:

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

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

0

这是因为你的排序整个结果集,您应该单独排序,联盟的每一个部分,或者您可以使用ORDER BY(有什么即子查询距离)THEN(即东西行ID)子句

4

联合查询只能有一个主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字段可以是您可能要排序什么。在这个例子中,它偏偏把结果从第一个表第一,第二台第二等

38

您可以使用子查询做到这一点:通过

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

Tnx,很好的一个分开订单。此外,我们可以有不同的安排如果订单条款是常见的,但我们想要的结果分离(而不是分离的订单): 'SELECT * FROM( SELECT AAA AS上校,1官方FROM表1 UNION ALL SELECT BBB作为官员,0作为官员从表2 )AS tbl ORDER BY Official,Col' – Alix 2013-12-12 13:21:53

+6

这是[不正确](http://dev.mysql.com/doc/refman/5.7/en/union.html):*对单个'SELECT'语句使用'ORDER BY'意味着在最终结果中行出现的顺序没有任何意义。* – shmosel 2016-03-22 19:05:28

+0

你是对的,接受的答案也是正确的。当我测试它时,这恰好运行良好。 – rickythefox 2016-03-29 16:29:03

0

我尝试添加的顺序给每个工会之前的查询如

(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 

这可能是一个有点棘手,因为你想要按范围分组,但我认为它应该是可行的。

+0

user151841 union_sort下面的想法将是一个很好的方式来处理分组 – 2010-08-20 14:10:53

2

我得到了这个工作加入联盟。

(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 
23
(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 
+0

这工作,但奇怪我需要改变一件事:我需要给按排序的字段共享别名。除此之外,谢谢! – HoldOffHunger 2016-09-13 23:57:34

6

不要忘记,UNION ALL是将记录添加到记录集不排序或合并(与工会)的方式。

因此,例如:

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 

它使各个查询更清晰,让您在每个查询不同的参数来进行排序。然而,通过使用所选答案的方式,可能会变得更加清晰,具体取决于复杂性以及数据的相关程度,因为您将这种排序概念化。它还允许您将人工列返回给查询程序,以便它具有可以排序或组织的上下文。

但是这种方式具有快速的优点,不会引入额外的变量,并且可以很容易地分离出包括排序在内的每个查询。增加限制的能力只是额外的奖励。

当然,可以随意将union全部变为union并为整个查询添加一个排序。或者添加一个人工ID,在这种情况下,这种方式可以很容易地按每个查询中的不同参数进行排序,但它与接受的答案相同。