none
【求教】一个order by+charindex然后累加的问题 RRS feed

  • 问题

  • declare @T table (ID int,N varchar(10))
    insert into @T
    select 1,'A' union all
    select 2,'B' union all
    select 3,'C' union all
    select 4,'D'
    
    --这样是可以累加的
    declare @sql varchar(10) 
    select @sql=isnull(@sql,'')+N from @T 
    select @sql as col
    /*
    col
    ----------
    ABCD
    */
    
    --这样是可以排序后累加的
    declare @sql1 varchar(10) 
    select @sql1=isnull(@sql1,'')+N from @T order by ID desc
    select @sql1 as col1
    /*
    col1
    ----------
    DCBA
    */
    
    --这样是可以排序的
    declare @s varchar(10) set @s='3124'
    select N from @T order by charindex(ltrim(ID),@s)
    /*
    N
    ----------
    C
    A
    B
    D
    */
    
    --这个的结果为什么不是CABD?
    declare @sql2 varchar(100) 
    select @sql2=isnull(@sql2,'')+N from @T order by charindex(ltrim(ID),@s)
    select @sql2 as col2
    
    /*
    col2
    ------------
    D
    */


    2012年6月4日 14:31
    版主

答案


  • select @sql1=isnull(@sql1,'')+N from @T order by ID desc
      |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(varchar(10),isnull([@sql1],'')+[N],0)))
           |--Sort(ORDER BY:([ID] DESC))
                |--Table Scan(OBJECT:(@T))

    select @sql2=isnull(@sql2,'')+N from @T order by charindex(ltrim(ID),@s)
      |--Sort(ORDER BY:([Expr1005] ASC))
           |--Compute Scalar(DEFINE:([Expr1005]=charindex(ltrim(CONVERT_IMPLICIT(varchar(12),[ID],0)),[@s]), [Expr1006]=CONVERT_IMPLICIT(varchar(100),isnull([@sql2],'')+[N],0)))
                |--Table Scan(OBJECT:(@T))

    从这个可以看到,可以得到期望结果的,是先排序,然后对排序的结果集对变量赋值

    不能得到想要的结果的那个,是在排序前,先针对每条记录计算出了排序的表达式和赋值表达式的值,排序后,再把已经计算好的结果赋给变量,所以最终只会得到一条记录的值,而不会累加

    2012年6月5日 1:27
  • declare @T table (ID int,N varchar(10))
    insert into @T
    select 1,'A' union all
    select 2,'B' union all
    select 3,'C' union all
    select 4,'D'
    
    declare @sql2 varchar(100) 
    ;with maco as
    (
    select ID,N,charindex(ltrim(ID),'3124') as c1 from @T
    )
    select @sql2=isnull(@sql2,'')+N from maco order by c1 --order by N 和order by c1 竟然效果不同
    select @sql2 as col2
    
    declare @sql3 varchar(100)
    select ID,N,charindex(ltrim(ID),'3124') as c1 into #t from @T
    select @sql3=isnull(@sql3,'')+N from #t order by c1 
    select @sql3 as col3
    drop table #t
    
    /*
    col2
    ------------------------------
    D
    
    col3
    ------------------------------
    CABD
    */
    
    --用cte公用表表达式也不行,插入临时表里可以,我都晕了....



    2012年6月5日 1:52
    版主

全部回复

  • set statistics profile on
    go
    declare @T table (ID int,N varchar(10))
    insert into @T
    select 1,'A' union all
    select 2,'B' union all
    select 3,'C' union all
    select 4,'D'
    
    --这样是可以排序后累加的
    declare @sql1 varchar(10) 
    select @sql1=isnull(@sql1,'')+N from @T order by ID desc
    select @sql1 as col1
    
    --这个的结果为什么不是CABD?
    declare @s varchar(10) set @s='3124'
    declare @sql2 varchar(100) 
    select @sql2=isnull(@sql2,'')+N from @T order by charindex(ltrim(ID),@s)
    select @sql2 as col2
    
    /*
    col2
    ------------
    D
    */
    

    2012年6月5日 1:23

  • select @sql1=isnull(@sql1,'')+N from @T order by ID desc
      |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(varchar(10),isnull([@sql1],'')+[N],0)))
           |--Sort(ORDER BY:([ID] DESC))
                |--Table Scan(OBJECT:(@T))

    select @sql2=isnull(@sql2,'')+N from @T order by charindex(ltrim(ID),@s)
      |--Sort(ORDER BY:([Expr1005] ASC))
           |--Compute Scalar(DEFINE:([Expr1005]=charindex(ltrim(CONVERT_IMPLICIT(varchar(12),[ID],0)),[@s]), [Expr1006]=CONVERT_IMPLICIT(varchar(100),isnull([@sql2],'')+[N],0)))
                |--Table Scan(OBJECT:(@T))

    从这个可以看到,可以得到期望结果的,是先排序,然后对排序的结果集对变量赋值

    不能得到想要的结果的那个,是在排序前,先针对每条记录计算出了排序的表达式和赋值表达式的值,排序后,再把已经计算好的结果赋给变量,所以最终只会得到一条记录的值,而不会累加

    2012年6月5日 1:27
  • 谢谢邹老大的回复!

    为什么执行顺序不一样?不好理解呀,如果我要用charindex排序后再累加应该如何实现呢?

    2012年6月5日 1:41
    版主
  • declare @T table (ID int,N varchar(10))
    insert into @T
    select 1,'A' union all
    select 2,'B' union all
    select 3,'C' union all
    select 4,'D'
    
    declare @sql2 varchar(100) 
    ;with maco as
    (
    select ID,N,charindex(ltrim(ID),'3124') as c1 from @T
    )
    select @sql2=isnull(@sql2,'')+N from maco order by c1 --order by N 和order by c1 竟然效果不同
    select @sql2 as col2
    
    declare @sql3 varchar(100)
    select ID,N,charindex(ltrim(ID),'3124') as c1 into #t from @T
    select @sql3=isnull(@sql3,'')+N from #t order by c1 
    select @sql3 as col3
    drop table #t
    
    /*
    col2
    ------------------------------
    D
    
    col3
    ------------------------------
    CABD
    */
    
    --用cte公用表表达式也不行,插入临时表里可以,我都晕了....



    2012年6月5日 1:52
    版主