Sma*_*003 5 sql sql-server sql-server-2012
我有一张包含以下数据的表格
IF OBJECT_ID('TEMPDB.DBO.#t1', 'U') IS NOT NULL
DROP TABLE #t1;
CREATE TABLE #t1
([c1] varchar(100), [c2] varchar(10), [c3] varchar(100), [c4] varchar(100))
;
INSERT INTO #t1
([c1], [c2], [c3], [c4])
VALUES
(93, '60-1.1.1.', 60, 3),
(104, '60-1.2.1.', 60, 3),
(102, '60-1.1.2.', 60, 3),
(101, '60-1.2.2.', 60, 3),
(92, '60-1.1.3.', 60, 3),
(96, '60-1.2.3.', 60, 3),
(103, '60-1.1.4.', 60, 3),
(94, '60-1.2.4.', 60, 3),
(105, '60-1.2.5.', 60, 3),
(97, '60-1.2.6.', 60, 3),
(99, '60-1.2.7.', 60, 3),
(100, '60-1.2.8.', 60, 3),
(98, '60-1.2.9.', 60, 3),
(95, '60-1.2.10.', 60, 3),
(91, '60-1.2.11.', 60, 3)
;
select * from #t1
Run Code Online (Sandbox Code Playgroud)
表的结果如下
select * from #t1 order by c3,c4
Run Code Online (Sandbox Code Playgroud)
现在我运行以下查询,我得到了预期的结果
select Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1
Run Code Online (Sandbox Code Playgroud)
上述查询的结果如下
现在我使用前1来获取记录我已经编写了如下代码
select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1
Run Code Online (Sandbox Code Playgroud)
上述查询的结果如下
现在我使用top with order by子句然后我得到了以下结果
select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,*
from #t1 order by c3,c4
Run Code Online (Sandbox Code Playgroud)
问题:为什么最后2个查询的结果发生了变化,因为我希望得到相同的结果?
让我用这种方式问你:
当我执行无顺序的前1个查询时,我得到93个记录值,所以当我按列顺序执行前1时,我期望得到相同的结果.根据我的假设,在查询中,caluse没有对订单产生影响
提前致谢
编辑1
即使我执行了100次,结果也一样
编辑2
实际上我已经创建了一个主表并插入了上述记录.在两个不同的会话中运行最后两个查询,结果是相同的
在第二台服务器上完成上述(服务器1中的相同步骤).运行最后两个前1个查询,结果在两个会话中相同.
服务器和会话中的结果似乎相同.
结果
如果您没有ORDER BY子句,则允许 Sql Server 以其想要的任何顺序显示结果.这意味着您可以获得与预期不同的结果.即使你有一个ORDER BY子句,如果结果集中的某些记录与同一个位置相关联,Sql Server也可以使用它想要的记录.
通常,当未指定订单时,Sql Server将以最快的顺序提供结果.这意味着随着时间的推移,结果将趋于有些一致,依赖于主键顺序或索引顺序之类的东西.在您的简单示例中,如果"基础"订单发生变化,那将会令人惊讶.
但重要的是要记住,这种排序完全没有保证.在实际生产环境中,如果您未指定订单,则结果可能会在执行之间发生变化.这可能会发生很多原因,但一个基本的例子是优化,其中两个查询可能在同一索引或表搜索上捎带,第二个查询在第一个查询的中间拾取搜索.另一个原因是表上的统计信息或行计数更改,以致Sql Server决定以不同于之前的方式使用(或不使用)索引.
因此,如果您真的关心在使用选择器时获取特定记录TOP,那么您也应该使用它ORDER BY,并确保您具体到足以明确无误.
对于此特定数据和查询示例,您有一个没有ORDER BY子句的示例和一个带有ORDER BY子句的示例,但第二个示例的子句仅按列c3和顺序排序c4.这些列对每条记录都具有相同的值.这意味着Sql Server仍可以免费使用最方便的订单,因为一切都很紧密.
但是,这并不意味着Sql Server将在第二个查询中使用与第一个查询中相同的顺序.添加该ORDER BY子句迫使Sql Server至少查看并评估结果集,然后才知道哪个记录属于哪个位置,并且该进程可以改变结果在内存中的排列,使得一个全新的顺序看起来最多方便.
因此,我们看看您是否关心结果,您不仅需要一个ORDER BY条款,而且该条款必须具有足够的选择性以保证您想要的顺序.如果要c1显示特定值,则应c1在您的ORDER BY子句中包含.
| 归档时间: |
|
| 查看次数: |
374 次 |
| 最近记录: |