2013-05-03 2 views
1

День №3 с SQL Server.Использование CROSS APPLY для более чем одного столбца

Я пытаюсь объединить 2 столбца данных с разделителями в один вывод из функции, обозначенной таблицей. Вот мои данные:

enter image description here

Я хотел бы, чтобы данные были обработаны и помещены в таблицу в следующем формате:

enter image description here

Я в настоящее время пытается использовать этот CROSS APPLY TSQL, но я не знаю, что делаю.

USE [Metrics] 
INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues) 
SELECT d.RawKey, c.*, e.* 
FROM dbo.tblRawData d 
CROSS APPLY dbo.splitstringcomma(d.DelimitedString) c, dbo.splitstringcomma(d.DelimitedValues) e 

Мои исследования по CROSS ОТНОСИТЬСЯ имеет широкий контекст, и я не понимаю, как она должна применяться в этом случае. Нужен ли мне подзапрос с дополнительным CROSS APPLY и объединение для объединения возвратов из двух функций, связанных с таблицей?

Вот функция раскола я использовал первоначально (я не могу вспомнить автора зачислить их):

CREATE FUNCTION [dbo].[splitstring] (@stringToSplit VARCHAR(MAX), @Delimiter CHAR(1)) 
RETURNS 
@returnList TABLE ([Name] [nvarchar] (500)) 
AS 
BEGIN 

DECLARE @name NVARCHAR(255) 
DECLARE @pos INT 

WHILE CHARINDEX(@Delimiter, @stringToSplit) > 0 
BEGIN 
    SELECT @pos = CHARINDEX(@Delimiter, @stringToSplit) 
    SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1) 

    INSERT INTO @returnList 
    SELECT @name 

    SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)[email protected]) 
END 

INSERT INTO @returnList 
SELECT @stringToSplit 

RETURN 
END 

Редактировать & Пересмотренный запрос

USE [Metrics] 
INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues) 
SELECT s.RawKey, s.SplitString, v.SplitValues 
FROM (
SELECT d.RawKey, d.DelimitedString, 
c.item SplitString, c.rn 
FROM dbo.tblRawData d 
CROSS APPLY dbo.splitstring(d.DelimitedString, ',') c 
) s 

INNER JOIN 

(
SELECT d.RawKey, d.DelimitedValues, 
c.item SplitValues, c.rn 
FROM dbo.tblRawData d 
CROSS APPLY dbo.splitstring(d.DelimitedValues, ',') c 
) v 
on s.RawKey = v.RawKey 
and s.rn = v.rn; 

ответ

3

Это может быть проще чтобы ответить на это, если мы увидим вашу функцию разделения строк. Мой ответ использует версию моей функции разделения, которая у меня есть.

Я бы включил в свою функцию разделения номер строки, которую вы можете использовать для СОЗДАНИЯ разделенной строки и значений разделения.

Сплит функция:

CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))  
returns @temptable TABLE (items varchar(MAX), rn int)  
as  
begin  
    declare @idx int  
    declare @slice varchar(8000) 
    declare @rn int = 1 -- row number that increments with each value in the delimited string 

    select @idx = 1  
     if len(@String)<1 or @String is null return  

    while @idx!= 0  
    begin  
     set @idx = charindex(@Delimiter,@String)  
     if @idx!=0  
      set @slice = left(@String,@idx - 1) 
     else  
      set @slice = @String  

     if(len(@slice)>0) 
      insert into @temptable(Items, rn) values(@slice, @rn)  

     set @String = right(@String,len(@String) - @idx)  
     set @rn = @rn +1 

     if len(@String) = 0 break  
    end 
return 
end; 

Затем, если у вас есть несколько столбцов для разделения, можно использовать запрос, подобный следующему:

INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues) 
select s.rawkey, 
    s.splitstring, 
    v.splitvalues 
from 
(
    SELECT d.RawKey, d.delimitedstring, d.delimitedvalues, 
    c.items SplitString, 
    c.rn 
    FROM dbo.tblRawData d 
    CROSS APPLY dbo.Split(d.DelimitedString, ',') c 
) s 
inner join 
(
    SELECT d.RawKey, d.delimitedstring, d.delimitedvalues, 
    c.items SplitValues, 
    c.rn 
    FROM dbo.tblRawData d 
    CROSS APPLY dbo.Split(d.DelimitedValues, ',') c 
) v 
    on s.rawkey = v.rawkey 
    and s.delimitedstring = v.delimitedstring 
    and s.rn = v.rn; 

См SQL Fiddle with Demo

Это использует два подзапроса которые генерируют список значений split, тогда они объединяются с использованием номера строки, созданного функцией split.

+0

не могу сказать вам, сколько я ценю помощь - я буду видеть, если я не могу адаптировать этот код сразу :) – Shrout1

+0

Ok - Я создал простой вариант запрос просто для проверки различных возвратов функции. Кажется, он возвращает две строки; как будто он не смог выполнить последнюю итерацию функции Split ... 'USE [410_Metrics] INSERT INTO dbo.tblSplitData (SplitKey, SplitString, RowNumber) SELECT d.RawKey, c.items, c.rn FROM dbo .tblRawData d CROSS APPLY dbo.Split (d.DelimitedString, ',') c' – Shrout1

+0

@Chris Сложно сказать, так как я не вижу, что вы используете, можете ли вы редактировать скрипт sql с точным кодом и данными, которые вы используете? – Taryn

1

Поскольку вы находитесь на сервере Sql Server 2008. Вы можете сделать это без использования UDF с использованием XML.

;WITH CTE1 AS 
( 
    SELECT * 
    ,RN= Row_Number() OVER(Partition BY DelemitedString,DelimitedValues,RawKey,TableID ORDER BY TableID) 
    FROM 
    (
    SELECT * 
    ,DelimitedStringXML = CAST('<d>'+REPLACE(DelemitedString,',','</d><d>')+'</d>' AS XML) 
    ,DelimitedValueXML = CAST('<d>'+REPLACE(DelimitedValues,',','</d><d>')+'</d>' AS XML) 

    FROM dbo.tblRawData 
    ) as t 
    Cross Apply 
    (
    SELECT y.value('.', 'VARCHAR(30)') AS SplitString FROM DelimitedStringXML.nodes('//d') as x(y) 

    ) as b 
) 
,CTE2 AS 
(
    SELECT * 
    ,RN= Row_Number() OVER(Partition BY DelemitedString,DelimitedValues,RawKey,TableID ORDER BY TableID) 
    FROM 
    (
    SELECT * 
    ,DelimitedStringXML = CAST('<d>'+REPLACE(DelemitedString,',','</d><d>')+'</d>' AS XML) 
    ,DelimitedValueXML = CAST('<d>'+REPLACE(DelimitedValues,',','</d><d>')+'</d>' AS XML) 

    FROM dbo.tblRawData 
    ) as t 
    CROSS APPLY 
    (
    SELECT h.value('.', 'VARCHAR(30)') AS SplitValue FROM DelimitedValueXML.nodes('//d') as g(h) 

    ) as c 
) 


SELECT a.RawKey,a.SplitString,b.SplitValue 
FROM CTE1 as a 
INNER JOIN CTE2 as b 
    on a.TableID= b.TableID 
    AND a.RN = b.RN 

Вот SQLFiddle Demo

Смежные вопросы