我正在尝试分割一个字符串,该字符串具有3个设置的Alpha字符,这些字符可以按任意顺序显示,后跟一个数字值。我遇到的问题是字母字符的顺序不固定。字母字符后面的数字值的数量也不能包含以下任何示例:
X1Y45Z1
Y25Z1
X1Y9Z1
X2Z6
在我们本地IT部门的大量帮助下(我仍在学习SQL),我设法将X Y和Z分成带有数字后的单独列,但它们并不总是按顺序出现
我正在尝试获得如下结果:
如果X在col1中,则在新列“ X”中显示X后面的编号,如果Y在col1中,则在新列“ Y”中显示Y后面的编号,等等。
目前,我们使用2个cte分解字符串。并且我正在尝试简化它,以便我可以搜索字符串,在创建“ X”,“ Y”,“ Z”之后具有3列,并在每个Alpha分隔符后放入正确的数字。我应该注意,我没有具有完全的管理员访问权限,所以我无法创建新表或更新/插入数据或清除它。
如果格式略有错误,也表示歉意。这是我在StackOverflow上的第一篇文章
declare @tbl table
(
Col1 varchar(100), <-------This Column contains the values I want
)
insert into @tbl
select Col1,
from table1,
where xyz
;with cte as
(
select
Col1,
replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(**Col1**,'P', '</x><x>P'),'C', '</x><x>C'),'I', '</x><x>I'),'M', '</x><x>M'),'S', '</x><x>S'),'Q', '</x><x>Q'),'L', '</x><x>L'),'T', '</x><x>T'),'E', '</x><x>E'),'R', '</x><x>R'),'U', '</x><x>U'),'W', '</x><x>W')
**Col1NODES**
from
@tbl
)
, cte2 (Col1, Col1Nodes) as
(
select
Col1,
convert(xml,'<z><x>' + Col1nodes + '</x></z>') **Col1NODES**
from
cte
)
select
Col1,
isnull(Col1Nodes.value('/z[1]/x[2]','varchar(100)'),'-') F1,
isnull(Col1Nodes.value('/z[1]/x[3]','varchar(100)'),'-') F2,
isnull(Col1Nodes.value('/z[1]/x[4]','varchar(100)'),'-') F3
from
cte2
当前输出如下:
答案 0 :(得分:2)
如果您拥有SQL Server 2016+,则可以尝试基于JSON使用以下解决方案。重要的部分是将输入数据转换为有效的JSON对象(例如,将X1Y45Z1
转换为{"X":1,"Y":45,"Z":1}
)。之后,您需要使用适当的OPENJSON()
子句和WITH
函数来解析此对象,以定义输出中的列。
表格:
CREATE TABLE Data (
TextData nvarchar(100)
)
INSERT INTO Data
(TextData)
VALUES
('X1Y45Z1'),
('Y25Z1'),
('X1Y9Z1'),
('X2Z6'),
('Z1X6')
声明:
SELECT d.TextData, j.*
FROM Data d
CROSS APPLY OPENJSON(
CONCAT(
N'{',
STUFF(REPLACE(REPLACE(REPLACE(d.TextData, N'X', N',"X":'), N'Y', N',"Y":'), N'Z', N',"Z":'), 1, 1, N''),
N'}'
)
) WITH (
X int '$.X',
Y int '$.Y',
Z int '$.Z'
) j
输出:
---------------------
TextData X Y Z
---------------------
X1Y45Z1 1 45 1
Y25Z1 25 1
X1Y9Z1 1 9 1
X2Z6 2 6
Z1X6 6 1
对于SQL Server 2016之前的版本,您可以使用基于XML的方法。您需要将文本数据转换为适当的XML(例如,X1Y45Z1
被转换为<row><name>X</name><value>1</value></row><row><name>Y</name><value>45</value></row><row><name>Z</name><value>1</value></row>
):
SELECT
TextData,
XmlData.value('(/row[name = "X"]/value/text())[1]', 'nvarchar(4)') AS X,
XmlData.value('(/row[name = "Y"]/value/text())[1]', 'nvarchar(4)') AS Y,
XmlData.value('(/row[name = "Z"]/value/text())[1]', 'nvarchar(4)') AS Z
FROM (
SELECT
TextData,
CONVERT(
xml,
CONCAT(
STUFF(REPLACE(REPLACE(REPLACE(d.TextData, N'X', N'</value></row><row><name>X</name><value>'), N'Y', N'</value></row><row><name>Y</name><value>'), N'Z', N'</value></row><row><name>Z</name><value>'), 1, 14, N''),
N'</value></row>'
)
) AS XmlData
FROM Data d
) x