2013-03-08 24 views
-1

的第n次數來獲得子在SQLSEVER我有一個varcharSQL Server 2008中如何通過查找字符

colName_vch = 'field1;field2;field3;field4;field5;field6;field7'

我想要的字段4值。

現在一個很長的路是對遞歸;SUBSTRING做使用RIGHTCHARINDEX,但變得非常複雜,並增加查詢時間。

是否有任何其他快速/不太複雜的方式來實現這一目標?

我知道這是一個糟糕的數據庫設計,但我堅持了一段時間了。

任何幫助表示讚賞!

+0

你想'field4',因爲它是第4項物理在列表中,而不是因爲它是按字母順序排列第四,對不對? – 2013-03-08 13:05:18

+0

是,列表中的第四個項目 – 2013-03-08 13:26:21

回答

1

我不知道如果我真正理解你的問題,但這裏是我的猜測:

你可以寫一個自定義的Split功能,通過一個分隔符分割(在這種情況下;)。然後,您可以使用ROW_NUMBER來獲得具有給定索引的期望部分(此處爲4)。

例如:

DECLARE @string VARCHAR(100); 
SET @string='field1;field2;field3;field4;field5;field6;field7'; 
DECLARE @index INT; 
SET @index = 4; 

WITH cte 
    AS (SELECT item, 
       rn=Row_number() 
        OVER( 
         ORDER BY item) 
     FROM dbo.Split(@string, ';')) 
SELECT TOP 1 item 
FROM cte 
WHERE rn = @index 

上。這裏SQL-撥弄一個DEMO

這是我的分裂功能:

CREATE FUNCTION [dbo].[Split] 
(
    @ItemList NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @IDTable TABLE (Item VARCHAR(50)) 
AS  

BEGIN  
    DECLARE @tempItemList NVARCHAR(MAX) 
    SET @tempItemList = @ItemList 

    DECLARE @i INT  
    DECLARE @Item NVARCHAR(4000) 

    SET @tempItemList = REPLACE (@tempItemList, ' ', '') 
    SET @i = CHARINDEX(@delimiter, @tempItemList) 

    WHILE (LEN(@tempItemList) > 0) 
    BEGIN 
     IF @i = 0 
      SET @Item = @tempItemList 
     ELSE 
      SET @Item = LEFT(@tempItemList, @i - 1) 
     INSERT INTO @IDTable(Item) VALUES(@Item) 
     IF @i = 0 
      SET @tempItemList = '' 
     ELSE 
      SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i) 
     SET @i = CHARINDEX(@delimiter, @tempItemList) 
    END 
    RETURN 
END 
+1

但是,使用'ORDER BY Item'來確定行號將按字母順序選擇第4個項目。在這種情況下,它恰好*發生*是物品*中的第4項也是第4 *個字母*。 – 2013-03-08 12:56:06

+0

@AaronBertrand:也許這是OP實際想要的。但是,其實我已經注意到這個問題。但由於我不知道如何訂購一個不可用的索引,我問過這個問題:http://stackoverflow.com/questions/15294610/order-by-index-possible您誠摯的邀請回答:) – 2013-03-08 13:03:05

0
CREATE FUNCTION dbo.SplitStrings 
(
    @List  NVARCHAR(MAX), 
    @Delimiter NVARCHAR(255) 
) 
RETURNS @t TABLE([Index] INT IDENTITY(1,1), Item NVARCHAR(255)) 
AS 
BEGIN 
    INSERT @t(Item) SELECT SUBSTRING(@List, Number, 
     CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number) 
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) 
     FROM sys.all_objects) AS n(Number) 
    WHERE Number <= CONVERT(INT, LEN(@List)) 
     AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter 
    ORDER BY Number OPTION (MAXDOP 1); 

    RETURN; 
END 
GO 

DECLARE @x TABLE(i INT, string NVARCHAR(4000)); 

INSERT @x SELECT 1, N'field1;field2;field3;field4;field5;' 
UNION ALL SELECT 2, N'x;y;6;r;3;2;w;' 
UNION ALL SELECT 3, N'ttt;444;rrr;333;111;444;777;888;'; 

SELECT x.i, s1.Item 
FROM @x AS x 
CROSS APPLY dbo.SplitStrings(x.string, ';') AS s1 
WHERE s1.[Index] = 4; 
相關問題