如何设置邮寄地址的格式,以便始终将所有非空行都推到顶部?也就是说,我想将地址从下面的结构转换为邮寄地址。
结构如下:
[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
这样做的方法是使用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”是您需要其地址的记录的标识符。这将返回四个总是4 行 包含您需要为您的地址中的数据。
更新: 如果需要将其作为一组四 列 而不是四行返回,则只需将其放入视图中,然后使用 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