互联网上有许多拆分功能。我个人的偏好是由 Jeff Moden 创建并在过去几年中由社区增强的。你可以在这里找到他的文章,http://www.sqlservercentral.com/articles/Tally+Table/72993/。确保您查看 cmets ......在此发布时有几百个。这是该拆分器的代码。
CREATE FUNCTION [dbo].[DelimitedSplit8K]
--===== Define I/O parameters
(@pString VARCHAR(8000), @pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
--===== "Inline" CTE Driven "Tally Table" produces values from 0 up to 10,000...
-- enough to cover VARCHAR(8000)
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), --10E+1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS (--==== This provides the "zero base" and limits the number of rows right up front
-- for both a performance gain and prevention of accidental "overruns"
SELECT 0 UNION ALL
SELECT TOP (DATALENGTH(ISNULL(@pString,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
SELECT t.N+1
FROM cteTally t
WHERE (SUBSTRING(@pString,t.N,1) = @pDelimiter OR t.N = 0)
)
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY s.N1),
Item = SUBSTRING(@pString,s.N1,ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000))
FROM cteStart s
;
无论您使用哪种拆分器(只要它是表值函数),它都可以像这样工作。
if OBJECT_ID('tempdb..#Something') is not null
drop table #Something;
create table #Something
(
SomeValue varchar(100)
);
insert #Something
select 'World Cup 2014' union all
select 'Family Guy' union all
select 'UFC Fight Night' union all
select '9pm News and Weather' union all
select '2014 Media Awards' union all
select 'Homeland 2524232' union all
select 'Simpsons 2524231' union all
select 'Shameless' union all
select 'Soccer Night 4534232 International' union all
select 'Rugby Live 4534232 HTML5';
with ParsedData as
(
select *
from #Something s
cross apply dbo.DelimitedSplit8K(s.SomeValue, ' ')
where Item not like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
)
select distinct
Stuff((SELECT ' ' + Item
FROM ParsedData p2
WHERE p1.SomeValue = p2.SomeValue
ORDER BY p1.ItemNumber --The split function keeps track of the order for us already
FOR XML PATH('')), 1, 1, ' ') as Details
from ParsedData p1