2012-11-14 82 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

相關問題