我有一个包含代码和说明的列,需要拆分它们。
多个代码可能存在也可能不存在于该字段中。
例如
"CSxxxxx description text here"
"WSxxxxx description text here"
"CSxxxxx, WSxxxxx, CSxxxxx description text here"
如果有多个代码,则应重复描述,因此上面第3行的输出将是插入到辅助表中的3行。
目前,代码的格式始终为:
FixedLetter-FixedLetter-Number-Number-Number-Number-Number
OR
FixedLetter-FixedLetter-Number-Number-Number-Number
我可以编写正则表达式来识别第一对,但是我不熟悉从字符串中删除它并插入到另一个表中?
谢谢, 戴夫
答案 0 :(得分:1)
我能想到这样做的唯一方法很容易"是通过拆分字符串。 SQL Server 2016具有字符串拆分功能。您可以通过Googling" SQL Server split"在网络上找到一个。
那就是这样的:
select t.*, c.code
from t outer apply
(select s.code
from dbo.split(textcol, ' ')) s(code)
where replace(code, ',', '') like '[A-Z][A-Z][0-9][0-9][0-9][0-9][0-9]' or
replace(code, ',', '') like '[A-Z][A-Z][0-9][0-9][0-9][0-9]'
) c(code);
请注意,这应该适用于您问题中的示例。它可能不适用于您的所有数据。文字永远不干净。
答案 1 :(得分:1)
另一种选择是使用CROSS APPLY与一点XML作为解析器(假设不是2016)
示例强>
Declare @YourTable Table (ID int,[SomeCol] varchar(100))
Insert Into @YourTable Values
(1,'CS12345 description text here for id 1')
,(2,'WS67890 description text here for id 2')
,(3,'CS23456, WS34567, CS45678 description text here for id 3')
,(4,'No Codes Just a Desc')
;with cte as (
Select A.ID
,B.*
From @YourTable A
Cross Apply (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(A.SomeCol,' ','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
)
Select ID
,Code = replace(RetVal,',','')
,Descr = Stuff((Select ' ' +RetVal From cte Where A.ID=ID and RetVal Not Like '%[0-9][0-9][0-9][0-9]%' Order By RetSeq For XML Path ('')),1,1,'')
From cte A
Where RetVal Like '%[0-9][0-9][0-9][0-9]%'
Union All
Select ID
,Code = ''
,SomeCol
From @YourTable
Where SomeCol not like '%[0-9][0-9][0-9][0-9]%'
<强>返回强>
ID Code Descr
1 CS12345 description text here for id 1
2 WS67890 description text here for id 2
3 CS23456 description text here for id 3
3 WS34567 description text here for id 3
3 CS45678 description text here for id 3
4 No Codes Just a Desc