SQL查询-在UNION中使用Order By


83

从两个表中提取数据时,如何以编程方式对联合查询进行排序?例如,

SELECT table1.field1 FROM table1 ORDER BY table1.field1
UNION
SELECT table2.field1 FROM table2 ORDER BY table2.field1

引发异常

注意:正在MS Access Jet数据库引擎上尝试这样做

Answers:


118

有时您需要ORDER BY在每个部分中将与组合在一起UNION

在这种情况下

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

1
为我工作时的顺序会影响结果集(当使用前X为)
詹姆斯Barrass

这正是我想要的!谢谢!
里奇·耶拉(Srichand Yella)2011年

对我来说效果很好...您需要确保外部select具有表别名。那咬我。
Troy

使用Microsoft SQL Server标准版(64位)11.0.5058.0版时,我没有遇到任何问题
hlovdal 2015年

3
在SSMS中,您将需要更改子查询SELECT TOP 100 PERCENT,以便使用ORDER BY在一个子查询
约瑟夫Nields

64
SELECT field1 FROM table1
UNION
SELECT field1 FROM table2
ORDER BY field1

18
从技术上讲,这无法完成您在原始问题中逻辑上要问的问题。
伊恩·博伊德

2
@伊恩·博伊德:我明白你的意思,但是他们的要求没有逻辑上的意义:联合对集合进行操作,集合没有顺序!
2011年

8
@onedaywhen原始作者想要连接两个有序结果集。UNION不允许这种情况发生。可能还有其他构造可以做到这一点。可能没有。无论哪种方式,此答案都无法从技术上实现作者的要求。
伊恩·博伊德

4
@Ian Boyd:在SQL中,它ORDER BY是游标的一部分,而UNION对表进行操作,因此它们的代码无法工作。我看不到如何从荒谬的代码中推断出OP的意图。考虑一下SQLUNION删除了重复项:如果这些是您的“有序结果集”,结果{1, 2, 3} UNION {2, 4, 6}将是{1, 2, 3, 4, 6}还是{1, 3, 2, 4, 6}??我们不知道,因为就SQL而言,“有序列的结果集”的并集是未定义的,并且未指定OP。
2011年

我正在使用MYSQL,我在所有select语句中都包含了字段(订购字段)。然后只需在末尾添加Order by,对我来说很好。
CreativeManix

57

我认为这很好地解释了。

以下是使用ORDER BY子句的UNION查询:

select supplier_id, supplier_name
from suppliers
where supplier_id > 2000
UNION
select company_id, company_name
from companies
where company_id > 1000
ORDER BY 2;

由于两个“ select”语句之间的列名不同,因此按ORDER BY子句在结果集中的位置引用这些列将更为有利。

在此示例中,我们将结果按supplier_name/company_name升序排序,如“ ORDER BY 2”所示。

supplier_name/company_name字段是在结果集中的位置#2。

从这里获取:http : //www.techonthenet.com/sql/union.php


28

使用一个具体的例子:

SELECT name FROM Folders ORDER BY name
UNION
SELECT name FROM Files ORDER BY name

档案:

name
=============================
RTS.exe
thiny1.etl
thing2.elt
f.txt
tcpdump_trial_license (1).zip

资料夹:

name
============================
Contacts
Desktop
Downloads
Links
Favorites
My Documents

所需的输出:(首先选择结果,即首先选择文件夹的结果)

Contacts
Desktop
Downloads
Favorites
Links
My Documents
f.txt
RTMS.exe
tcpdump_trial_license (1).zip
thiny1.etl
thing2.elt

SQL达到预期的效果:

SELECT name 
FROM (
    SELECT 1 AS rank, name FROM Folders
    UNION 
    SELECT 2 AS rank, name FROM Files) dt
ORDER BY rank, name

3
到目前为止,这是最好的答案
javier_domenech

1
这是很棒的答案!
Ali Gonabadi '16

注意-您必须为派生表指定别名(如本示例中的所示dt),否则它将不起作用。这让我有些困惑,因为我一开始就忽略了细节,并且SSMS抛出的错误消息并不是特别有用。
CactusCake

17

这是Northwind 2007的示例:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], [Quantity]
FROM [Product Orders]
UNION SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity]
FROM [Product Purchases]
ORDER BY [Order Date] DESC;

完成所有合并后,只需将ORDER BY子句作为最后一个语句。您可以将多个集合合并在一起,然后在最后一个集合之后放置ORDER BY子句。


9
(SELECT table1.field1 FROM table1 
UNION
SELECT table2.field1 FROM table2) ORDER BY field1 

工作?记住思维定势。使用并集获取所需的集,然后对其执行操作。


