2016-07-07 26 views
0

我有以下功能:如何在sql中索引我的行?

CREATE FUNCTION dbo.SplitStrings_XML 
(
    @List  NVARCHAR(MAX), 
    @Delimiter NVARCHAR(255) 
) 
RETURNS TABLE 
WITH SCHEMABINDING 
AS 
    RETURN 
    ( 
     SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)') 
     FROM 
     ( 
     SELECT x = CONVERT(XML, '<i>' 
      + REPLACE(@List, @Delimiter, '</i><i>') 
      + '</i>').query('.') 
    ) AS a CROSS APPLY x.nodes('i') AS y(i) 
    ); 
GO 

和下面的代碼:

declare @string nvarchar(max) = 'aaa,1.3,1,bbb,1.5,ccc,2.0,1' 
;WITH AllItems as 
(
    SELECT Item, ROW_NUMBER() OVER(ORDER BY (select null)) as rn 
    FROM dbo.SplitStrings_XML(@string, ',') 
) 
, Strings as 
(
    SELECT Item as Name, ROW_NUMBER() OVER(ORDER BY (select null)) as rn 
    FROM dbo.SplitStrings_XML(@string, ',') 
    WHERE ISNUMERIC(Item) = 0 
), Doubles as 
( 
    SELECT Item as Measure, ROW_NUMBER() OVER(ORDER BY (select null)) as rn 
    FROM dbo.SplitStrings_XML(@string, ',') 
    WHERE ISNUMERIC(Item) = 1 AND CHARINDEX('.', Item) > 0 
), Integers as 
(
    SELECT Item as Value, ROW_NUMBER() OVER(ORDER BY (select null)) as rn 
    FROM dbo.SplitStrings_XML(@string, ',') 
    WHERE ISNUMERIC(Item) = 1 AND CHARINDEX('.', Item) = 0 
) 

SELECT Name, Measure, Value 
FROM AllItems A 
LEFT JOIN Strings S ON A.rn = S.rn 
LEFT JOIN Doubles D ON A.rn = D.rn 
LEFT JOIN Integers I ON A.rn = I.rn 
WHERE COALESCE(Name, Measure, Value) IS NOT NULL 

在這段代碼中,我們得到了一個@string = 'aaa,1.3,1,bbb,1.5,ccc,2.0,1',返回字符在名爲Name行,在返回的雙重價值行命名Measure並在名爲Value行中的int值,問題是,在我的字符串我一直一個Name and Measure但有時Value失蹤,我想向一個NULL值在該空間。所以在我的例子

我shouldhave像

Name  Measure Value 
---------+--------+------- 
aaa  1.3  1 
bbb  1.5  NULL 
ccc  2.0  1 

相反,我有:

Name  Measure Value 
---------+--------+------- 
aaa  1.3  1 
bbb  1.5  1 
ccc  2.0  NULL 

回答

2

首先,我建議您修改返回的項目數的函數。但是,這不是必要的,因爲你的row_number()這樣做。

然後,我假設「缺失值」的意思是「,,」。

如果是的話,我會建議定義的CTE爲:

WITH AllItems as (
     SELECT Item, ROW_NUMBER() OVER (ORDER BY (select null)) as rn 
     FROM dbo.SplitStrings_XML(@string, ',') 
    ), 
    Strings as (
     SELECT Item as Name, ROW_NUMBER() OVER (ORDER BY (select null)) as rn 
     FROM AllItems ai 
     WHERE ai.rn % 3 = 1 
    ), 
    Doubles as ( 
     SELECT Item as Measure, ROW_NUMBER() OVER (ORDER BY (select null)) as rn 
     FROM AllItems ai 
     WHERE ai.rn % 3 = 2 
    ), 
    Integers as (
     SELECT Item as Value, ROW_NUMBER() OVER(ORDER BY (select null)) as rn 
     FROM AllItems ai 
     WHERE ai.rn % 3 = 0 
    ) 
. . . 
+0

,如果你不介意我問這個,你知道我應該怎麼比如做可以說我們得到了'字符串= 'aaa,2,1'這2個仍然是一個度量值,它會將其視爲一個值,我應該如何處理這個問題? –

+0

@JohnPietrar。 。 。我不認爲字符串中的值是一個好主意。有許多方法可以在字符串中編碼數據,例如XML和JSON。修復寫入值的代碼,使其明確無誤。 –

+0

一個問題是,這樣它找到空值,其餘的表是隨機的,所以在我給出的例子中@string ='aaa,1.3,1,bbb,1.5,ccc,2.0,1'it會做'Name = aaa | bbb | 2.0;度量= 1.3 | 1.5 | 1;值= 1 | ccc | NULL',而它應該是'Name = aaa | bbb | ccc; Measure = 1.3 | 1.5 | 2.0;值= 1 | NULL | 1',這是因爲缺少的值不是',,',它只是不存在,因爲你可以在'bbb,1.5'後面看到,值應該有一個缺失的值。 –