SQL Server 2008与2014中的order by子句行为的差异

时间:2015-03-31 16:39:42

标签: sql-server sql-server-2008 sql-order-by sql-server-2014

我在我的存储过程中使用了临时表变量,并使用order by子句从另一个临时表中插入临时表。它在SQL Server 2008中工作。Order by子句在插入表时正在工作。

但是现在我已将数据库升级到SQL Server 2014,现在order by子句的行为已经改变。它不再以有序的方式插入数据。

例如:

    declare @table1 table(id int, datecolumn datetime)
    declare @table2 table(id int, datecolumn datetime)
    declare @table3 table(id int, datecolumn datetime)

    insert into @table1 values(1, getdate());
    insert into @table1 values(1, DATEADD(hour, 1, getdate()));
    insert into @table1 values(1, DATEADD(hour, 2, getdate()));
    insert into @table2 values(2, getdate());
    insert into @table2 values(2, DATEADD(minute, 55, getdate()));
    insert into @table2 values(2, DATEADD(minute, 130, getdate()));

    insert into @table3
       select * 
       from  
          (select * from @table1
           union all 
           select * from @table2) t 
       order by datecolumn

    select * from @table3

在SQL Server 2008中输出正确

id  datecolumn
---------------------------
1   2015-03-31 21:27:48.290
2   2015-03-31 21:27:48.290
2   2015-03-31 22:22:48.290
1   2015-03-31 22:27:48.290
1   2015-03-31 23:27:48.290
2   2015-03-31 23:37:48.290

但在SQL Server 2014中,它显示不正确的

id  datecolumn
----------------------------
1   2015-03-31 10:57:22.920
1   2015-03-31 11:57:22.920
1   2015-03-31 12:57:22.920
2   2015-03-31 10:57:22.920
2   2015-03-31 11:52:22.920
2   2015-03-31 13:07:22.920

如何在SQL Server 2014中使其工作?

3 个答案:

答案 0 :(得分:3)

您必须在select中包含order by子句。 SQL Server不保证行的顺序保持与插入中的顺序相同。可以使用原始时间列或添加标识字段。

答案 1 :(得分:1)

SQL表中物理存储的订单数据通常不是由插入的顺序决定的,而是由表上的聚集索引决定的。实际上,如果您没有聚簇索引,则订单未定义。

如果它不是临时表,您可以检查表的设计并查找聚簇索引,可能在表的主键内。

但是,您不应该依赖聚集索引在任何查询中提供有序结果。优化器可以选择不同的索引来检索数据,例如,如果有一个较小的覆盖索引返回数据(请参阅Without ORDER BY, there is no default sort order.以及更多详细信息No Seatbelt - Expecting Order without ORDER BY由@marc_s提供)< / p>

简而言之,表中数据的物理顺序在优化器内部是有意义的,但如果您希望结果有序,则添加ORDER BY子句。

答案 2 :(得分:-1)

感谢各位帮忙。从SQL Server 2012执行的顺序已经改变。因此,现在添加主键将为我提供与SQL Server 2008相同的输出。

所以现在我已将表格改为

declare @table3 table (Sort_Id INT IDENTITY(1,1) PRIMARY KEY, id int, datecolumn datetime)

它正在发挥作用:)