在 SQL 服务器中用 2 个分隔符拆分字符串
Split a string with 2 delimiters in SQL Server
我的 SQL 服务器数据库中有一些错误数据。
看起来像这样:
abc.qwerty@yahoo.com|fubar@cc.uk|helloworld@gmail.com
或
abc.qwerty@yahoo.com;fubar@cc.uk
如果分隔符可以是“|
”、“;
”、“,
”中的任何一个,我如何将它们拆分为单独的电子邮件。
拆分后,结果将添加到同一列中的3列table:
Email1: abc.qwerty@yahoo.com, Email2: fubar@cc.uk, Email3: helloworld@gmail.com
第一步我会清理你的数据。 SQL服务器有一个Replace
功能你可以使用。
REPLACE ( string_expression , string_pattern , string_replacement )
您可以在 SQL Server Management Studio 中 运行 的示例:
select Replace(Replace('ab|de,ghi;de', ',', '|'), ';', '|')
会先替换逗号,再替换分号。结果 ab|de|ghi|de
或者,您可以通过 运行在结果拆分上放置一个游标来多次拆分数据(使用您用于拆分的任何机制。
DECLARE @STR NVARCHAR(MAX)='abc.es@yahoo.com|shudo@cc.uk|maria@gmail.com, abc.es@yahoo.com;shudo@cc.uk'
-- Converts values to rows
SELECT Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
- 查看工作FIDDLEhere
更新
如果您希望逗号分隔值作为最终字符串,您可以执行以下操作
DECLARE @STR NVARCHAR(MAX)='abc.qwerty@yahoo.com|fubar@cc.uk|helloworld@gmail.com,abc.qwerty@yahoo.com;fubar@cc.uk '
DECLARE @Final VARCHAR(MAX)='';
-- Converts values to rows
;WITH CTE AS
(
SELECT DISTINCT
Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
-- Convert to Comma Seperated Values
SELECT @Final +=
Isnull('Email' + CAST(ROW_NUMBER() OVER(ORDER BY IDS)AS VARCHAR(10)) + ': ' + Ids, '') + ', '
FROM CTE
SELECT LEFT(@Final,len(@Final)-1)
PRINT @Final
更新 2:将分隔符分隔的值拆分为行并动态转换为列
我在查询里面写了逻辑
DECLARE @STR NVARCHAR(MAX)='abc.es@yahoo.com|shudo@cc.uk|maria@gmail.com,abc.es@yahoo.com;shudo@cc.uk'
;WITH CTE AS
(
-- Converts values to rows
SELECT DISTINCT Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
-- Create a column to order Emails like Email1,Email2.... and insert to a temp table
-- It can be done without temp table, but its for sake of readability
SELECT 'Email' + CAST(ROW_NUMBER() OVER(ORDER BY Ids)AS VARCHAR(10)) EMails,Ids
INTO #TEMP
FROM CTE
-- Get columns to pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + EMails + ']','[' + EMails + ']')
FROM (SELECT DISTINCT EMails FROM #TEMP) PV
ORDER BY EMails
-- Pivot the result(convert to columns from rows)
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM
(
SELECT EMails,Ids
FROM #TEMP
) x
PIVOT
(
MIN(Ids)
FOR EMails IN (' + @cols + ')
) p;'
EXEC SP_EXECUTESQL @query
现在,如果您想将电子邮件插入到您创建的 table 中,您可以使用以下代码
DECLARE @query NVARCHAR(MAX)
SET @query = 'INSERT INTO YOURTABLE(' + @cols + ')
SELECT * FROM
(
SELECT EMails,Ids
FROM #TEMP
) x
PIVOT
(
MIN(Ids)
FOR EMails IN (' + @cols + ')
) p;'
EXEC SP_EXECUTESQL @query
我的 SQL 服务器数据库中有一些错误数据。
看起来像这样:
abc.qwerty@yahoo.com|fubar@cc.uk|helloworld@gmail.com
或
abc.qwerty@yahoo.com;fubar@cc.uk
如果分隔符可以是“|
”、“;
”、“,
”中的任何一个,我如何将它们拆分为单独的电子邮件。
拆分后,结果将添加到同一列中的3列table:
Email1: abc.qwerty@yahoo.com, Email2: fubar@cc.uk, Email3: helloworld@gmail.com
第一步我会清理你的数据。 SQL服务器有一个Replace
功能你可以使用。
REPLACE ( string_expression , string_pattern , string_replacement )
您可以在 SQL Server Management Studio 中 运行 的示例:
select Replace(Replace('ab|de,ghi;de', ',', '|'), ';', '|')
会先替换逗号,再替换分号。结果 ab|de|ghi|de
或者,您可以通过 运行在结果拆分上放置一个游标来多次拆分数据(使用您用于拆分的任何机制。
DECLARE @STR NVARCHAR(MAX)='abc.es@yahoo.com|shudo@cc.uk|maria@gmail.com, abc.es@yahoo.com;shudo@cc.uk'
-- Converts values to rows
SELECT Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
- 查看工作FIDDLEhere
更新
如果您希望逗号分隔值作为最终字符串,您可以执行以下操作
DECLARE @STR NVARCHAR(MAX)='abc.qwerty@yahoo.com|fubar@cc.uk|helloworld@gmail.com,abc.qwerty@yahoo.com;fubar@cc.uk '
DECLARE @Final VARCHAR(MAX)='';
-- Converts values to rows
;WITH CTE AS
(
SELECT DISTINCT
Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
-- Convert to Comma Seperated Values
SELECT @Final +=
Isnull('Email' + CAST(ROW_NUMBER() OVER(ORDER BY IDS)AS VARCHAR(10)) + ': ' + Ids, '') + ', '
FROM CTE
SELECT LEFT(@Final,len(@Final)-1)
PRINT @Final
更新 2:将分隔符分隔的值拆分为行并动态转换为列
我在查询里面写了逻辑
DECLARE @STR NVARCHAR(MAX)='abc.es@yahoo.com|shudo@cc.uk|maria@gmail.com,abc.es@yahoo.com;shudo@cc.uk'
;WITH CTE AS
(
-- Converts values to rows
SELECT DISTINCT Split.a.value('.', 'VARCHAR(100)') 'Ids'
FROM
(
-- Use 3 REPLACE for '|', ';', ','
SELECT CAST ('<M>' + REPLACE(REPLACE(REPLACE(@STR, '|', '</M><M>'),',','</M><M>'),';','</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
-- Create a column to order Emails like Email1,Email2.... and insert to a temp table
-- It can be done without temp table, but its for sake of readability
SELECT 'Email' + CAST(ROW_NUMBER() OVER(ORDER BY Ids)AS VARCHAR(10)) EMails,Ids
INTO #TEMP
FROM CTE
-- Get columns to pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + EMails + ']','[' + EMails + ']')
FROM (SELECT DISTINCT EMails FROM #TEMP) PV
ORDER BY EMails
-- Pivot the result(convert to columns from rows)
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM
(
SELECT EMails,Ids
FROM #TEMP
) x
PIVOT
(
MIN(Ids)
FOR EMails IN (' + @cols + ')
) p;'
EXEC SP_EXECUTESQL @query
现在,如果您想将电子邮件插入到您创建的 table 中,您可以使用以下代码
DECLARE @query NVARCHAR(MAX)
SET @query = 'INSERT INTO YOURTABLE(' + @cols + ')
SELECT * FROM
(
SELECT EMails,Ids
FROM #TEMP
) x
PIVOT
(
MIN(Ids)
FOR EMails IN (' + @cols + ')
) p;'
EXEC SP_EXECUTESQL @query