TSQL для преобразования адреса в почтовый адрес - SQL Server 2005 - PullRequest
2 голосов
/ 10 декабря 2010

Я хотел бы преобразовать адрес (Line1, Line2, Line3, City, State, ZIP) в почтовый адрес (Addr1, Addr2, Addr3, Addr4), в котором нет пустых строк, а город, штат и ZIP объединены вместе на одной линии. Было бы неплохо иметь такую ​​функцию.

т.е.
Line1 =
Line2 = 123 Где-то
Line3 =
Город = Детройт
State = MI
Почтовый индекс = 48000

Вот структура таблицы для входящего адреса:

IF OBJECT_ID('tempdb..#Employee') IS NOT NULL DROP TABLE #Employee
CREATE TABLE #Employee (Line1 VARCHAR(30), Line2 VARCHAR(30), Line3 VARCHAR(30), 
  City VARCHAR(17), State VARCHAR(2), ZIP VARCHAR(10)) 
GO 

INSERT #Employee VALUES ('', '123 Somewhere', '', 'Detroit', 'MI', '48000') 

SELECT * FROM #Employee  

Полученный почтовый адрес

Addr1 = 123 Где-то
Addr2 = Детройт, штат Мичиган 48000
Addr3 =
Addr4 =

или одно поле с cr символ
Addr =
123 Где-то кр
Детройт МИ 48000 кр
кр
кр

Было бы неплохо, чтобы функция возвращала Addr1, Addr2, Addr3 и Addr4 или просто Addr с помощью.

SqueezeAddress (Line1, Line2, Line3, City, State, ZIP)
Тогда SqueezeAddress возвращает Addr1, Addr2, Addr3, Addr4
или
Адр с кр

Все строки Addr1-4 будут VARCHAR (40) или если используется одно поле Addr VARCHAR (200)

Согласно запросу Фила в комментариях ниже, здесь используется текущая логика (многие поля были удалены, чтобы было легче читать):

SELECT Line1, Line2, Line3, 
    ISNULL(LTRIM(RTRIM(ADDR.City)) + ', ','')  + ISNULL(ADDR.RegionCode,'') 
    + ' ' + ISNULL(ADDR.PostalCode,'') AS Line4,

  UPDATE #tmpBilling
  SET Line1 = Line2, Line2 = NULL
  WHERE ISNULL(Line1, '') = ''
    AND ISNULL(Line2, '') <> ''

  UPDATE #tmpBilling
  SET Line2 = Line3, Line3 = NULL
  WHERE ISNULL(Line2, '') = ''
    AND ISNULL(Line3, '') <> ''

  UPDATE #tmpBilling
  SET Line2 = Line4, Line4 = NULL
  WHERE ISNULL(Line2, '') = ''
    AND ISNULL(Line4, '') <> ''

  UPDATE #tmpBilling
  SET Line3 = Line4, Line4 = NULL
  WHERE ISNULL(Line3, '') = ''
    AND ISNULL(Line2, '') <> ''

Ответы [ 3 ]

3 голосов
/ 10 декабря 2010

Возможно, я что-то здесь упускаю, но если это просто простая конкатенация строк, тогда это сработает ...

Настройка данных тестирования (я добавил еще несколько образцов)

IF OBJECT_ID('tempdb..#Employee') IS NOT NULL DROP TABLE #Employee 
CREATE TABLE #Employee (Line1 VARCHAR(30), Line2 VARCHAR(30), Line3 VARCHAR(30),  
  City VARCHAR(17), State VARCHAR(2), ZIP VARCHAR(10))  
GO  

INSERT #Employee VALUES ('', '123 Somewhere', '', 'Detroit', 'MI', '48001')  
INSERT #Employee VALUES ('123 Somewhere', 'Suite 500', '', 'Detroit', 'MI', '48002')  
INSERT #Employee VALUES ('123 Somewhere', 'Suite 500', 'attn: JP', 'Detroit', 'MI', '48003')  

SELECT * FROM #Employee 

Отсюда все, что вам нужно сделать, это сшить нити вместе. Эта версия предполагает, что у вас есть как нулевые, так и пустые строки для разметки.

SELECT
    isnull(nullif(Line1, '') + char(13) + char(10), '')
  + isnull(nullif(Line2, '') + char(13) + char(10), '')
  + isnull(nullif(Line3, '') + char(13) + char(10), '')
  + City + ' ' + State + ' ' + ZIP
  + char(13) + char(10) + '------------------------------'
 from #Employee

Оберните это в функцию:

CREATE FUNCTION dbo.SqueezeAddress
 (
   @Line1  varchar(30)
  ,@Line2  varchar(30)
  ,@Line3  varchar(30)
  ,@City   varchar(17)
  ,@State    varchar(2)
  ,@Zip    varchar(10)
 )
RETURNS varchar(200)
AS
 BEGIN
    RETURN isnull(nullif(@Line1, '') + char(13) + char(10), '')
            + isnull(nullif(@Line2, '') + char(13) + char(10), '')
            + isnull(nullif(@Line3, '') + char(13) + char(10), '')
            + @City + ' ' + @State + ' ' + @ZIP
            + char(13) + char(10) + '------------------------------'
 END
GO

Наконец, поместите функцию в запрос:

SELECT dbo.SqueezeAddress(Line1, Line2, Line3, City, State, Zip)
 from #Employee
