我在我的存储过程中使用了临时表变量,并使用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中使其工作?
答案 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)
它正在发挥作用:)