代码之家  ›  专栏  ›  技术社区  ›  Ray Booysen

SQL Server UNION-默认的行为顺序是什么

  •  33
  • Ray Booysen  · 技术社区  · 17 年前

    如果我有一些工会声明作为人为的例子:

    SELECT * FROM xxx WHERE z = 1
    UNION 
    SELECT * FROM xxx WHERE z = 2
    UNION
    SELECT * FROM xxx WHERE z = 3
    

    order by 行为

    我看到的测试数据基本上没有按照上面指定的顺序返回数据。也就是说,数据是有序的,但我想知道这方面的优先规则是什么。

    另一件事是,在这种情况下,xxx是一个视图。视图将3个不同的表连接在一起,以返回我想要的结果。

    7 回复  |  直到 14 年前
        1
  •  46
  •   DJ.    17 年前

    没有默认顺序。

    没有 订购人 子句返回的订单未定义。这意味着SQL Server可以按照它喜欢的任何顺序将它们带回来。

    根据我所看到的,没有orderby,结果返回的顺序取决于查询计划。因此,如果它正在使用一个索引,那么结果可能会按照该顺序返回,但同样没有保证。

        2
  •  17
  •   Will Rickards    17 年前

    这可能是最基本的,但我想我加上这个。

    例如:

    SELECT 1, * FROM xxx WHERE z = 'abc'
    UNION ALL
    SELECT 2, * FROM xxx WHERE z = 'def'
    UNION ALL
    SELECT 3, * FROM xxx WHERE z = 'ghi'
    ORDER BY 1
    

    当我要运行两个查询并且我知道只有一个查询将返回任何结果时,伪序号列也很有用。然后我可以检查返回结果的序号。这使我不必进行多个数据库调用和大多数空结果集检查。

        3
  •  12
  •   Ray Booysen    17 年前

    因为UNION会删除重复项,所以它会进行不同的排序。这是在连接所有UNION语句之前完成的(检查执行计划)。

    要停止排序,请执行UNION ALL,这样也不会删除重复项。

        4
  •  8
  •   BradC    17 年前

    如果你漏掉它,它可能会 显得

    编辑:一些好的、具体的示例:(所有示例都是MS SQL server)

    • Dave Pinal's blog 描述两个非常相似的查询如何显示不同的外观顺序,因为使用了不同的索引:

      SELECT ContactID FROM Person.Contact
      SELECT *         FROM Person.Contact
      
    • Conor Cunningham 显示当表变大时(如果查询优化器决定使用并行执行计划),外观顺序如何变化。

    • Hugo Kornelis 证明了表观顺序是 始终基于主键。 Here is his follow-up post 解释一下。

        5
  •  2
  •   David Aldridge    17 年前

    就结果集排序而言,联合可能具有欺骗性,因为数据库有时会使用排序方法来提供联合中隐含的DISTINCT,这使得行看起来像是故意排序的——当然,这不适用于没有隐含DISTINCT的联合ALL。

    正如DJ所说,始终使用ORDER BY

        6
  •  1
  •   Cruachan    17 年前

    很常见的情况是,编写得很差的代码假定表数据是按插入顺序返回的,95%的情况下,编码人员都能侥幸逃脱,并且从未意识到这是一个与许多常见数据库(MSSQL、Oracle、MySQL)一样的问题。这当然是一个完全的谬误,应该予以纠正 总是