2010-04-07 42 views
0

我在使用SQL Server中的行号进行动态分类时遇到了问题。我有它的工作,但它在非数字字段抛出错误。我需要改变以获得与Alpha工作排序?行号在文本列上排序

ID Description 
5 Test  
6 Desert 
3 A evil 

Ive得到了一个SQL Prodcedure

CREATE PROCEDURE [CRUDS].[MyTable_Search] 
    -- Add the parameters for the stored procedure here 
    -- Full Parameter List 
    @ID int = NULL,  
    @Description nvarchar(256) = NULL, 
    @StartIndex int = 0, 
    @Count int = null, 
    @Order varchar(128) = 'ID asc' 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for procedure here 
Select * from 
    (
     Select ROW_NUMBER() OVER 
      (Order By 
       case 
        when @Order = 'ID asc' then [TableName].ID 
        when @Order = 'Description asc' then [TableName].Description  
       end asc, 
       case 
        when @Order = 'ID desc' then [TableName].ID 
        when @Order = 'Description desc' then [TableName].Description 
       end desc 
      ) as row, 
      [TableName].* from [TableName] 
     where 
      (@ID IS NULL OR [TableName].ID = @ID) AND 
      (@Description IS NULL OR [TableName].Description = @Description) 
) as a 
where 
    row > @StartIndex 
    and (@Count is null or row <= @StartIndex + @Count) 
order by 
    case 
     when @Order = 'ID asc' then a.ID  
     when @Order = 'Description asc' then a.Description 
    end asc, 
    case 
     when @Order = 'ID desc' then a.ID 
     when @Order = 'Description desc' then a.Description 
    end desc 


END 
+1

边注:添加'@count是null'条件到谓词会减慢你的查询很多。您应该将该行更改为'或行<= ISNULL(@StartIndex + @Count,2147483647)'。它看起来很愚蠢,但如果桌子很大,那么它会产生很大的差异。对于那些其他'@param IS NULL'谓词也是如此,它们确实会扼杀查询性能。 – Aaronaught 2010-04-07 15:09:08

+0

你解决了这个问题吗? – 2010-04-09 11:26:39

+0

我想你不需要额外的ORDER BY,如果你的SELECT已经有了。 – 2010-04-09 11:34:42

回答

0

正常工作对我来说:

declare @TableName table (id int,Description varchar(50)) 
insert @TableName values (1,'aaa') 
insert @TableName values (2,'bbb') 
insert @TableName values (3,'ccc') 
insert @TableName values (4,'ddd') 
insert @TableName values (5,'eee') 
insert @TableName values (6,'fff') 
insert @TableName values (7,'ggg') 
insert @TableName values (8,'hhh') 
DECLARE @Order   varchar(10) 
     ,@ID   int 
     ,@Description varchar(50) 
     ,@StartIndex int 
     ,@Count   int 

SELECT @Order='Description desc' 
     ,@StartIndex=2 
     ,@Count=3 

--query unchanged, except alias to "t" and table name to "@TableName" 
Select * from 
    (
     Select ROW_NUMBER() OVER 
      (Order By 
       case 
        when @Order = 'ID asc' then t.ID 
        when @Order = 'Description asc' then t.Description  
       end asc, 
       case 
        when @Order = 'ID desc' then t.ID 
        when @Order = 'Description desc' then t.Description 
       end desc 
      ) as row, 
      t.* from @TableName t 
     where 
      (@ID IS NULL OR t.ID = @ID) AND 
      (@Description IS NULL OR t.Description = @Description) 
) as a 
where 
    row > @StartIndex 
    and (@Count is null or row <= @StartIndex + @Count) 
order by 
    case 
     when @Order = 'ID asc' then a.ID  
     when @Order = 'Description asc' then a.Description 
    end asc, 
    case 
     when @Order = 'ID desc' then a.ID 
     when @Order = 'Description desc' then a.Description 
    end desc 

输出:

row     id   Description 
-------------------- ----------- ------------- 
3     3   ccc 
4     4   ddd 
5     5   eee 

(3 row(s) affected) 

可能张贴关于你的数据的详细信息运行此和实际的错误r消息。基于OP的评论

编辑,试试这个:

declare @TableName table (id int,Description varchar(50)) 
insert @TableName values (1,'1') 
insert @TableName values (2,'bbb') 
insert @TableName values (3,'ccc') 
insert @TableName values (4,'ddd') 
insert @TableName values (5,'eee') 
insert @TableName values (6,'fff') 
insert @TableName values (7,'ggg') 
insert @TableName values (8,'hhh') 
DECLARE @Order   varchar(50) 
     ,@ID   int 
     ,@Description varchar(50) 
     ,@StartIndex int 
     ,@Count   int 

SELECT @Order='Description desc' 
     ,@StartIndex=2 
     ,@Count=3 

Select * from 
    (
     Select ROW_NUMBER() OVER 
      (Order By 
       case 
        when @Order = 'ID asc' then RIGHT(REPLICATE('0',10)+CONVERT(varchar(10),t.ID),10) 
        when @Order = 'Description asc' then t.Description  
       end asc, 
       case 
        when @Order = 'ID desc' then RIGHT(REPLICATE('0',10)+CONVERT(varchar(10),t.ID),10) 
        when @Order = 'Description desc' then t.Description 
       end desc 
      ) as row, 
      t.* from @TableName t 
     where 
      (@ID IS NULL OR t.ID = @ID) AND 
      (@Description IS NULL OR t.Description = @Description) 
) as a 
where 
    row > @StartIndex 
    and (@Count is null or row <= @StartIndex + @Count) 
order by 
    case 
     when @Order = 'ID asc' then RIGHT(REPLICATE('0',10)+CONVERT(varchar(10),a.ID),10) 
     when @Order = 'Description asc' then a.Description 
    end asc, 
    case 
     when @Order = 'ID desc' then RIGHT(REPLICATE('0',10)+CONVERT(varchar(10),a.ID),10) 
     when @Order = 'Description desc' then a.Description 
    end desc 

我基本的ID转换为使用此逻辑串:

RIGHT(REPLICATE('0',10)+CONVERT(varchar(10),ID),10) 
+0

将@Order更改为varchar(50)而不是10,10将截断排序顺序,从而跳过排序部分 – 2010-04-07 15:40:10

+0

所以基本上,我必须将所有列转换为单个数据类型(varchar)才能进行排序?我在桌上还有其他专栏,只是想确认一下。 – 2010-04-07 17:12:01

+0

我总是这样做(转换为字符串),但通常在排序时组合列以区分主列可能有重复项。例如,如果您按日期排序(没有时间),您希望包含其他列,因为可能会有相同日期的行。当你转换为字符串想想他们如何排序:数字需要前导零(或者你会得到1,10,11,2,22 ...)格式日期时间使用样式121(YYYY-MM-DD hh:mi:ss .mmm),把管道“|”或列之间的东西,垫空等。 – 2010-04-07 17:44:21