SQL2005 视图排序问题

wgale025 2009-02-24 08:40:04
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
...全文
1528 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Liu_qingwei 2012-09-24
  • 打赏
  • 举报
回复
99.99percent还是有0.01的会没有的,如果确定返回行在10000条以下,可以用TOP 10000 或更大的值都可以
  • 打赏
  • 举报
回复
我一直为这个苦恼 谢谢大神指点
kooddoo 2011-01-19
  • 打赏
  • 举报
回复
do熊的有一点点小问题用
select * from sysobjects
可以发现,EXITS还是要分类型的。
U是表,V才是视图
if exists(select * from sysobjects where name='vw_user' and type='V')
99.99percent是否有效待高手来测
Dylan-du 2010-07-22
  • 打赏
  • 举报
回复
do熊说的不错,顶你!
drc606 2010-07-07
  • 打赏
  • 举报
回复
记录下,很有用
Liyingyue_FFS 2009-02-24
  • 打赏
  • 举报
回复
顶大牛
zjcxc 2009-02-24
  • 打赏
  • 举报
回复
查询的时候, 会根据你的查询语句重新定义执行计划, 所以在视图中定义 ORDER BY 并不能保证输出结果的顺序

sql server 的设计是如此的, 所以无解
lzfrab 2009-02-24
  • 打赏
  • 举报
回复
学习了...
liangCK 2009-02-24
  • 打赏
  • 举报
回复
这是SQL Server 2005联机丛书的原话:

ORDER BY 子句仅用于确定视图定义中的 TOP 子句返回的行。ORDER BY 不保证在查询视图时得到有序结果,除非在查询本身中也指定了 ORDER BY。
claro 2009-02-24
  • 打赏
  • 举报
回复
帮顶
等。
dobear_0922 2009-02-24
  • 打赏
  • 举报
回复
把TOP 100改成TOP 99,你会发现,视图中的order by还是有作用的:
if exists(select * from sysobjects where name='vw_user') 
drop view vw_user
GO
--创建视图
CREATE view vw_user
as
select top 99 percent 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc
go
go
--分别从视图和表中查询数据
select * from vw_user--查出来的顺序和我的排序这段排序的不一样。郁闷了。出什么问题了,求教。
select * from users

/*
姓名 等级 积分
-------------------------------------------------- ----------- -----------
李明 2 2200
何大 2 2100
张五 1 1890
赵七 1 1670

(4 行受影响)

id name grade point
----------- -------------------------------------------------- ----------- -----------
1 何大 2 2100
2 李明 2 2200
3 张五 1 1890
4 赵七 1 1670

(4 行受影响)
*/
等不到来世 2009-02-24
  • 打赏
  • 举报
回复
sql2005中,同时使用top 100 percent和order by时,将不会对视图中的数据排序。

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

如果你使用top 90 percent和order by,就能排序。它的含义是按order by的顺序返回90%的行。
也就是说,视图它更关注于返回哪些行,而不是按什么顺序。
所以还是在视图外指定顺序比较地道一点。
dobear_0922 2009-02-24
  • 打赏
  • 举报
回复
在SQL2005中,
select TOP 100 percent * from tb 
---->相当于
select * from tb


这个可以看查询计划:
set showplan_all on
go

select top 100 percent 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc

select 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc

go
set showplan_all off

/*
StmtText
---------------------------------------------------------------------------------------------------

select top 100 percent 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc 1 1 0 NULL
|--Sort(ORDER BY:([test].[dbo].[users].[grade] DESC, [test].[dbo].[users].[point] DESC))
|--Clustered Index Scan(OBJECT:([test].[dbo].[users].[PK__users__705EA0EB]))

select 姓名=name,等级=grade,积分=point
from users order by grade desc,point desc 2 4 0
|--Sort(ORDER BY:([test].[dbo].[users].[grade] DESC, [test].[dbo].[users].[point] DESC))
|--Clustered Index Scan(OBJECT:([test].[dbo].[users].[PK__users__705EA0EB]))

(6 行受影响)

*/
wgale025 2009-02-24
  • 打赏
  • 举报
回复
EXPAND VIEWS 怎么用呢?帮助里面怎么没有到如何使用,是一个设置开关吗?还是SQL语句中使用。连个代码示例也没有。我知道我的视图查出来的结果为什么没有按我想要的顺序排序。
原因是:我的基表上建了一个主键,建主键的话,会自动创建主建索引,但他又属于聚集索引。聚集索引会进默认进行排序,而我的查询视图的时候刚好是通过主键索引的排序方式输出的结果。
所以我郁闷。
为什么会不按我的排序字段来排序。
wgale025 2009-02-24
  • 打赏
  • 举报
