将多个分隔值拆分为多行
Splitting multiple delimited values into multiple rows
我一直在 Whosebug 中寻找解决方案,但没有找到任何有用的东西。我遇到了一个问题,希望有人愿意帮助我。
我有这样的价值:
Create table DemoRecords
(
CustID int identity (1,1),
CustomerName varchar(50),
CurrencyCode varchar(50),
CurrentBalance varchar(50),
DateValue varchar(50)
)
GO
INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBP','10500ý2500ý1050','20150101ý20150201ý20150301')
..我需要这样的输出:(请看下面的图片)
Picture
请不要建议我使用 CTE,因为其中有超过 100 列 table。
这是一个将字符串拆分成行的函数。下面是针对您的 demorecords table 的查询,它使用该函数来获取请求的结果。
create function dbo.split
(
@delimited nvarchar(max),
@delimiter nvarchar(5)
)
returns @rows table
(
rownumber int not null identity(1,1),
value nvarchar(max) not null
)
as
begin
if @delimited is null return
declare @delr_len int = len(@delimiter)
declare @start_at int = 1
declare @end_at int
declare @deld_len int
while 1=1
begin
set @end_at = charindex(@delimiter,@delimited,@start_at)
set @deld_len = case @end_at when 0 then len(@delimited) else @end_at-@start_at end
insert into @rows (value) values( substring(@delimited,@start_at,@deld_len) );
if @end_at = 0 break;
set @start_at = @end_at + @delr_len
end
return
end
go
select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value
from demorecords r
cross apply (select rownumber, value from dbo.split(r.currencycode,'ý') ) currencycode
cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber ) currentbalance
cross apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber ) datevalue
如果您有一列可能包含缺失值,请使用外部应用而不是内部应用来连接该列的函数结果。在以下示例中,DateValue 列缺少值 3 和值 4。
INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBPýEUR','10500ý2500ý1050ý','ý')
select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value
from demorecords r
cross apply (select rownumber, value from dbo.split(r.currencycode,'ý') ) currencycode
cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber ) currentbalance
outer apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber ) datevalue
或者,您可以清理您的输入以不丢失值。在上面的例子中,我希望 DateValue 是 'ýý' 而不是 'ý'。如果您的情况允许,您可能更愿意查找并修复这些问题,而不是使用外部联接。
我一直在 Whosebug 中寻找解决方案,但没有找到任何有用的东西。我遇到了一个问题,希望有人愿意帮助我。
我有这样的价值:
Create table DemoRecords
(
CustID int identity (1,1),
CustomerName varchar(50),
CurrencyCode varchar(50),
CurrentBalance varchar(50),
DateValue varchar(50)
)
GO
INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBP','10500ý2500ý1050','20150101ý20150201ý20150301')
..我需要这样的输出:(请看下面的图片)
请不要建议我使用 CTE,因为其中有超过 100 列 table。
这是一个将字符串拆分成行的函数。下面是针对您的 demorecords table 的查询,它使用该函数来获取请求的结果。
create function dbo.split
(
@delimited nvarchar(max),
@delimiter nvarchar(5)
)
returns @rows table
(
rownumber int not null identity(1,1),
value nvarchar(max) not null
)
as
begin
if @delimited is null return
declare @delr_len int = len(@delimiter)
declare @start_at int = 1
declare @end_at int
declare @deld_len int
while 1=1
begin
set @end_at = charindex(@delimiter,@delimited,@start_at)
set @deld_len = case @end_at when 0 then len(@delimited) else @end_at-@start_at end
insert into @rows (value) values( substring(@delimited,@start_at,@deld_len) );
if @end_at = 0 break;
set @start_at = @end_at + @delr_len
end
return
end
go
select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value
from demorecords r
cross apply (select rownumber, value from dbo.split(r.currencycode,'ý') ) currencycode
cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber ) currentbalance
cross apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber ) datevalue
如果您有一列可能包含缺失值,请使用外部应用而不是内部应用来连接该列的函数结果。在以下示例中,DateValue 列缺少值 3 和值 4。
INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBPýEUR','10500ý2500ý1050ý','ý')
select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value
from demorecords r
cross apply (select rownumber, value from dbo.split(r.currencycode,'ý') ) currencycode
cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber ) currentbalance
outer apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber ) datevalue
或者,您可以清理您的输入以不丢失值。在上面的例子中,我希望 DateValue 是 'ýý' 而不是 'ý'。如果您的情况允许,您可能更愿意查找并修复这些问题,而不是使用外部联接。