SQL Server的第3天。
我正在尝试将2列分隔数据合并到表值函数的一个输出中。这是我的数据:
我希望以下列格式处理数据并将其放入表中:
我目前尝试使用此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 APPLY的研究有广泛的背景,我不明白它应该如何应用于这种情况。我是否需要带有附加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)-@pos)
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;
答案 0 :(得分:3)
如果我们能看到你的分裂字符串函数,可能会更容易回答这个问题。我的答案是使用我的分割功能版本。
我会在您的split函数中包含一个行号,您可以使用该行号来加入拆分字符串和拆分值。
分割功能:
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;
这使用两个子查询生成拆分值列表,然后使用拆分函数创建的行号连接它们。
答案 1 :(得分:1)
由于您使用的是Sql Server 2008.您可以在没有使用XML的UDF的情况下执行此操作。
;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