日期:2014-05-17  浏览次数:20493 次

SQL2005 视图排序问题
if exists(select * from sysobjects where name='users')
drop table users
go
create table users
(
id int identity primary key,
name varchar(50),
grade int,
point int
)
--创建表
GO
--向表中添加数据
insert into users(name,grade,point)
select '李明',2,2200 union
select '张五',1,1890 union
select '赵七',1,1670 union
select '何大',2,2100

我有一张这样的表,在这张表的基础上要建一个视图,
--创建视图
if exists(select * from sysobjects where name='vw_user')
drop view vw_user
GO
--创建视图
CREATE view vw_user
as
select top 100 percent 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc
go
go
--分别从视图和表中查询数据
select * from vw_user--查出来的顺序和我的排序这段排序的不一样。郁闷了。出什么问题了,求教。
select * from users

------解决方案--------------------
你看看下面的东西对你是否有用?
SQL code
解析视图上的索引
Microsoft® SQL Server? 2000 查询优化器确定给定查询是否能从使用数据库中定义的任何索引中获益。索引包括索引视图和基表索引。当满足下列条件时,SQL Server 查询优化器使用索引视图: 

下列会话选项均设置为 ON: 
ANSI_NULLS


ANSI_PADDING


ANSI_WARNINGS


ARITHABORT


CONCAT_NULL_YIELDS_NULL


QUOTED_IDENTIFIERS 
NUMERIC_ROUNDABORT 会话选项设置为 OFF。


查询优化器查找视图索引列与查询中的元素之间的匹配部分,如: 
WHERE 子句中的搜索条件谓词。


联接操作。


聚合函数。 
估计的索引使用成本是查询优化器考虑使用的所有访问机制中的最低成本。 
除 SET 选项的要求外,查询优化器使用上述规则确定表索引是否包含查询。查询中无须再指定其它选项以使用索引视图。

查询不必在 FROM 子句中显式引用索引视图,查询优化器即可使用该索引视图。如果查询所引用的基表中的列也同时存在于索引视图中,并且,查询优化器估计使用索引视图将提供最低成本的访问机制,则查询优化器会选择索引视图,其方式类似于当查询中不直接引用基表索引时选择基表索引。当视图中包含非查询所引用的列时,只要视图提供覆盖一个或多个查询所指定列的最低成本选项,查询优化器即可能选择该视图。

使用 EXPAND VIEWS 选项可防止使用视图索引进行查询。可使用 NOEXPAND 视图提示强制优化器使用在 FROM 子句中指定的索引视图上的索引。不过,建议让查询优化器动态地决定各查询使用的最佳访问方法。只在经测试证实 EXPAND 和 NOEXPAND 可显著提高性能的特定情形中使用它们。

EXPAND VIEWS 选项指定对于整个查询,查询优化器不应使用任何视图索引。 

查询优化器不使用任何索引视图,除非在 FROM 子句中指定了视图。当查询优化器评估覆盖查询中所引用列的低成本方法时,它将忽略所有视图索引。


查询优化器将 FROM 子句中引用的索引视图视为标准视图。查询优化器将视图的逻辑纳入查询执行计划中,并从基表中动态生成结果集。查询优化器忽略在视图上定义的索引。 
当指定视图为 NOEXPAND 时,查询优化器将考虑使用视图上定义的任何索引。通过在可选的 INDEX() 子句中指定 NOEXPAND,可强制查询优化器使用指定索引。只能为索引视图指定 NOEXPAND,而不能为还未建立索引的视图指定 NOEXPAND。

------解决方案--------------------
在SQL2005中,
SQL code
select TOP 100 percent * from tb 
---->相当于
select * from tb

------解决方案--------------------
sql2005中,同时使用top 100 percent和order by时,将不会对视图中的数据排序。

因为系统认为你这样的排序没有实用价值。(一般视图里是不排序的)

如果你使用top 90 percent和order by,就能排序。它的含义是按order by的顺序返回90%的行。
也就是说,视图它更关注于返回哪些行,而不是按什么顺序。
所以还是在视图外指定顺序比较地道一点。
------解决方案--------------------
这是SQL Server 2005联机丛书的原话:

ORDER BY 子句仅用于确定视图定义中的 TOP 子句返回的行。ORDER BY 不保证在查询视图时得到有序结果,除非在查询本身中也指定了 ORDER BY。
------解决方案--------------------
查询的时候, 会根据你的查询语句重新定义执行计划, 所以在视图中定义 ORDER BY 并不能保证输出结果的顺序

sql server 的设计是如此的, 所以无解