2012-11-14 55 views
4

我有一个数据库字段,其中包含以多行字符串形式存储的地址信息。如何在tsql中将多行字符串拆分为列

88 Park View 
Hemmingdale 
London 

谁能告诉我拿到第1行的最好方式,线2 &线在SELECT语句中作为3场不同?

问候 理查德

回答

5

尝试这样的事情?你要知道,这是有点脆弱

DECLARE @S VARCHAR(500), @Query VARCHAR(1000) 
SELECT @S='88 Park View 
      Hemmingdale 
      London' 

SELECT @Query=''''+ REPLACE(@S, CHAR(13),''',''')+'''' 
EXEC('SELECT '[email protected]) 

结果

88 Park View | Hemmingdale | London 
0

只是为了好玩,用XML解决方案更新。这应该处理'。'问题,并可以很容易地扩展到更多的线路。

DECLARE @xml XML , @S VARCHAR(500) = '88 Park View 
Hemmingdale 
London' 

SET @xml = CAST('<row><col>' + REPLACE(@S,CHAR(13),'</col><col>') + '</col></row>' AS XML) 

SELECT 
    line.col.value('col[1]', 'varchar(1000)') AS line1 
    ,line.col.value('col[2]', 'varchar(1000)') AS line2 
    ,line.col.value('col[3]', 'varchar(1000)') AS line3 
FROM @xml.nodes('/row') AS line(col) 
+0

聪明,但“88公园景街”呢? –

+0

@TimLehner,你是对的。也许这不是一个好主意,使用'。'地址:) – EricZ

3

这里是我想出了一个使用CTE递归迭代值的表,并通过新的生产线CHAR(13)他们拆出来,然后用PIVOT显示结果的解决方案。您可以通过将其添加到PIVOT,将其扩展到其他列(超过5个)。

DECLARE @Table AS TABLE(ID int, SomeText VARCHAR(MAX)) 

INSERT INTO @Table VALUES(1, '88 Park View 
Hemmingdale 
London') 

INSERT INTO @Table VALUES(2, '100 Main Street 
Hemmingdale 
London') 

INSERT INTO @Table VALUES(3, '123 6th Street 
Appt. B 
Hemmingdale 
London') 

;WITH SplitValues (ID, OriginalValue, SplitValue, Level) 
AS 
(
    SELECT ID, SomeText, CAST('' AS VARCHAR(MAX)), 0 FROM @Table 

    UNION ALL 

    SELECT ID 
    , SUBSTRING(OriginalValue, CASE WHEN CHARINDEX(CHAR(13), OriginalValue) = 0 THEN LEN(OriginalValue) + 1 ELSE CHARINDEX(CHAR(13), OriginalValue) + 2 END, LEN(OriginalValue)) 
    , SUBSTRING(OriginalValue, 0, CASE WHEN CHARINDEX(CHAR(13), OriginalValue) = 0 THEN LEN(OriginalValue) + 1 ELSE CHARINDEX(CHAR(13), OriginalValue) END) 
    , Level + 1 
    FROM SplitValues 
    WHERE LEN(SplitValues.OriginalValue) > 0 
) 

SELECT ID, [1] AS Level1, [2] AS Level2, [3] AS Level3, [4] AS Level4, [5] AS Level5 
FROM (
    SELECT ID, Level, SplitValue 
    FROM SplitValues 
    WHERE Level > 0 
    ) AS p 
PIVOT (MAX(SplitValue) FOR Level IN ([1], [2], [3], [4], [5])) AS pvt 

结果:

ID   Level1    Level2    Level3    Level4    Level5 
----------- -------------------- -------------------- -------------------- -------------------- -------------------- 
1   88 Park View   Hemmingdale   London    NULL     NULL 
2   100 Main Street  Hemmingdale   London    NULL     NULL 
3   123 6th Street  Appt. B    Hemmingdale   London    NULL 
+0

非常好的答案。 – Paddy

0

我知道这是可怕的,但这样一来,你有3行3列,分别为L1,L2和L3:

declare @input nvarchar(max) = 'line 1' + CHAR(13) + CHAR(10) + 'line 2' + CHAR(13) + CHAR(10) + 'line 3' + CHAR(13) + CHAR(10) + 'line 4' + CHAR(13) + CHAR(10) + 'line 5' 
declare @delimiter nvarchar(10) = CHAR(13) + CHAR(10) 

declare @outtable table (id int primary key identity(1,1), data nvarchar(1000)) 

declare @pos int = 1 
declare @temp nvarchar(1000) 

if substring(@input, 1, len(@delimiter)) = @delimiter 
begin 
    set @input = substring(@input, 1+len(@delimiter), len(@input)) 
end 

while @pos > 0 
begin 

    set @pos = patindex('%' + @delimiter + '%', @input) 

    if @pos > 0 
     set @temp = substring(@input, 1, @pos-1) 
    else 
     set @temp = @input 

    insert into @outtable (data) values (@temp) 

    set @input = substring(@input, @pos+len(@delimiter), len(@input)) 

end 

select 
    top 1 ISNULL(a.data,'') as l1, ISNULL(b.data,'') as l2, ISNULL(c.data,'') as l3 
from 
    @outtable a 
     left outer join @outtable b on b.id = 2 
     left outer join @outtable c on c.id = 3 

sqlfiddle here

相关问题