2016-07-07 3 views
0

私は、次の機能があります、私たちはNameという名前の行の文字を返します@string = 'aaa,1.3,1,bbb,1.5,ccc,2.0,1'を得た。このコードではSQLで行をインデックスする方法は?

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 

でdouble型の値を返します。

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 

し、次のコード行の名前はMeasureで、行のint値はValueです。問題は文字列には常にName and Measureがありますが、時にはValueがなくなってしまい、その領域にNULL値を配置したいと考えています。

は、だから私の例では、私が代わりに私が持っている

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

のようなものをshouldhave:

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

問題は、この方法ではnull値を見つけ、テーブルの残りの部分はランダムなので、私の '@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 | 'Name = aaa | 'でなければなりません。 bbb | ccc;測定値= 1.3 | 1.5 | 2.0;値= 1 | NULL | 1 'であり、欠落した値は ',,'ではないので、 'bbb、1.5'の後に見ることができるように、存在しない値があるはずです。 –

関連する問題