如何格式化邮件地址,以便始终将所有非空行推送到顶部?也就是说,我想将地址从下面的结构转换为邮寄地址。
这是结构:
[Line1] [varchar](50) NULL,
[Line2] [varchar](50) NULL,
[Line3] [varchar](50) NULL,
[City] [varchar](50) NULL,
[State] [varchar] (2) NULL,
[PostalCode] [varchar](50) NULL,
以下是一些示例数据:
Line1=
Line2=123 Some Address
Line3=
City=Royal Oak
State=MI
ZIP=45673-2312
以下结果应该是(应返回4个不同或单独的字段):
MailAddress1=123 Some Address
MailAddress2=ROYAL OAK MI 45673-2312
MailAddress3=
MailAddress4=
我正在使用SQL Server 2005。
有人在我们公司写了这个逻辑,它似乎很复杂(注意:这不是整个SELECT语句):
,CASE
WHEN eai.Line1 IS NULL OR eai.Line1 = '' THEN
CASE
WHEN eai.Line2 IS NULL OR eai.Line2 = '' THEN
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
ELSE eai.Line3
END
ELSE eai.Line2
END
ELSE eai.Line1
END
,CASE
WHEN eai.Line1 IS NULL OR eai.Line1 = '' THEN
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
ELSE eai.Line3
END
ELSE
CASE
WHEN eai.Line2 IS NULL OR eai.Line2 = '' THEN
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
ELSE eai.Line3
END
ELSE eai.Line2
END
END
,CASE
WHEN eai.Line1 IS NULL OR eai.Line1 = '' THEN
CASE
WHEN eai.Line2 IS NULL OR eai.Line2 = '' THEN NULL
ELSE
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN NULL
ELSE ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
END
END
ELSE
CASE
WHEN eai.Line2 IS NULL OR eai.Line2 = '' THEN
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN NULL
ELSE ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
END
ELSE
CASE
WHEN eai.Line3 IS NULL OR eai.Line3 = '' THEN ISNULL(LTRIM(RTRIM(eai.City)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(eai.PostalCode)),'')
ELSE eai.Line3
END
END
END
,CASE WHEN eai.Line2 IS NOT NULL AND eai.Line2 <> '' AND eai.Line3 IS NOT NULL AND eai.Line3 <> '' THEN eai.City + ' ' + eai.RegionCode + ' ' + eai.PostalCode ELSE NULL END
答案 0 :(得分:7)
这样做的方法是使用UNPIVOT。这是解决方案:
With AddrTable as (
Select AddrFld, MailAddr From (
Select Cast(ISNULL([Line1], '') as Varchar(102)) as [A1],
Cast(ISNULL([Line2], '') as Varchar(102)) as [A2],
Cast(ISNULL([Line3], '') as Varchar(102)) as [A3],
Cast(ISNULL(LTRIM(RTRIM(City)),'') + ' ' + ISNULL(LTRIM(RTRIM(RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(PostalCode)),'') as Varchar(102)) as A4
From TableName Where UniqueID=@UniqueID) p
Unpivot (MailAddr For AddrFld in ([A1], [A2], [A3], [A4])) as unpvt)
Select Row_Number() over (Order by (Case Len(MailAddr) When 0 then 1 else 0 end), AddrFld) as RN,
MailAddr From AddrTable
Order By RN
这是输出:
Address1
Westby WI 55555
-empty line-
-empty line-
请注意,我必须使用“Varchar(102)”作为字段长度(unpivot要求所有字段都相同),因为您的城市/地区/邮政总共最多可以有102个字符。另请注意,“@ UniqueID”是您需要的记录的标识符。这将返回四个,总是四个行,其中包含您的地址所需的数据。
更新: 如果您需要将其作为一组四个列而不是四行返回,那么只需将其放入视图中然后使用 Pivot 查询视图。我在这里包含了视图的完整性,因为在创建视图时我必须稍微改变上面的内容,因此包含了uniqueID字段并且没有进行排序(排序现在在查询中完成):
Create View AddressRows AS
With AddrTable as (
Select UniqueID, AddrFld, MailAddr From (
Select UniqueID,
Cast(ISNULL([Line1], '') as Varchar(102)) as [A1],
Cast(ISNULL([Line2], '') as Varchar(102)) as [A2],
Cast(ISNULL([Line3], '') as Varchar(102)) as [A3],
Cast(ISNULL(LTRIM(RTRIM(City)),'') + ' ' + ISNULL(LTRIM(RTRIM(RegionCode)),'') + ' ' + ISNULL(LTRIM(RTRIM(PostalCode)),'') as Varchar(102)) as A4
From TableName Where UniqueID=@UniqueID) p
Unpivot (MailAddr For AddrFld in ([A1], [A2], [A3], [A4])) as unpvt)
Select UniqueID,
Row_Number() over (Order by (Case Len(MailAddr) When 0 then 1 else 0 end), AddrFld) as RN,
MailAddr From AddrTable
然后,当您想要将匹配的“行”拉出时,使用此SQL将其转回(注意我使用UniqueID再次查询):
Select [Addr1], [Addr2], [Addr3], [Addr4] From (
Select Top 4 'Addr' + Cast(Row_Number() over (Order by RN) as Varchar(12)) as AddrCol, -- "Top 4" needed so we can sneak the "Order By" in
MailAddr
From AddressRows Where UniqueID=@UniqueID
) p PIVOT (Max([MailAddr]) for AddrCol in ([Addr1], [Addr2], [Addr3], [Addr4])
) as pvt
返回:
Addr1 Addr2 Addr3 Addr4
-------------- ------------------ ------------- ------------------
Address1 Westby WI 54667
答案 1 :(得分:1)
这是一个三分钟投资的解决方案:
DECLARE @address TABLE (
[Line1] [varchar](50) NULL,
[Line2] [varchar](50) NULL,
[Line3] [varchar](50) NULL,
[City] [varchar](50) NULL,
[State] [varchar] (2) NULL,
[PostalCode] [varchar](50) NULL
)
INSERT INTO @address (
[Line1],
[Line2],
[Line3],
[City],
[State],
[PostalCode]
)
VALUES (
NULL,
'123 Some Address',
NULL,
'Royal Oak',
'MI',
'45673-2312'
)
SELECT * FROM @address
SELECT
ISNULL(Line1 + CHAR(13), '')
+ ISNULL(Line2 + CHAR(13), '')
+ ISNULL(Line3 + CHAR(13), '')
+ ISNULL(City + ' ', '')
+ ISNULL([State] + ' ', '')
+ ISNULL(PostalCode, '')
FROM @address
结果:
123 Some Address
Royal Oak MI 45673-2312
在获得所需结果之前,先控制控制字符。
答案 2 :(得分:0)
SELECT
LTRIM(RTRIM(LINE1)) + LTRIM(RTRIM(LINE2)) + LTRIM(RTRIM(LINE3)) AS MailAddress1,
LTRIM(RTRIM(CITY)) + ' ' + LTRIM(RTRIM(STATE)) + ' ' + LTRIM(RTRIM(POSTALCODE)) AS MailAddress2
FROM MyTable