2010-04-07 25 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