我正在尝试创建一个函数,该函数将从表中获取一列,对于单元格中的每个字符串,它将拆分成单独的单词,并连接每个单词separatley以创建不同的子字符串。我一直在研究如何使用SQL等数组来管理它,但是我没有运气
两个表是:
Account(AccountID(PK), Name, Country)
accountSubstring(subID(PK), AccountID, Substring)
理想情况下,我需要一个可以从Account的“名称”列中提取的函数。对于每一行,它将把字符串分成单独的单词,然后通过字符串separatley连接每个单词。然后,这些新创建的子字符串将作为“子字符串”输入到accountSubstring表中,并且该子字符串属于原始表中的AccountID。
例如,如果要更好地解释,如果“名称”中的名称之一是“ Stack Overflow Ireland Ltd”,则预期结果将是:
Stack
StackOverflow
StackOverflowIreland
StackOverflowIrelandLtd
Overflow
OverflowIreland
OverflowIrelandLtd
Ireland
IrelandLtd
Ltd
我需要遍历每个新创建的拆分词和concat,直到到达最后一个词。上面的每一项都将作为新行插入到accountSubstring中,但具有与来自相同原始字符串的相同AccountID。
“帐户”表有成千上万的行,将需要对所有表进行处理。这是一项匹配服务,子字符串用于比较。
希望我已经清楚要做什么,非常感谢。
答案 0 :(得分:0)
这使您先前的问题适应于使用表而不是常量。这是一个示例:
with words as (
select a.accountid, s.value as word, row_number() over (partition by a.accountid order by charindex(s.value, a.name)) as seqnum
from account a cross apply
string_split(a.name, ' ') s
),
cte as (
select accountid, seqnum, convert(varchar(max), word) as combined, format(seqnum, '000') as seqnums
from words w
union all
select cte.accountid, w.seqnum, concat(cte.combined, ' ', w.word), concat(seqnums, ':', format(w.seqnum, '000'))
from cte join
words w
on cte.accountid = w.accountid and w.seqnum = cte.seqnum + 1
)
insert into accountSubstring (AccountId, Substring)
select cte.accountId, cte.combined
from cte
order by accountid, seqnums;
db <>小提琴是here。
答案 1 :(得分:0)
首先创建编号表。
SELECT TOP (4000)
n = ISNULL(CONVERT(integer, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))), 0)
INTO dbo.tblNumber1
FROM sys.columns AS c
CROSS JOIN sys.columns AS c2
CREATE UNIQUE CLUSTERED INDEX cuq
ON dbo.tblNumber1 (n)
WITH (MAXDOP = 1, SORT_IN_TEMPDB = ON);
然后创建分割字符串功能
CREATE FUNCTION [dbo].[DelimitedSplitString] (
@pString VARCHAR(8000)
,@pDelimiter CHAR(1)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
WITH cteStart(N1) AS (
SELECT 1
UNION ALL
SELECT t.number + 1
FROM dbo.tblNumber1 t
WHERE number < datalength(@pString)
AND SUBSTRING(@pString, t.number, 1) = @pDelimiter
)
,cteLen(N1, L1) AS (
SELECT s.N1
,ISNULL(NULLIF(CHARINDEX(@pDelimiter, @pString, s.N1), 0) - s.N1, 8000)
FROM cteStart s
)
SELECT ItemNumber = ROW_NUMBER() OVER (
ORDER BY l.N1
)
,Item = SUBSTRING(@pString, l.N1, l.L1)
FROM cteLen l;
最终脚本,
DECLARE @Input table( id int identity(1,1),pString VARCHAR(2000))
insert into @Input values
('Stack Overflow Ireland Ltd')
,('Replace a sequential set of numbers with special character')
declare @pDelimiter CHAR(1)=' '
declare @t table (id int,itemNum int,Item varchar(50))
INSERT INTO @t
SELECT i.id
,ca.ItemNumber
,ca.Item
FROM @Input I
CROSS APPLY (
SELECT ItemNumber
,Item
FROM [dbo].[DelimitedSplitString](pString, @pDelimiter)
) ca;
WITH CTE
AS (
SELECT *
FROM @t t
,dbo.tblNumber1 n
WHERE n.number <= t.itemNum
)
SELECT id
,(
SELECT '' + item
FROM cte c1
WHERE c.id = c1.id
AND c.number = c1.number
AND c1.itemNum <= c.itemNum
FOR XML path('')
)
FROM CTE c
ORDER BY id
,number
,itemNum