我有一个文本列,用户在地址中输入。我需要将地址显示/拆分为多个列以包含在报告中。
地址数据位于文本列中,在应用程序/屏幕上如下所示。
123 Stack Street
Holborn
London
EC1 2QW
每个地址行以回车符结束,但在SQL Server 2008上显示在一列中。
如果没有复杂的代码,变量等,任何想法都是如何实现的?
我想在每次回车时分成一个新列。
答案 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个回车符。