2016-07-07 45 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'后面看到,值应该有一个缺失的值。 –