我有一个包含2列的表(在SQL Server中)。一列包含使用tilda ~
分隔的多个服务器名称。此列可能包含也可能不包含实际的服务器名称。另一列具有实际的服务器名称。
我正在寻找一种方法将第一列值分成它们自己的分隔列。别名的数量范围从1到?。
Server_Alias_Names Actual_Server_Name
------------------------------------------------------------
Server1~ROSCO24~Server3~Server4~~~~~ ROSCO24
STEVETESDB26~~~~~~~~~ STEVETESDB26
RALPHPRD117~RALPHPRD117-adm~Server0025~Server0025a1~Server0025a2~Server0025a3~~~~~ RALPHPRD117
Server1001~Server1001R1~Server1001-adm~~~~~~~ DBTEST1001
我从字符串中提取了前两个服务器,我在接下来的几个服务器上遇到了麻烦。任何帮助表示赞赏!!!
SELECT
LEFT(Server_Alias_Names, CHARINDEX('~', Server_Alias_Names) - 1) as 'First_Server',
SUBSTRING(Server_Alias_Names,len(LEFT(Server_Alias_Names, CHARINDEX('~', Server_Alias_Names)+1)),LEN(LEFT(Server_Alias_Names, CHARINDEX ('~', Server_Alias_Names)))) as 'Second_Server'
FROM
TBL_NAME
答案 0 :(得分:3)
实现这一目标的最简单方法是使用字符串拆分器。 Aaron Bertrand在这里提供了相当完整的可行选项列表。 http://sqlperformance.com/2012/07/t-sql-queries/split-strings。请注意,这些都没有任何循环或递归。我不太确定你要对这些信息做什么,但你说你只想解析字符串。
答案 1 :(得分:1)
WITH splitit
AS
(
SELECT Actual_Server_Name, len(Actual_Server_Name) - len(replace(Actual_Server_Name, '~', '')) as TildaCount,
CONVERT(XML,'<X><x>'
+ REPLACE(Server_Alias_Names,'~', '</x><x>') + '</x></X>') AS xmlname
FROM table
)
SELECT Actual_Server_Name,
CASE TildaCount > 0 THEN xmlname.value('/X/x[1]','varchar(100)') ELSE '' END AS s1,
CASE TildaCount > 1 THEN xmlname.value('/X/x[2]','varchar(100)') ELSE '' END AS s2,
CASE TildaCount > 2 THEN xmlname.value('/X/x[3]','varchar(100)') ELSE '' END AS s3,
CASE TildaCount > 3 THEN xmlname.value('/X/x[4]','varchar(100)') ELSE '' END AS s4,
CASE TildaCount > 4 THEN xmlname.value('/X/x[5]','varchar(100)') ELSE '' END AS s5,
CASE TildaCount > 5 THEN xmlname.value('/X/x[6]','varchar(100)') ELSE '' END AS s6,
CASE TildaCount > 6 THEN xmlname.value('/X/x[7]','varchar(100)') ELSE '' END AS s7
FROM splitit
如果你愿意,你也可以从最后删除额外的〜,但我认为即使你不这样做也会有效。
答案 2 :(得分:0)
@Hogan - 我最终将你的脚本与@Sean Lange在评论中提供的链接中的一些帮助结合起来。这就是我想出来的。
WITH splitit
AS
(
SELECT
y.i.value('(./text())[1]', 'nvarchar(4000)') as Separated_Server,
Actual_Server_Name
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(Server_Alias_Names,'~', '</i><i>')
+ '</i>').query('.')
, Actual_Server_Name
FROM TBL_NAME
) as a cross apply x.nodes('i') as y(i)
)
SELECT DISTINCT
Actual_Server_Name,
Separated_Server
FROM splitit
Where Separated_Server is not null
ORDER BY 1,2
--Some of the separated items were also sorted by a comma so I added another step to separate those as well.
--Uncomment the code below for an additional and replace the comma after Separated_Server with the special character you want to use for separation
--,splitit_2
--AS
--(
--SELECT distinct
--ServerName,
--y.i.value('(./text())[1]', 'nvarchar(4000)') as Server_Alias
--FROM
-- (
-- SELECT x = CONVERT(XML, '<i>'
-- + REPLACE(Separated_Server,',', '</i><i>')
-- + '</i>').query('.')
-- ,[ServerName]
-- FROM splitit
-- ) as a cross apply x.nodes('i') as y(i)
--)
--SELECT DISTINCT
--Actual_Server_Name,
--Separated_Server
--FROM splitit_2
--Where Separated_Server is not null
--ORDER BY 1,2