1 голос
/ 10 декабря 2010

Более просто (и легче отлаживать, ИМХО):

-------------------------------------------------------------
-- assumptions:
-- 
-- * nullable fields never contain an nil (empty) string.
--   every nullable column will contain either a proper value
--   or NULL.
--
-- * zipcode is a 5- or 9-digit USPS zip code, without a dash.
--   Addresses lacking a zipcode will be NULL.
--------------------------------------------------------------
drop table dbo.address
go
create table dbo.address
(
  id int not null identity(1,1) primary key clustered ,
  line1   varchar(100) null ,
  line2   varchar(100) null ,
  line3   varchar(100) null ,
  city    varchar(100) null ,
  state   varchar(2)   null ,
  zipcode varchar(9)   null ,
)
go
-----------------------------------------------------------------------
-- create a work table and rotate the source table such that
-- the work table contains 1 row for each non-null row for each address
-----------------------------------------------------------------------
drop table #addr
go
create table #addr
(
  id      int          not null , -- pk.1
  line_no int          not null , -- pk.2
  value   varchar(100) not null ,

  primary key clustered ( id , line_no ) ,

)
go

insert #addr ( id , line_no , value )
select addr.id , addr.line_no , addr.value
from ( select id      = t.id ,
       line_no = row_number() over ( partition by t.id order by t.seq ) ,
       value   = t.value
       from ( select id    = id ,
                     seq   = 1  ,
                     value = line1
              from dbo.address where line1 is not null
              UNION
              select id    = id ,
                     seq   = 2  ,
                     value = line2
              from dbo.address where line2 is not null
              UNION
              select id    = id ,
                     seq   = 3  ,
                     value = line3
              from dbo.address where line3 is not null
              UNION
              select id    = id ,
                     seq   = 4  ,
                     value = ltrim(rtrim(
                                 coalesce( city    , '' )
                               + case when city is not null and state is not null then ', ' else '' end
                               + coalesce( state   , '' )
                               + case when ( city is not null or state is not null ) and zipcode is not null then ' ' else '' end
                               + coalesce( left(zipcode,5) , '' )
                               + case when len(zipcode) = 9 then '-' + right(zipcode,4) else '' end
                               ))
              from dbo.address
              where city    is not null
                 OR state   is not null
                 OR zipcode is not null
            ) t
     ) addr

---------------------------------------------------------------------
-- finally, do another table rotation to build the desired result set
---------------------------------------------------------------------
select id    = addr.id    ,
       line1 = line1.value ,
       line2 = line2.value ,
       line3 = line3.value ,
       line4 = line4.value
from      #addr addr
left join #addr line1 on line1.id = addr.id and line1.line_no = 1
left join #addr line2 on line2.id = addr.id and line2.line_no = 2
left join #addr line3 on line3.id = addr.id and line3.line_no = 3
left join #addr line4 on line4.id = addr.id and line4.line_no = 4
order by addr.id
1 голос
/ 10 декабря 2010

Предполагая, что пустые значения на самом деле являются NULL, а не пустыми строками, и что город, штат и Zip запрашиваются:

;With AddressValues As
    (
    Select PK, Line1 As LineValue, 1 As LinePos
    From AddressTable
    Union All
    Select PK, Line2, 2
    From AddressTable
    Union All
    Select PK, Line3, 3
    From AddressTable
    Union All
    Select PK, [City] + ', ' + [State] + '  ' + [Zip], 4
    From AddressTable
    )
    , OrderedValues As
    (
    Select PK, LineValue
        , Row_Number() Over( Partition By PK Order By LinePos ) As Num
    From AddressValues
    Where LineValue Is Not Null
    )
    , ValuesAsColumns As
    (
    Select PK
        , Case When Num = 1 Then LineValue End As Line1
        , Case When Num = 2 Then LineValue End As Line2
        , Case When Num = 3 Then LineValue End As Line3
        , Case When Num = 4 Then LineValue End As Line4
    From OrderedValues
    Group By PK
    )
Update #tmpBilling
Set Line1 = VC.Line1
    , Line2 = VC.Line2
    , Line3 = VC.Line3
    , Line4 = VC.Line4
From #tmpBilling As B
    Join ValuesAsColumns As VC
        On VC.PK = B.PK

EDIT

Здесь то жерезультат в виде функции:

CREATE FUNCTION dbo.SqueezeAddress
(
    @Line1 varchar(50)
    , @Line2 varchar(50)
    , @Line3 varchar(50)
    , @City varchar(50)
    , @State varchar(50)
    , @Zip varchar(50)
    , @LineNumToReturn int

)
RETURNS varchar(50)
AS
BEGIN

Declare @Result varchar(50);

With AddressValues As
    (
    Select @Line1 As LineValue, 1 As LinePos
    Union All
    Select @Line2, 2
    Union All
    Select @Line3, 3
    Union All
    Select @City + ', ' + @State + '  ' + @Zip, 4
    )
    , OrderedValues As
    (
    Select LineValue
        , Row_Number() Over( Order By LinePos ) As Num
    From AddressValues
    Where LineValue Is Not Null
    )
Select @Result = LineValue
From OrderedValues
Where Num = @LineNumToReturn

Return @Result  

END
GO

Select dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 1)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 2)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 3)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 4)

)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...