【问题标题】:SQL: how to use UNION and order by a specific select?SQL:如何使用 UNION 并按特定选择排序?
【发布时间】:2011-08-27 13:34:12
【问题描述】:

我有两个选择:

SELECT id FROM a -- returns 1,4,2,3
UNION
SELECT id FROM b -- returns 2,1

我收到正确的行数,例如:1,4,2,3

但我首先想要b 表结果:2,1,4,32,1,3,4

我该怎么做?

(我正在使用 Oracle)

【问题讨论】:

    标签: sql oracle select union


    【解决方案1】:
    SELECT id FROM a -- returns 1,4,2,3
    UNION
    SELECT id FROM b -- returns 2,1
    order by 2,1
    

    【讨论】:

    • 这不起作用,因为order by 2, 1 按第二列和第一列排序,但在结果集中你只有一列id
    • 是的,确实如此。我就它的例子举了。感谢指正
    【解决方案2】:

    @Adrien 的回答不起作用。它给出了 ORA-01791。

    正确答案(针对所提出的问题)应该是:

    select id
    from 
     (SELECT id, 2 as ordered FROM a -- returns 1,4,2,3
      UNION ALL
      SELECT id, 1 as ordered FROM b -- returns 2,1
      )
    group by id
    order by min(ordered)
    

    解释:

    1. “UNION ALL”将 2 个集合组合在一起。 “UNION”是浪费的,因为 2 个集合不可能相同,因为有序字段不同。
    2. “分组依据”然后消除重复项
    3. “order by min (ordered)”确保表 b 的元素排在第一位

    这解决了所有情况,即使表 b 比表 a 有更多或不同的元素

    【讨论】:

      【解决方案3】:

      @Adrian 的回答非常合适,我只是想分享另一种实现相同结果的方法:

      select nvl(a.id, b.id)
      from a full outer join b on a.id = b.id
      order by b.id;
      

      【讨论】:

        【解决方案4】:
        SELECT id, 1 AS sort_order
          FROM b
        UNION
        SELECT id, 2 AS sort_order
          FROM a
        MINUS
        SELECT id, 2 AS sort_order
          FROM b
        ORDER BY 2;
        

        【讨论】:

          【解决方案5】:

          使用@Adrian 提示,我找到了解决方案:

          我正在使用 GROUP BYCOUNT。 我尝试将 DISTINCTORDER BY 一起使用,但我收到错误消息:"not a SELECTed expression"

          select id from 
          (
              SELECT id FROM a -- returns 1,4,2,3
              UNION ALL -- changed to ALL
              SELECT id FROM b -- returns 2,1
          )
          GROUP BY id ORDER BY count(id);
          

          感谢 Adrian 和 this 博客。

          【讨论】:

          • 如果你想要“b”行首先,你不想要 COUNT(id) DESC 吗?此外,这仅在“b”是“a”中记录的子集时才有效。最后,鉴于此特定示例,您不能依赖以任何特定方式排序的“b”或“a”中的记录。当我尝试这个时,我得到了 1,2,4,3 的输出。
          • a) 是的,在这个例子中我需要 DESC(我忘了放)。但在我的应用程序中,我需要在表格末尾。 b) 没问题,在我的应用程序中,表 ba 的子集。 c) 好的,无论原件选择的顺序是什么。计数完成工作:)
          • 那么你很好;-) 我想你得到了你需要的答案,我主要想向其他人指出这个解决方案中需要注意的一些事情。我认为这里 COUNT 的使用很巧妙。
          • 如果表 B 包含表 A 中没有的值,此解决方案将不起作用。
          • @Adrian:它们将被包括在内,但它们的计数将为 1,因此它们将与表 A 中的值混合。
          【解决方案6】:

          你想这样做:

          select * from 
          (
              SELECT id, 2 as ordered FROM a -- returns 1,4,2,3
              UNION
              SELECT id, 1 as ordered FROM b -- returns 2,1
          )
          order by ordered
          

          更新

          我注意到,即使您有两个不同的表,您也加入了 ID,这意味着,如果您在两个表中都有 1,那么您只会出现一次。如果这是所需的行为,您应该坚持使用UNION。如果没有,请更改为UNION ALL

          所以我还注意到,如果您更改我提出的代码,您将开始同时获得12(来自ab)。在这种情况下,您可能希望将建议的代码更改为:

          select distinct id from 
          (
              SELECT id, 2 as ordered FROM a -- returns 1,4,2,3
              UNION
              SELECT id, 1 as ordered FROM b -- returns 2,1
          )
          order by ordered
          

          【讨论】:

          • +1 你可以在联合的第二部分省略列别名
          • 是的,我知道。但是在 SO 中你必须要快:)
          • 起来!不太完美:我得到了重复的结果……而且 distinct 不起作用……
          • UNION 不过滤重复项,因为这两个集合由于排序常数而不同。
          • +1 - 通过演示您向 ORDER BY 提供别名而不是列名来帮助我!棘手,干得好。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-05-04
          • 2011-06-10
          • 1970-01-01
          • 2019-01-14
          • 1970-01-01
          • 2017-06-02
          • 2014-02-22
          相关资源
          最近更新 更多