2014-02-18 3 views
2

У меня есть один текстовый столбец, в котором пользователи вводят адреса. Мне нужно отобразить/разделить адреса на несколько столбцов для включения в отчет.Как разбить столбец текста адреса на несколько столбцов

Данные адреса находятся в столбце «Текст» и отображаются, как показано ниже на приложении/экране.

123 Stack Street 
Holborn 
London 
EC1 2QW 

Каждая строка адреса заканчивается символом возврата каретки, но отображается в один столбец на SQL Server 2008.

Любая идея, как это может быть достигнуто без сложного кода, переменных и т.д.?

Я хотел бы разделить на каждое возвращение каретки в новую колонку.

+1

123 Stack Street (CR) Holborn (CR) Лондон (CR) EC1 2QW (CR) – user3306489

+0

Вы пробовали это прибегая к помощи? Или даже глядя на переполнение стека? Какие у вас проблемы? Что вы пробовали? –

+0

Поиск 'Split Delimited String' или' Parse разделенная запятой строка '... единственный сложный бит заключается в том, что вместо запятой у вас есть' CHAR (13) 'как ваш разделитель. –

ответ

0

Test Data

DECLARE @TABLE TABLE ([Address] [VARCHAR](4000)) 
INSERT INTO @TABLE VALUES 
('123' + CHAR(13) + 'Stack Street'+ CHAR(13) + 'Holborn' 
        + CHAR(13) + 'London'+ CHAR(13) + 'EC1 2QW'), 
('456' + CHAR(13) + 'OverFlow Street'+ CHAR(13) + 'Bolton' 
     + CHAR(13) + 'Greater Manchester'+ CHAR(13) + 'M1 6lML') 

Запрос

SELECT * 
FROM 
(
SELECT DENSE_RANK() OVER (ORDER BY [Address]) AS rn 
     ,'Address Line' + CAST(ElementID AS NVARCHAR(10)) AS AddressLines 
     , Element 
FROM @TABLE 
      CROSS APPLY dbo.func_Split([Address], CHAR(13))c 
)Q 
PIVOT (MAX(Element) 
     FOR AddressLines 
     IN ([Address Line1],[Address Line2],[Address Line3] 
      ,[Address Line4],[Address Line5]) 
    )p 

Результат Набор

╔════╦═══════════════╦═════════════════╦═══════════════╦════════════════════╦═══════════════╗ 
║ rn ║ Address Line1 ║ Address Line2 ║ Address Line3 ║ Address Line4 ║ Address Line5 ║ 
╠════╬═══════════════╬═════════════════╬═══════════════╬════════════════════╬═══════════════╣ 
║ 1 ║   123 ║ Stack Street ║ Holborn  ║ London    ║ EC1 2QW  ║ 
║ 2 ║   456 ║ OverFlow Street ║ Bolton  ║ Greater Manchester ║ M1 6lML  ║ 
╚════╩═══════════════╩═════════════════╩═══════════════╩════════════════════╩═══════════════╝ 

Функция Split

Я использовал раздвоение функцию в моем решении увидеть здесь для определения Sql Server Split function

2
CREATE function [dbo].[SplitString] 
(
    @str nvarchar(max), 
    @separator char(1) 
) 
returns table 
AS 
return (
with tokens(p, a, b) AS (
    select 
     cast(1 as bigint), 
     cast(1 as bigint), 
     charindex(@separator, @str) 
    union all 
    select 
     p + 1, 
     b + 1, 
     charindex(@separator, @str, b + 1) 
    from tokens 
    where b > 0 
) 
select 
    p-1 ItemIndex, 
    substring(
     @str, 
     a, 
     case when b > 0 then b-a ELSE LEN(@str) end) 
    AS Item 
from tokens 
); 

Затем выполнить его как этот

select ItemIndex,Item 
from SplitString('123 Stack Street 
    Holborn 
    London 
    EC1 2QW',CHAR(13)) 
+0

Привет, спасибо, но как это сделать для столбца, содержащего адреса? – user3306489

0

Я всегда предпочитал XML и вернуться к любому из других вариантов. Я также заметил, что вы сказали «ТЕКСТ», поэтому я пошел вперед и сделал текст для преобразования varchar (max) для вас в первом выражении таблицы, которое делает REPLACE.

По существу заменить все CHAR (13) на тег конца/начала xml. Оберните это в XML. Выведите его как XML. Отбросьте его обратно на стол так, как вы считаете нужным.

DECLARE @Tmp TABLE (Id INT,Name TEXT) 
INSERT @Tmp SELECT 1,'123 Stack Street' + CHAR(13) + 'Holborn' + CHAR(13) + 'EC1 2QW' 

DECLARE @XML XML = 
(
    SELECT T.Id AS "@ID", 
      CONVERT(XML,'<PART>' + REPLACE(CAST(Name AS VARCHAR(max)),CHAR(13),'</PART><PART>') + '</PART>') AS AddressParts 
    FROM  @Tmp AS T 
    FOR XML PATH('Name'), ROOT('Names'), ELEMENTS, TYPE 
) 

SELECT Address1 = FieldAlias.value('(AddressParts/PART)[1]','varchar(max)'), 
     Address2 = FieldAlias.value('(AddressParts/PART)[2]','varchar(max)'), 
     Address3 = FieldAlias.value('(AddressParts/PART)[3]','varchar(max)'), 
     Address3 = FieldAlias.value('(AddressParts/PART)[4]','varchar(max)') 
FROM  @XML.nodes('//Name') AS S(FieldAlias) 
Смежные вопросы