Как я могу улучшить этот почтовый адрес оператора SQL Server SELECT? - PullRequest
2 голосов
/ 16 марта 2009

Как я могу отформатировать почтовый адрес, чтобы я всегда помещал все ненулевые строки в верх? То есть я хочу преобразовать адрес из структуры ниже в почтовый адрес.

Вот структура:

[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

Ответы [ 3 ]

7 голосов
/ 16 марта 2009

Способ сделать это с помощью 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)" в качестве длины поля (для отмены требуется, чтобы все поля были одинаковыми), потому что ваш город / регион / почтовый индекс может иметь до 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 голос
/ 16 марта 2009

Вот решение за три минуты:

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

Работайте с управляющими символами, пока не получите нужный результат.

0 голосов
/ 16 марта 2009

</p> <pre> 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 </pre> <p>

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