我在解析一些我得到的数据时遇到了一些问题,其格式如下:
1. FREE_AGENT "10710,|9452,"
2. FREE_AGENT "11381,|2918,"
3. FREE_AGENT "10220,|"
4. FREE_AGENT "9625,|"
5. FREE_AGENT "11213,11225,11193,|"
,|
分隔符之前的所有内容都被视为播放器添加,,|
分隔符之后的所有内容都被视为丢弃。
理想情况下,我希望将其解析为如下所示的行:
1. FREE_AGENT ADD "10710"
1. FREE_AGENT DROP "9452"
2. FREE_AGENT ADD "11381"
2. FREE_AGENT DROP "2918"
3. FREE_AGENT ADD "10220"
4. FREE_AGENT ADD "9625"
5. FREE_AGENT ADD "11213"
5. FREE_AGENT ADD "11225"
5. FREE_AGENT ADD "11193"
任何帮助将不胜感激。我有基本的t-sql字符串分割器,但没有得到很多运气,如
CREATE FUNCTION split(
@delimited NVARCHAR(MAX),
@delimiter NVARCHAR(100)
) RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))
AS
BEGIN
DECLARE @xml XML
SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>'
INSERT INTO @t(val)
SELECT r.value('.','varchar(MAX)') as item
FROM @xml.nodes('/t') as records(r)
RETURN
END
答案 0 :(得分:0)
我喜欢使用动态sql来解析字符串。您可以使用Union All Select
(在其他解析中)替换分隔符以使其工作:
-- load your test data
declare @YourTable table(AGENT varchar(10),STRING varchar(50))
insert into @YourTable values
('FREE_AGENT','10710,|9452,'),
('FREE_AGENT','11381,|2918,'),
('FREE_AGENT','10220,|'),
('FREE_AGENT','9625,|'),
('FREE_AGENT','11213,11225,11193,|')
-- create dynamic query to return parsed STRING value
-- with associated AGENT and ADD_DROP value
declare @sql varchar(max)
set @sql = ''
select @sql = @sql + '
select
''' + AGENT + ''' AGENT,
''' + ADD_DROP + ''' ADD_DROP,
' + replace(STRING,',','
union all
select
''' + AGENT + ''' AGENT,
''' + ADD_DROP + ''' ADD_DROP,') + '
union all'
from (
select
AGENT,
'ADD' ADD_DROP,
replace(left(STRING,charindex('|',STRING)),',|','') STRING
from @YourTable
where replace(left(STRING,charindex('|',STRING)),'|','') <> ''
union all
select
AGENT,
'DROP' ADD_DROP,
replace(replace(right(STRING,charindex('|',
reverse(STRING))),'|','') + '|',',|','') STRING
from @YourTable
where replace(right(STRING,charindex('|',reverse(STRING))),'|','') <> ''
) q
-- remove last union all
set @sql = replace(@sql + '|','union all|','')
-- return results
exec(@sql)
答案 1 :(得分:0)
因为你只有一个“,|”用于将ADD与DROP分开的分隔符,您可以在CTE中执行此操作,以便它们返回两个不同的列,一个ADD的CSV列和一个DROP的CSV列。然后你可以用标准分割器拆分它们,使用UNION ALL将一列的拆分与另一列的拆分结合起来。
示例:强>
(请注意,下面的示例使用了一个名为SQL#(SQLsharp)的SQLCLR库,我是作者。此处使用的拆分函数可以在免费版中获得。如果您愿意,还有其他几种方法可以正确拆分SQL Server中的CSV,我已在此answer)
DECLARE @Data TABLE (AgentID INT NOT NULL PRIMARY KEY,
Agent NVARCHAR(50),
Actions VARCHAR(500))
INSERT INTO @Data VALUES (1, N'FREE_AGENT', '10710,|9452,')
INSERT INTO @Data VALUES (2, N'FREE_AGENT','11381,|2918,')
INSERT INTO @Data VALUES (3, N'FREE_AGENT','10220,|')
INSERT INTO @Data VALUES (4, N'FREE_AGENT','9625,|')
INSERT INTO @Data VALUES (5, N'FREE_AGENT','11213,11225,11193,|')
INSERT INTO @Data VALUES (6, N'FREE_AGENT','9633,|342,54545,')
;WITH SplitActions AS
(
SELECT sd.AgentID,
sd.Agent,
sd.Actions,
CHARINDEX(',|', sd.Actions) AS [DelimiterLocation]
FROM @Data sd
),
SplitValues AS
(
SELECT sa.AgentID,
sa.Agent,
SUBSTRING(sa.Actions, 1, (sa.DelimiterLocation - 1)) AS [Adds],
SUBSTRING(sa.Actions, (sa.DelimiterLocation + 2), 500) AS [Drops]
FROM SplitActions sa
)
SELECT sv.AgentID, sv.Agent, N'ADD' AS [Action], addvals.SplitVal AS [ID]
FROM SplitValues sv
CROSS APPLY SQL#.String_Split4k(sv.Adds, N',', 2) addvals
UNION ALL
SELECT sv.AgentID, sv.Agent, N'DROP' AS [Action], dropvals.SplitVal AS [ID]
FROM SplitValues sv
CROSS APPLY SQL#.String_Split4k(sv.Drops, N',', 2) dropvals
ORDER BY [AgentID] ASC, [Action] ASC
输出
AgentID Agent Action ID
1 FREE_AGENT ADD 10710
1 FREE_AGENT DROP 9452
2 FREE_AGENT ADD 11381
2 FREE_AGENT DROP 2918
3 FREE_AGENT ADD 10220
4 FREE_AGENT ADD 9625
5 FREE_AGENT ADD 11213
5 FREE_AGENT ADD 11225
5 FREE_AGENT ADD 11193
6 FREE_AGENT ADD 9633
6 FREE_AGENT DROP 342
6 FREE_AGENT DROP 54545