如果要排序的字段的名称不同,也可以在order by子句中使用序数值
Anson Smith,

5
SELECT table1Column1 as col1,table1Column2 as col2
    FROM table1
UNION
(    SELECT table2Column1 as col1, table1Column2 as col2
         FROM table2
)
ORDER BY col1 ASC

4
SELECT field1
FROM ( SELECT field1 FROM table1
       UNION
       SELECT field1 FROM table2
     ) AS TBL
ORDER BY TBL.field1

(使用ALIAS)


@DisplacedGuy如果MJ对某个问题有更好的答案,那么上述任何一个问题,在这种情况下,公认的答案显然有问题,那么MJ应该可以,我鼓励他留下新的答案
MobileMon

顺便说一句,MJ的答案是最好的!(至少对我来说)
MobileMon

4

这是我见过的最愚蠢的事情,但是它有效,并且您不能与结果争论。

SELECT *
FROM (
    SELECT table1.field1 FROM table1 ORDER BY table1.field1
    UNION
    SELECT table2.field1 FROM table2 ORDER BY table2.field1
) derivedTable

派生表的内部不会自己执行,但是作为派生表可以很好地工作。我已经在SS 2000,SS 2005,SS 2008 R2和所有这三个版本上进行了尝试。


2

这是怎么做的

select * from 
    (select top 100 percent pointx, pointy from point
     where pointtype = 1
     order by pointy) A
union all
select * from 
    (select top 100 percent pointx, pointy from point
     where pointtype = 2
     order by pointy desc) B

2

浏览此评论部分时,我遇到了两种不同的回答问题的模式。遗憾的是,对于SQL 2012,第二种模式不起作用,所以这是我的“解决方法”


在公共列上排序

这是您最容易遇到的情况。就像许多用户指出的那样,您真正需要做的就是Order By在查询末尾添加一个

SELECT a FROM table1
UNION
SELECT a FROM table2
ORDER BY field1

要么

SELECT a FROM table1 ORDER BY field1
UNION
SELECT a FROM table2 ORDER BY field1

在不同列上排序

这实际上是棘手的地方。使用SQL 2012,我尝试了最高职位,但它不起作用。

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

按照评论中的要求,我尝试了这个

SELECT * FROM 
(
  SELECT TOP 100 PERCENT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT TOP 100 PERCENT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

这段代码确实进行了编译,但是DUMMY_ALIAS1DUMMY_ALIAS2覆盖Order BySelect语句中这使它不可用。

我能想到的唯一对我有用的解决方案不是使用联合,而是使查询单独运行然后处理它们。所以基本上,Union当您想要Order By


1

通过单独使用顺序,每个子集都获得顺序,而不是整个集合,而这正是您希望合并两个表的方式。

您应该使用类似这样的东西来设置一个有序集合:

SELECT TOP (100) PERCENT field1, field2, field3, field4, field5 FROM 
(SELECT table1.field1, table1.field2, table1.field3, table1.field4, table1.field5 FROM table1
UNION ALL 
SELECT table2.field1, table2.field2, table2.field3, table2.field4, table2.field5 FROM  table2) 
AS unitedTables ORDER BY field5 DESC

0

第二个表不能在ORDER BY子句中包含表名。

所以...

SELECT table1.field1 FROM table1 ORDER BY table1.field1
UNION
SELECT table2.field1 FROM table2 ORDER BY field1

不抛出异常


这是一个多么好的问题。您能否确定您的版本(或嵌套版本)是否返回了所需的结果?还是它们都返回相同的结果?如果是这样,(其他人的)嵌套解决方案是否会更高效,因为它只执行一次ORDER BY?
DOK

我不确定Jet引擎的性能会有所提高,但是我想说由于嵌套的缘故,可读性得到了提高。
Curtis Inderwiesche

0

如果有必要保持内部排序:

SELECT 1 as type, field1 FROM table1 
UNION 
SELECT 2 as type, field1 FROM table2 
ORDER BY type, field1

0
(SELECT FIELD1 AS NEWFIELD FROM TABLE1 ORDER BY FIELD1)
UNION
(SELECT FIELD2 FROM TABLE2 ORDER BY FIELD2)
UNION
(SELECT FIELD3 FROM TABLE3 ORDER BY FIELD3) ORDER BY NEWFIELD

试试这个。它为我工作。


0

对于Sql Server 2014/2012 / Others(未选中):

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) 
as DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) 
as DUMMY_ALIAS2

您在2012年尝试此操作时遇到编译错误。该脚本不适用于存储过程。您需要top子句。
蒂莫西·杜林2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.