【问题标题】:How to use order by with union all in sql?如何在sql中使用order by with union all?
【发布时间】:2013-03-18 05:18:10
【问题描述】:

我尝试了下面给出的 sql 查询:

SELECT * FROM (SELECT * 
FROM TABLE_A ORDER BY COLUMN_1)DUMMY_TABLE
UNION ALL 
SELECT * FROM TABLE_B 

这会导致以下错误:

ORDER BY 子句在视图、内联函数、派生中无效 表、子查询和公用表表达式,除非 TOP 或 FOR 还指定了 XML。

我需要在 union all 中使用 order by。我该如何做到这一点?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:
    SELECT  * 
    FROM 
            (
                SELECT * FROM TABLE_A 
                UNION ALL 
                SELECT * FROM TABLE_B
            ) dum
    -- ORDER BY .....
    

    但如果您想将来自Table_A 的所有记录放在结果列表的顶部,您可以添加可用于排序的用户定义值,

    SELECT  * 
    FROM 
            (
                SELECT *, 1 sortby FROM TABLE_A 
                UNION ALL 
                SELECT *, 2 sortby FROM TABLE_B
            ) dum
    ORDER   BY sortby 
    

    【讨论】:

    • @JohnWoo - 'dum' 在这里做什么?
    • @CIvemy dum 是一个表别名。
    • 如果您使用 TOP,则不起作用。看@Fandango68提供的答案
    【解决方案2】:

    不是 OP 的直接响应,但我想我会在这里响应 OP 的 ERROR 消息,这可能会完全指向另一个方向!

    一旦检索到记录集并对批次进行排序,所有这些答案都指的是整体 ORDER BY。

    如果您想独立地对 UNION 的每个部分进行排序,并且仍然让它们“加入”在同一个 SELECT 中,该怎么办?

    SELECT pass1.* FROM 
     (SELECT TOP 1000 tblA.ID, tblA.CustomerName 
      FROM TABLE_A AS tblA ORDER BY 2) AS pass1
    UNION ALL 
    SELECT pass2.* FROM 
      (SELECT TOP 1000 tblB.ID, tblB.CustomerName 
       FROM TABLE_B AS tblB ORDER BY 2) AS pass2
    

    请注意,TOP 1000 是一个任意数字。使用足够大的数字来捕获您需要的所有数据。

    【讨论】:

    • 完美。 Oracle 允许您在任何地方进行排序... SQL Server 的新手... 使用 TOP 很棒但是我发现它的功能在更复杂的查询中非常缺乏... 我不断收到 OP 提到的错误 ORDER BY 错误... 让我订购了该死的结果大声笑。
    • 您可以使用TOP 100 PERCENT 子句。使用任意数字认为它总是大于返回的记录数是不好的做法。
    • @keiichi 这就是为什么 TOP 100 不是一个好主意stackoverflow.com/questions/1622878/…
    【解决方案3】:

    你真的不需要括号。可以直接排序:

    SELECT *, 1 AS RN FROM TABLE_A
    UNION ALL 
    SELECT *, 2 AS RN FROM TABLE_B
    ORDER BY RN, COLUMN_1
    

    【讨论】:

    • 这是否记录在某处?找到了Example C in the UNION doc,但是显示是可以的,不解释了。
    • @Trisped,from where group having select order是逻辑处理顺序。所以最终应用的排序在这里是合法的。 msdn.microsoft.com/en-us/library/ms189499.aspx
    • 值得注意的是,您必须将所有排序的列放在每个 SELECT 子句中。
    • 我不会将此称为正确答案,因为您要选择一个额外的列 (RN)。您并不总是可以选择/奢侈地在结果集中包含任意列。
    • @pedrambashiri 无需选择额外的列。我想这只是为了演示目的。正如 HartleySan 所指出的,您必须在两个 SELECT 子句中命名要排序的列。通过使用别名(RN 列),即使两个表中的列名称不同,您也可以进行排序。
    【解决方案4】:
    select CONCAT(Name, '(',substr(occupation, 1, 1), ')') AS f1
    from OCCUPATIONS
    union
    select temp.str AS f1 from 
    (select count(occupation) AS counts, occupation, concat('There are a total of ' ,count(occupation) ,' ', lower(occupation),'s.') As str  from OCCUPATIONS group by occupation order by counts ASC, occupation ASC
     ) As temp
     order by f1
    

    【讨论】:

      【解决方案5】:

      有时候你需要做这样的事情:

      根据排序从表 1 中拉出前 5 个
      表 2 中的底部 5 基于另一种排序
      并将它们结合在一起。

      解决方案

      select * from (
      -- top 5 records
      select top 5 col1, col2, col3 
      from table1 
      group by col1, col2
      order by col3 desc ) z 
      
      union all
      
      select * from (
      -- bottom 5 records 
      select top 5 col1, col2, col3 
      from table2 
      group by col1, col2
      order by col3 ) z 
      

      这是我能够绕过错误并且工作正常的唯一方法。

      【讨论】:

        【解决方案6】:
        SELECT * FROM (SELECT * 
        FROM TABLE_A ORDER BY COLUMN_1)DUMMY_TABLE
        UNION ALL 
        SELECT * FROM TABLE_B 
        ORDER BY 2;
        

        2 是这里的列号 .. 在 Oracle SQL 中,您可以使用要对数据进行排序的列号

        【讨论】:

          【解决方案7】:

          这解决了我的 SELECT 语句:

          SELECT * FROM 
          (SELECT id,name FROM TABLE_A 
          UNION ALL 
          SELECT id,name FROM TABLE_B )  dum
          order by dum.id , dum.name
          

          其中 id 和 name 列在表中可用,您可以使用您的列。

          【讨论】:

          • 和接受的答案一样
          猜你喜欢
          • 1970-01-01
          • 2016-09-01
          • 2020-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-30
          • 2010-09-26
          相关资源
          最近更新 更多