回复
我来发贴子就是想搞清楚原因,要是不想搞清楚原因,我干麻来发个贴呢。在查询的时候排序,这个谁都想得到,但是为什么我在创建视图的时候排序了,但查出来的结果却没有排序。这才是我想要搞清楚的问题。解决方案我有。但不是你这种的。
dawugui 2009-02-24
  • 打赏
  • 举报
回复
你看看下面的东西对你是否有用?
解析视图上的索引
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。



视图索引
Microsoft® SQL Server™ 2000 支持在视图上定义索引。视图有时也称为虚拟表,这是由于视图返回的结果集与包含行和列的表具有相同的常规格式,并且在 SQL 语句中可以相同的方式引用视图和表。非索引视图的结果集不永久存储在数据库中。每当查询引用视图时,SQL Server 便动态地将生成视图结果集所需的逻辑合并到由基表中的数据生成完整的查询结果集所需的逻辑中。生成视图结果的过程称为视图具体化。有关更多信息,请参见视图解析。

对于涉及对大量的行进行复杂处理的非索引视图,为引用视图的每个查询动态生成结果集的开销会很大。这类视图包括聚集大量数据或联接许多行的视图。若经常在查询中引用这类视图,可通过在视图上创建唯一聚集索引来提高性能。在视图上创建唯一聚集索引时将执行该视图,并且结果集在数据库中的存储方式与带聚集索引的表的存储方式相同。有关用于存储聚集索引的结构的更多信息,请参见聚集索引。

在视图上创建索引的另一个好处是:查询优化器开始在查询中使用视图索引,而不是直接在 FROM 子句中命令视图。这样一来,可从索引视图检索数据而无需重新编码,由此带来的高效率也使现有查询获益。

在视图上创建聚集索引可存储创建索引时生成的结果集。索引视图还自动反映自创建索引后对基表数据所做的更改,这一点与在基表上创建的索引相同。当对基表中的数据进行更改时,索引视图中存储的数据也反映数据更改。视图的聚集索引必须唯一,从而提高了 SQL Server 在索引中查找受任何数据更改影响的行的效率。

必须设置特定的 SET 选项后才能在视图上创建索引。只有当执行语句的连接具有相同的选项设置时,查询优化器才考虑对后续 SQL 语句使用索引。有关更多信息,请参见影响结果的 SET 选项。

与基表上的索引相比,对索引视图的维护可能更复杂。只有当提高的视图结果检索速度超过了修改所需的开销时,才应在视图上创建索引。这样的视图通常包括映射在相对静态的数据上、处理多行以及由许多查询引用的视图。

在视图上创建的第一个索引必须是唯一聚集索引。在创建唯一聚集索引后,可创建其它非聚集索引。视图上的索引命名规则与表上的索引命名规则相同。唯一区别是表名由视图名替换。

若除去视图,视图上的所有索引也将被除去。若除去聚集索引,视图上的所有非聚集索引也将被除去。可分别除去非聚集索引。除去视图上的聚集索引将删除存储的结果集,并且优化器将重新像处理标准视图那样处理视图。

尽管 CREATE UNIQUE CLUSTERED INDEX 语句仅指定组成聚集索引键的列,但视图的完整结果集将存储在数据库中。与基表上的聚集索引一样,聚集索引的 B 树结构仅包含键列,但数据行包含视图结果集中的所有列。

dawugui 2009-02-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wgale025 的回复:]
我不想在查视图的时候重新排序。
我在创建视图的时候已经排过序了。
[/Quote]
有些事情不是你想不想的问题,解决问题才是最好的.友情帮顶.
wgale025 2009-02-24
  • 打赏
  • 举报
回复
我不想在查视图的时候重新排序。
我在创建视图的时候已经排过序了。
dawugui 2009-02-24
  • 打赏
  • 举报
回复
CREATE view vw_user
as
select top 100 percent 姓名=name,等级=grade,积分=point from users order by grade desc,point desc
go

select * from vw_user order by grade desc,point desc
dawugui 2009-02-24
  • 打赏
  • 举报
回复
select * from vw_user order by ...
加载更多回复(1)

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