如何在sql中索引我的行?

时间:2016-07-07 15:57:55

标签: sql sql-server-2008 tsql

我有以下功能:

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的行中的double值以及名为{的行中的int值{1}},问题是在我的字符串中我总是Value但有时Name and Measure丢失了,我想在该空格中放置一个NULL值。

所以在我的例子中我应该有像

这样的东西
Value

相反,我有:

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

1 个答案:

答案 0 :(得分: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
    )
. . .