如何将“地址”文本列拆分为多个列

时间:2014-02-18 21:25:23

标签: sql sql-server split

我有一个文本列,用户在地址中输入。我需要将地址显示/拆分为多个列以包含在报告中。

地址数据位于文本列中,在应用程序/屏幕上如下所示。

123 Stack Street
Holborn
London
EC1 2QW

每个地址行以回车符结束,但在SQL Server 2008上显示在一列中。

如果没有复杂的代码,变量等,任何想法都是如何实现的?

我想在每次回车时分成一个新列。

4 个答案:

答案 0 :(得分: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))

答案 1 :(得分:0)

测试数据

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       ║
╚════╩═══════════════╩═════════════════╩═══════════════╩════════════════════╩═══════════════╝

拆分功能

我在我的解决方案中使用了分割功能,请参阅此处了解Sql Server Split function

的定义

答案 2 :(得分:0)

我一直更喜欢xml并回到任何其他选项。我还注意到你说过“TEXT”所以我继续在第一个执行REPLACE的表表达式中为你做了varchar(max)转换。

基本上用end / begin xml标签替换所有CHAR(13)。用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)

答案 3 :(得分:0)

如果使用sql server 2016(问题是5年前)或更高版本,则您有https://docs.microsoft.com/en-us/sql/t-sql/functions/parsename-transact-sql?view=sql-server-2016可用。只需将回车符替换为“。”角色优先。每行最多可返回3-4个回车符。