【问题标题】:SQL Query - Using Order By in UNIONSQL 查询 - 在 UNION 中使用 Order By
【发布时间】:2010-09-17 20:24:08
【问题描述】:

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

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

抛出异常

注意:这是在 MS Access Jet 数据库引擎上尝试的

【问题讨论】:

    标签: sql ms-access sorting sql-order-by union


    【解决方案1】:

    有时您需要在每个需要与UNION 组合的部分中包含ORDER BY

    在这种情况下

    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
    

    【讨论】:

    • 在 order by 影响结果集时为我工作(如使用 Top x 时)
    • 这正是我要找的!谢谢!
    • 对我很有用...您需要确保外部选择具有表别名。那咬我。
    • I had no problems 在 Microsoft SQL Server Standard(64 位)版本 11.0.5058.0 中使用此语法。
    • 在 SSMS 中,您需要将子查询更改为 SELECT TOP 100 PERCENT 以便在子查询中使用 ORDER BY
    【解决方案2】:
    SELECT field1 FROM table1
    UNION
    SELECT field1 FROM table2
    ORDER BY field1
    

    【讨论】:

    • 从技术上讲,这并不能满足您在原始问题中的逻辑要求。
    • @Ian Boyd:我同意你的观点,但他们的要求没有逻辑意义:联合对集合进行操作,集合没有顺序!
    • @onedaywhen 原作者想要连接两个有序的结果集。 UNION 不允许这种情况发生。可能有另一种构造来做到这一点。可能没有。无论哪种方式,这个答案在技术上都不能满足作者的要求。
    • @Ian Boyd:在 SQL 中,ORDER BY 是游标的一部分,而UNION 对表进行操作,因此它们的代码无法运行。我看不出您如何从荒谬的代码中推断出 OP 的意图。考虑 SQL 的 UNION 删除重复项:如果这些是您的“有序结果集”{1, 2, 3} UNION {2, 4, 6},结果会是 {1, 2, 3, 4, 6} 还是 {1, 3, 2, 4, 6}?我们不知道,因为关于 SQL 的“有序结果集”的联合是未定义的,并且 OP 没有指定。
    • 我使用的是 MYSQL,我在所有的 select 语句中都包含了字段(Ordering 字段)。然后在最后添加了 Order by,对我来说很好。
    【解决方案3】:

    我认为这很好解释。

    以下是使用 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 字段位于 结果集。

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

    【讨论】:

      【解决方案4】:

      用一个具体的例子:

      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
      

      【讨论】:

      • 这是迄今为止最好的答案
      • 这是一个很好的答案!
      • 注意 - 你必须给派生表一个别名(如本例中的dt所示),否则它将不起作用。我对此感到困惑了一会儿,因为我一开始就省略了那个细节,而且 SSMS 抛出的错误消息并不是特别有用。
      【解决方案5】:

      以下是 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 子句。

      【讨论】:

        【解决方案6】:
        (SELECT table1.field1 FROM table1 
        UNION
        SELECT table2.field1 FROM table2) ORDER BY field1 
        

        工作?记住思考集。使用联合获取您想要的集合,然后对其执行操作。

        【讨论】:

        • 您也可以在 order by 子句中使用序数值,以防您希望排序的字段名称不同
        【解决方案7】:
        SELECT table1Column1 as col1,table1Column2 as col2
            FROM table1
        UNION
        (    SELECT table2Column1 as col1, table1Column2 as col2
                 FROM table2
        )
        ORDER BY col1 ASC
        

        【讨论】:

          【解决方案8】:
          SELECT field1
          FROM ( SELECT field1 FROM table1
                 UNION
                 SELECT field1 FROM table2
               ) AS TBL
          ORDER BY TBL.field1
          

          (使用别名)

          【讨论】:

          • @DisplacedGuy 如果 MJ 对某个问题有比上述任何一个更好的答案,并且在这种情况下,接受的答案显然有问题,那么 MJ 应该能够并且我鼓励他离开新的答案
          • 顺便说一句,MJ 的回答是最好的! (至少对我来说)
          【解决方案9】:

          这是我见过的最愚蠢的事情,但它确实有效,而且你无法与结果争论。

          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 上尝试过这个,并且所有三个都可以工作。

          【讨论】:

            【解决方案10】:

            这是怎么做的

            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
            

            【讨论】:

              【解决方案11】:

              浏览此评论部分,我遇到了两种不同的回答问题的模式。可悲的是,对于 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 覆盖了在 Select 语句中建立的 Order By,这使得它无法使用。

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

              【讨论】:

                【解决方案12】:

                通过单独使用顺序,每个子集都会获得顺序,但不是整个集合,这就是您想要合并两个表的结果。

                你应该使用这样的东西来拥有一个有序集:

                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
                

                【讨论】:

                  【解决方案13】:

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

                  所以...

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

                  不抛出异常

                  【讨论】:

                  • 这是个好问题。您能说出您的版本还是嵌套版本是否返回了所需的结果?或者,它们是否都返回相同的结果?如果是这样,(其他人的)嵌套解决方案是否会因为它只执行一次 ORDER BY 而性能更高?
                  • 我不确定 Jet 引擎的性能优势,但我会说由于嵌套增加了可读性。
                  【解决方案14】:

                  如果需要保持内部排序:

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

                  【讨论】:

                    【解决方案15】:
                    (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
                    

                    试试这个。它对我有用。

                    【讨论】:

                      【解决方案16】:

                      对于 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 年尝试这个时遇到编译错误。该脚本不适用于存储过程。您需要顶部子句。
                      猜你喜欢
                      • 1970-01-01
                      • 2021-03-30
                      • 2011-04-10
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-09-26
                      • 2010-10-04
                      相关资源
                      最近更新 更多