[英]how the top 1 works in 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
该表的结果如下
select * from #t1 order by c3,c4
现在我运行以下查询,我得到了预期的结果
select Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1
以上查询的结果如下
现在我已使用前1个来获取记录,我已将代码编写如下
select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1
以上查询的结果如下
现在我将top和order by子句一起使用,然后得到以下结果
select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,*
from #t1 order by c3,c4
问:为什么我希望得到相同的结果,所以最近2个查询的结果有所变化?
让我以这种方式问你:
当我不按顺序执行前1个查询时,我得到93个记录值,因此当我按列进行前1个查询时,我期望得到相同的结果。 在查询中,根据我的假设,没有因考量而影响订单
提前致谢
编辑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
列c4
。 这些列的每条记录都具有相同的值。 这意味着Sql Server仍然可以自由使用最方便的顺序,因为一切都可以。
但是,这并不意味着Sql Server将在第二个查询中使用与第一个查询相同的顺序。 添加ORDER BY
子句强制Sql Server在知道哪个记录属于哪个位置之前,至少要查看并评估结果集,并且该过程可以改变结果在内存中的排列,从而使一个全新的顺序出现最方便。
因此,我们看到您是否关心结果,不仅需要ORDER BY
子句,而且该子句必须具有足够的选择性以保证所需的顺序。 如果要显示特定的c1
值,则应在ORDER BY
子句中包含c1
。
没有适当的order by子句,由于表不一定按任何顺序读取,您将继续获得意外结果。 您在上一个查询中使用的order by语句强调了此问题。 由于所有数据都具有相同的c3,c4值,因此它们在返回时具有相同的优先级。 这意味着未指定返回值的顺序。 我建议您查看这篇文章以了解更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.