我了解您无法在视图中看到ORDER BY。 (至少在我正在使用的SQL Server 2012中)

我也理解对视图进行排序的“正确”方法是在查询视图的ORDER BY语句周围放置一个SELECT

但是相对于实际的SQL和视图的用法而言,我还是比较陌生,我想了解为什么这是设计使然。如果我正确地遵循了历史记录,这曾经是可能的,并且已从SQL Server 2008中明确删除,依此类推(请不要在确切的版本上引用我的意思)。

但是,我能想出为什么Microsoft删除此功能的最好原因是“视图是未排序的数据集合”。

我假设这是为什么不对视图进行排序的一个很好的逻辑原因。为什么视图不能只是扁平化的数据收集?为什么特别未排序?似乎很难(至少对我/恕我直言)提出一种具有排序视图的情况。

评论

第一个答案是完美的。我建议您是否要订购视图,为什么不这样做。从[YourView]中选择[列]按[列]排序

简短的答案:“出于同样的原因,ORDER BY不属于表。”

#1 楼

(当然,不包括索引视图。)

视图没有实现-数据没有存储,那么如何排序呢?视图有点像一个存储过程,只包含一个不带参数的SELECT ...它不保存数据,只保存查询的定义。由于对视图的不同引用可能需要以不同的方式对数据进行排序,因此您执行此操作的方式(就像从表中进行选择一样,根据定义,该表也是行的未排序集合)将在外部查询中包含排序依据。

还可以对历史有所了解。如果不包括ORDER BY,则永远无法将TOP置于视图中。在这种情况下,ORDER BY决定TOP包含哪些行,而不是如何显示它们。碰巧的是,在SQL Server 2000中,如果TOP100 PERCENT{some number >= number of rows in the table},则优化器相当简单,最终生成的计划与TOP/ORDER BY相匹配。但是,这种行为从未得到保证或记录-只是基于观察,这是一个坏习惯。当SQL Server 2005发布时,由于优化程序的更改(导致使用不同的计划和运算符),此行为开始“中断”,其中,如果TOP / ORDER BYTOP 100 PERCENT,则将被完全忽略。一些客户对此抱怨很大,以至于Microsoft发布了一个跟踪标志以恢复旧的行为。我不会告诉您该标志是什么,因为我不想让您使用它,并且我想确保该意图是正确的-如果您想要可预测的排序顺序,请在外部查询上使用ORDER BY。 br />
总结和阐明您的观点:Microsoft没有删除任何内容。他们使产品变得更好,并且作为副作用,这种无证,无保证的行为变得不那么可靠。总体而言,我认为该产品更好。

评论


这里提到(在注释中)TOP对结果集执行游标操作。因此,它可以具有明确的顺序。

– Tim Schmelter
2012年7月24日在20:46

@TimSchmelter在优化器看到TOP 100 PERCENT / ORDER BY并将其从计划中完全删除时无济于事。试试看。

–亚伦·伯特兰(Aaron Bertrand)
2012年7月24日在20:47

这只是一个旁注。无论如何,其余的注释如下:“计划在SQL Server的未来版本中不建议使用SELECT TOP x技巧,因此最好不要使用它。”

– Tim Schmelter
2012年7月24日在20:51

@TimSchmelter,它已经是禁忌了。我认为它不会很快停止在任何新版本中工作,因为它将破坏太多现有代码。

–亚伦·伯特兰(Aaron Bertrand)
2012年7月24日在20:52

@TimSchmelter那里的顺序不是在谈论行的顺序,而是在谈论行中列的顺序。在SQL Server中,我们通常不谈论行是元组,因为行的物理实现对我们是如此明显(表以您定义它们的顺序列出了这些列)。

–亚伦·伯特兰(Aaron Bertrand)
2012年7月24日在21:07

#2 楼

如果允许对视图进行排序,那么结果的顺序应该是什么?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 


评论


我不明白这一点。除了编写数据库视图外,您还可以编写普通的sql查询。那么在那种情况下结果的顺序应该是什么?谢谢

– hqt
16 Dec 19'在18:50

#3 楼

一种可能是避免发生冲突的排序-如果视图按一个顺序排序,而该视图上的选择按另一顺序排序(不知道视图的排序),则可能会导致性能下降。因此,将排序要求留给用户会更安全。

另一个原因,排序会带来性能成本,因此,当只有一些用户需要排序时,为什么要惩罚视图的所有用户。 br />

#4 楼

出于各种原因,ANSI SQL只允许在最外面的查询上使用ORDER BY,这是由于将subselect / view / CTE连接到另一个表而外部查询本身具有ORDER BY时会发生的情况。

SQL服务器从不在视图内支持它(除非您使用TOP 100 PERCENT欺骗了它,我认为它主要是在触发错误)。

即使触发了错误,结果也始终不可靠,并且无法进行排序并非总是会像您期望的那样出现。

请参阅Query Optimizer团队的此博客文章,以获取完整的技术解释,以被认为有害的TOP 100%ORDER BY。


此代码的默认计划实现是对行进行排序,这是执行TOP操作的一部分。通常,这意味着
碰巧按排序顺序返回了结果,这使
客户认为可以保证对行进行了排序。
实际上并非如此。如果希望按排序顺序将行返回给
用户,则需要在最外面的
查询块(按ANSI)上使用ORDER BY以保证输出的显示顺序。


#5 楼

视图的行为类似于表,其内容由查询的结果确定。

表没有顺序;它们只是成排的行。

因此,视图也没有顺序。不过,您可以通过选择特定ORDER中的行对它们进行排序。

评论


表格...只是一排排的行-然后viwe只是虚拟的排成行的虚拟包-视图“不存在”-例如根本没有为他们存储任何数据-基本上,它们只是“存储要执行的查询的定义”。

– marc_s
2012年7月24日在20:36

+1对我而言,表格和视图的等效性似乎是视图不应包含“ order by”的主要原因

– Miracle173
2012年7月25日在7:34

“视图的行为就像表”。我会说“视图的行为类似于基表。视图是表。”

–超立方体ᵀᴹ
2012年7月31日,0:49

#6 楼

尚未给出一个答案,即“ order by”会干扰谓词推入,这会极大地影响性能。

一个示例是,将大量数据汇总为1​​0行汇总,是前10名/已排序:

select * from TopOrderedView; -- Ordered 10 line summary in 5s


对于具有强谓词的相同情况:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s


它仍然花费相同的时间,因为top / order by阻止谓词在管道中更早地运行。这可能会导致不必要的行得到处理,并且该计划将类似于没有谓词的行。

是否应该在下达订单之前进行推送确实是开发人员的选择,并且可以更改答案。大多数情况下,推送是逻辑意图。

逻辑上使用“前100%”允许谓词推送,但是不幸的是,在这种情况下,实现忽略了“ order by”并破坏了意图。

对于实际用例,一个不错的折衷办法是使引擎执行“拉动排序”。这将允许在视图中指定“排序依据”(排名前100%或不排名最高),并且仅当视图是直接选择而无显式排序依据,没有联接,没有聚合,没有时才使用该顺序视图链接等。此简单模型可以支持上面列出的两种情况。

#7 楼

您可以创建一个具有排序依据并在查询后保留排序依据的视图:

从..... order by
中选择顶部99.999999999999%*

评论


为什么不选择SELECT TOP 100%...?

– Max Vernon♦
15年12月16日在21:08

@Max可能与此技巧类似-并不是一个好主意。

–亚伦·伯特兰(Aaron Bertrand)
15年12月16日在21:30

同意@AaronBertrand-仅注意无需使用99.99999999999 :-)

– Max Vernon♦
15年12月16日在22:30