拥有字符串“abcd | efg | hijkl”我需要将其拆分为以下三个值:“abcd”,“efg”和“hijkl”。这很简单 - 考虑到分隔符可以改变它的位置,下面的代码将起作用:
DECLARE @id VARCHAR(100), @line1 INT, @line2 INT
SET @id = 'abcd|efg|hijkl'
SET @line1 = (SELECT CHARINDEX('|', @id))+1
SET @line2 = (SELECT CHARINDEX('|', @id, CHARINDEX('|', @id)+1))
SELECT LEFT(@id, CHARINDEX('|', @id)-1) AS First
,SUBSTRING(@id, @line1, @line2-@line1) AS Middle
,SUBSTRING(@id, @line2+1, len(@id)-@line2) AS Last
现在,假设我有一个类似字符串的表,我想检索由'First','Middle'和'Last'列组成的表,每个列都有适当的值。 我知道我可以用@ line1和@ line2代替select查询,但代码将不再可读了...怎么做?
答案 0 :(得分:1)
使用 XML :
尝试使用此代码一次带有样本值的临时表:
create table #YOUR_TABLE
(
[Name] varchar(100)
)
insert into #YOUR_TABLE values('abcd|efg|hijkl'),('a|e|hij')
使用XML查询所需的输出:
DECLARE @delimiter VARCHAR(100)
SET @delimiter='|' --IN This Variable you can change your required delimeter
;
WITH CTE
AS (SELECT [Name],
Cast('<M>'
+ Replace([Name], @delimiter, '</M><M>')
+ '</M>' AS XML) AS [Name XML]
FROM #YOUR_TABLE)
SELECT [Name],
[Name XML].value('/M[1]', 'varchar(100)') AS [First Name],
[Name XML].value('/M[2]', 'varchar(100)') AS [Middle Name],
[Name XML].value('/M[3]', 'varchar(100)') AS [Last Name]
FROM CTE
<强>输出强>:
Name First Name Middle Name Last Name
abcd|efg|hijkl abcd efg hijkl
a|e|hij a e hij
这里的第一步是将该字符串转换为XML并替换分隔符(即&#39; |&#39;在您的情况下使用一些开始和结束XML标记。这里我将delimeter替换为&#39; &#39;标签。
答案 1 :(得分:1)
如果总有3个字符串,那么您可以使用PARSENAME
函数:
DECLARE @s VARCHAR(100) = 'abcd|efg|hijkl'
SELECT PARSENAME(REPLACE(@s, '|', '.'), 3),
PARSENAME(REPLACE(@s, '|', '.'), 2),
PARSENAME(REPLACE(@s, '|', '.'), 1)
答案 2 :(得分:0)
您可以使用outer apply
存储中间卡路里结果(假设此处列的名称也为id
):
select
LEFT(id, CHARINDEX('|', id)-1) AS First
,SUBSTRING(id, line1.Value, line2.Value - line1.Value) AS Middle
,SUBSTRING(id, line2.Value + 1, len(id) - line2.Value) AS Last
from your_table
outer apply (SELECT CHARINDEX('|', id) + 1 as Value) as line1
outer apply (SELECT CHARINDEX('|', id, CHARINDEX('|', id) + 1) as Value) as line2
这样可以防止对同一表达式进行多次复制粘贴,并且您的代码仍然可读。