none
奇怪问题Order By后,数据不正确? RRS feed

  • 问题

  • declare @table table(UserId int,GroupId int)
    insert @table select 1,2 union all select 1,3 union select 2,1
    
    declare @str1 nvarchar(4000)
    select @str1='没有添加order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    (
     select Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) from @table
    )t
    select @str1--查询结果是:没有添加order by,3,2,1
    
    select @str1='添加了order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    (
     select Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) from @table
    )t
    order by Agg desc
    select @str1--查询结果是:添加了order by,1
    
    
    --奇怪问题Order By后,数据不正确?我想将数据排序后串在一起,有何办法?
    2009年12月17日 18:30

答案

  • declare @table table(UserId int,GroupId int)
    insert @table select 1,2 union all select 1,3 union select 2,1
    select * from @table
     select Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) into #temp from @table
     create index idx_temp on #temp(agg desc)
    
    
    declare @str1 nvarchar(4000)
    select @str1='没有添加order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    #temp t
    select @str1
    
    select @str1='添加了order by'
      drop index idx_temp on #temp
      create index idx_temp on #temp(agg)
    
     
    select @str1=@str1+','+cast(Agg as varchar)
    from
    #temp t
    
    select @str1
    
    drop table #temp
    
    


    hello
    • 已标记为答案 SQL STUDIO 2009年12月18日 12:01
    2009年12月18日 3:03

全部回复

  • declare @table table(UserId int,GroupId int)
    insert @table select 1,2 union all select 1,3 union select 2,1
    select * from @table
     select Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) into #temp from @table
     create index idx_temp on #temp(agg desc)
    
    
    declare @str1 nvarchar(4000)
    select @str1='没有添加order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    #temp t
    select @str1
    
    select @str1='添加了order by'
      drop index idx_temp on #temp
      create index idx_temp on #temp(agg)
    
     
    select @str1=@str1+','+cast(Agg as varchar)
    from
    #temp t
    
    select @str1
    
    drop table #temp
    
    


    hello
    • 已标记为答案 SQL STUDIO 2009年12月18日 12:01
    2009年12月18日 3:03
  • 你说得对,这个我也试过,不过我不想有表变量或者临时表(效率可能变差)。

    2009年12月18日 3:10
  • select @str1='添加了order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    (
     select top 100 percent
    	Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) from @table
    order by Agg desc
    )t
    
    select @str1--查询结果是:添加了order by,3,2,1
    
    2009年12月18日 4:20
  • 这个问题似乎在2005及之后的版本出现得比较频繁, 严格来说, 应该算是查询优化器的 BUG
    2009年12月18日 4:21
  • select @str1='添加了order by'
    select @str1=@str1+','+cast(Agg as varchar)
    from
    (
     select top 100 percent
    	Agg=sum(UserId) over()-sum(GroupId) over(partition by GroupId) from @table
    order by Agg desc
    )t
    select @str1--查询结果是:添加了order by,3,2,1
    

    desc或asc结果都是一样(order by,3,2,1),order by没有起作用
    2009年12月18日 7:04
  • 这个行为是这样的。

    根据MSDN(http://technet.microsoft.com/zh-cn/library/ms187330(SQL.90).aspx), SELECT @local_variable 通常用于将单个值返回到变量中。但是,如果 expression 是列的名称,则可返回多个值。如果 SELECT 语句返回多个值,则将返回的最后一个值赋给变量。

    那么对于select @local_variable = @local_variable + expression的用法,其结果应该是什么呢?有两种:
    (1) SQL Server遍历了subquery结果集的每一行,那么结果就是楼主希望的结果,因为@local_variable导致了迭代。
    (2) SQL Server可以定位到subquery的最后一行,那么结果就是楼主觉得疑惑的地方,因为相当于这个表达式只是最最后一行执行了一次。

    更详细参考下面的文章,就不多写了。
    一个SELECT语句引发的迭代(SELECT @local_variable = expression 的妙用)http://www.cnblogs.com/leadzen/archive/2008/02/12/1067469.html

    2009年12月19日 18:05