10

在 2008 年和 2012 年执行以下 SQL。在 2008 年执行时,返回的结果是正确的排序顺序。2012 年不保留排序顺序。

这是已知的变化吗?2012 年是否有解决方法来保留排序顺序?

CREATE TABLE #MyTable(Name VARCHAR(50), SortOrder INT)
INSERT INTO #MyTable SELECT 'b', 2 UNION ALL SELECT 'c', 3 UNION ALL SELECT 'a', 1 UNION ALL SELECT 'e', 5 UNION ALL SELECT 'd', 4

SELECT * INTO #Result FROM #MyTable ORDER BY SortOrder

SELECT * FROM #Result

DROP TABLE #MyTable
DROP TABLE #Result
4

6 回答 6

17

您如何通过使用来判断表格内的订单是什么select * from #result?不能保证查询中的顺序select

但是,SQL Fiddle 上的结果不同。如果要保证结果是一样的,那就加一个主键。然后保证插入顺序:

CREATE TABLE MyTable(Name VARCHAR(50), SortOrder INT)
INSERT INTO MyTable SELECT 'b', 2 UNION ALL SELECT 'c', 3 UNION ALL SELECT 'a', 1 UNION ALL SELECT 'e', 5 UNION ALL SELECT 'd', 4


select top 0 * into result from MyTable;

alter table Result add id int identity(1, 1) primary key;

insert into Result(name, sortorder)
    SELECT * FROM MyTable
    ORDER BY SortOrder;

在这之后我仍然厌恶这样做select * from Result。但是,是的,它在 SQL Server 2008 和 2012 中都以正确的顺序返回它们。不仅如此,而且因为 SQL Server 保证主键以正确的顺序插入,甚至可以保证记录在这个案例。

但 。. . 仅仅因为记录在页面上的特定顺序并不意味着它们将在没有order by子句的情况下按该顺序检索。

于 2013-05-20T18:15:42.030 回答
9

ORDER BY与 an 一起使用时,除了控制标识列的顺序(如果存在INSERT)之外,它从未保证做任何事情。

在 SQL Server 2012 之前,优化器总是生成一个计划,就好像存在标识列一样,因此看起来排序正确。SQL Server 2012 正确地不假定存在标识列,并且仅在表实际上具有标识列时才进行排序。

因此,您可以通过在临时结果表中添加标识列来解决此问题。

但是,您真的应该在语句中添加一个ORDER BY子句SELECT吗? SELECT没有 a 的语句ORDER BY从未保证以任何特定顺序返回结果。始终添加该ORDER BY子句以确保您以预期的方式收到结果。

于 2013-05-20T18:30:19.227 回答
2

首先,感谢 sgeddes 的解释,它帮助很大。关于定义表变量或创建临时表的事情是您必须定义它,如果您要完成定义它的工作,您不妨以正确的方式进行插入:

INSERT INTO #Result (col1, col2...)
SELECT Col1, Col2... FROM #MyTable....

在我的例子中,INSERT 中的 ORDER BY 是动态的,所以当我调用“SELECT * FROM #Result”时,ORDER BY 是未知的。我的解决方案是添加一个 ROW_NUMBER 列,我可以在获取数据时将其硬编码到 SELECT 中。是的,我仍然必须包含一个 ORDER BY,但至少它是静态的。这是我所做的:

--Insert
SELECT ROW_NUMBER() OVER (ORDER BY T.SortOrder ASC) AS RowNum, T.*  
INTO #Result 
FROM (SELECT * FROM #MyTable ...) AS T;

--Get data out
SELECT * FROM #Result ORDER BY RowNum;

希望这可以帮助。

于 2015-09-18T16:47:06.963 回答
0

如果您在查询每个数据库时有不同的排序结果,则您的排序规则可能在两者之间有所不同。

尝试在查询中显式设置排序规则,看看您的结果是否在两个数据库中以相同的顺序返回,例如

SELECT * FROM #Result ORDER BY C1 COLLATE Latin1_General_CS_AS
于 2013-05-20T18:10:52.780 回答
0

解决方法:您可以SET ROWCOUNT在这种类型的查询之前添加一个,然后在重置它之后将 if 放回零,它可以工作。这将强制 SQL 保持查询中的顺序。

SET ROWCOUNT 1000000000

CREATE TABLE #MyTable(Name VARCHAR(50), SortOrder INT)
INSERT INTO #MyTable SELECT 'b', 2 UNION ALL SELECT 'c', 3 UNION ALL SELECT 'a', 1 UNION ALL SELECT 'e', 5 UNION ALL SELECT 'd', 4

SELECT * INTO #Result FROM #MyTable ORDER BY SortOrder

SELECT * FROM #Result

SET ROWCOUNT 0

DROP TABLE #MyTable
DROP TABLE #Result
于 2014-02-24T16:22:56.427 回答
0

您必须按要订购的列创建 ROW_NUMBER() 订单。直接在选择中排序,在执行插入时被忽略。

创建表#MyTable(名称VARCHAR(50),SortOrder INT)

插入#MyTable
选择'b',2
联合所有选择'c',3
UNION ALL SELECT 'a', 1
联合所有选择'e',5
UNION ALL SELECT 'd', 4

选择名称,
        ROW_NUMBER() OVER (ORDER BY MyTable.SortOrder) AS SortOrder
INTO #结果
从#MyTable 作为我的表
按排序顺序排序

选择 * 从 #结果

删除表#MyTable
删除表#结果
于 2016-02-24T16:11:50.880 回答