如何前1作品在SQL Server 2012

问题描述:

我有以下数据如何前1作品在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 

表的结果如下

enter image description here

select * from #t1 order by c3,c4 

enter image description here

现在我跑了以下查询我得到了预期的结果

select Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1 

上述查询的结果如下

enter image description here

现在我已经使用顶1获取的记录我所编写的代码如下

select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1 

的以上查询结果如下

enter image description here

我现在已经使用顶部带有ORDER BY子句然后我得到了以下结果

select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* 
from #t1 order by c3,c4 

enter image description here

问:为什么在过去的2个查询结果的变化,如我所喜欢期待相同的结果?

让我问你这样:

当我没有为了执行前1查询通过我得到了93的记录值,所以当我按列与顺序执行前1我希望同样的结果。在查询按我的设想有通过caluse无秩序的影响

在此先感谢

编辑1

甚至当我执行100个时结果是相同的

EDIT 2

  • 服务器1

其实我已经创建了一个主表并插入了上面的记录。运行两个不同的会话的最后两个查询,结果是相同的

  • 服务器2

完成在第二服务器中的上述(在服务器1相同的步骤)。运行最后两个前1个查询,结果在两个会话中是相同的。

结果似乎在服务器和会话中都是相同的。

结果

enter image description here

执行计划enter image description here

+1

第一个查询不会使用'order by'与'top'..and第二个确实..但是,因为在c3,c4值中有关系,除非您在'order by'中指定了不同的列,结果将是任意的。 –

+0

如果没有'ORDER BY' –

+0

@vkp,它不会执行任何操作,但是执行100次后结果相同 – Smart003

当你有没有ORDER BY所产生的排序不确定性。
所以我不确定你感到如此惊讶。

+0

让我这样问你: 当我执行顶部1查询没有秩序时,我得到了93个记录值,所以当我执行顶部1按列排序时,我期望得到相同的结果。在查询中,根据我的假设,没有条款 – Smart003

没有正确的order by子句,由于表不一定以任何顺序读取,您将继续得到意想不到的结果。在最后一个查询中使用的order by语句强调了这个问题。由于所有数据都具有相同的c3,c4值,它们在返回时都具有相同的优先级。这意味着返回值的顺序是未指定的。我建议查看this post以了解更多信息。

+0

的订单影响,那么为什么我得到了相同的结果,即使在不同的会话中执行也是如此 – Smart003

+0

关系数据库没有自然顺序,虽然它可能显示基于许多测试,上面说的@vkp并不一定一致。看看这个答案是一个非常类似的问题:https://*.com/a/20050403/2461717 – sschmitz

+0

“随机”一词是这个答案是不正确的,不必要的混淆。值的顺序是未指定的,而不是随机的。查询优化器不会在行的周围进行混洗,只要相同的查询编译为相同的查询执行计划,结果的顺序就不会改变。但看似微不足道的更改可能导致具有不同顺序的不同查询执行计划。 – hvd

如果你没有一个ORDER BY条款时,SQL Server是允许呈现的结果就是了任何顺序。这意味着你可以得到不同于预期的结果。即使你有一个ORDER BY子句,如果结果集中的某些记录与同一位置相关,Sql Server可以使用它想要的顺序来记录相关记录。

通常,当没有指定订单时,Sql Server将以任何最快的顺序提供结果。这意味着随着时间的推移,结果将趋于一致,依赖于诸如主键顺序或索引顺序之类的内容。在你的简单例子中,如果这个“基础”顺序改变了,那将是令人惊讶的。

请务必记住,订购根本不能保证。在真实的生产环境中,如果您未指定订单,结果可能会在执行期间发生变化。出现这种情况的原因有很多,但一个基本的例子是优化,其中两个查询可能搭载在相同的索引或表寻找上,第二个查询在第一个查询中搜索。另一个原因是对表进行统计或行计数更改,以便Sql Server决定使用(或不使用)与以前不同的索引。

因此,如果您真的在使用像TOP这样的选择器时关心获取特定记录,那么您确实也应该使用ORDER BY,并确保您具有足够的明确性。


对于这个特定的数据和查询样,你有没有ORDER BY第一个样本,并用ORDER BY第一个样本,但只能通过列c3c4条款的第二样订货。 这些列对每个记录都有相同的值。这意味着Sql Server仍然可以*地使用任何顺序,因为所有的东西都是最方便的。

但是,这并不意味着Sql Server将在第二个查询中使用与第一个查询中相同的顺序。添加ORDER BY子句迫使Sql Server至少查看并评估结果集,然后才能知道哪个记录属于哪个位置,并且该进程可以改变结果在内存中的排列,使得整个新的订单看起来像是最方便。

所以我们看看你是否关心结果,你不仅需要一个ORDER BY条款,但是这个条款必须有足够的选择性来保证你想要的订单。如果您想要显示特定的c1值,则应在ORDER BY子句中包含c1

+0

谢谢老板,很好的解释,我只在主要环境中使用了order by子句,但我们的问题是显示93,但是104显示我不知道它背后的原因。你可以解释一下,在上面的表中,我按列顺序仍然值不同 – Smart003

+0

有列是字符串/ varchar类型,不是数字/ int类型。订购时,列不知道有数字值,并进行文本比较。在这种情况下,'1'在'9'之前,所以'104'在'93'之前。无序示例中得到93,因为sql server查看堆顺序(插入记录的顺序),并首先找到93,但在有序示例中找到了93,因为您将其强制置顶。 –

+0

,但排序是按其他列(c3,c4)完成的,因为您按照您的评论说你选择的列将会对查询结果产生影响1 – Smart003