2015-12-22 43 views
0

具有字符串“abcd | efg | hijkl”我需要将它分成以下三个值:“abcd”,“efg”和“hijkl”。这是非常简单的 - 考虑到分隔符可以改变它的位置,下面的代码将工作:SQL Server - 通过固定分隔符分割每个表格行

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, @[email protected]) AS Middle 
    ,SUBSTRING(@id, @line2+1, len(@id)[email protected]) AS Last 

现在,假设我有类似的字串的表,我想找回由列“第一”的表, '中间'和'最后',每个人都有适当的价值。 我知道我可以用@ line1和@ line2替换成select查询,但代码不会再被读取......怎么做?

回答

0

您可以使用outer apply存储中间calcutations结果(假设这里已列名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 

这将防止同一表达式的多个拷贝,粘贴和你的代码将保持可读性。

+0

感谢您快速的解答!唯一的一点是最后一行需要看起来像下面这样:outer apply(作为值,选择CHARINDEX('|',Id,CHARINDEX('|',Id)+1)作为行2 - 这将返回有效的结果。谢谢! – katta

+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并更换分隔符(即“|”在你的情况有一些开始和结束XML tags.Here我更换分隔符为“”的标签。

1

如果始终有3个字符串,那么你可以使用PARSENAME功能如下:

DECLARE @s VARCHAR(100) = 'abcd|efg|hijkl' 

SELECT PARSENAME(REPLACE(@s, '|', '.'), 3), 
     PARSENAME(REPLACE(@s, '|', '.'), 2), 
     PARSENAME(REPLACE(@s, '|', '.'), 1) 
+0

优雅的解决方案。感谢分享这个想法。 –