Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como posso melhorar esta instrução SQL Server SELECT de endereço de correspondência?


A maneira de fazer isso é com um UNPIVOT. Aqui está a solução:
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 [email protected]) 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

Aqui está a saída:
Address1
Westby WI  55555
-empty line-
-empty line-

Observe que eu tive que usar "Varchar(102)" como o tamanho do campo (unpivot exige que todos os campos sejam iguais) porque sua cidade/região/postal pode ter até 102 caracteres no total. Além disso, observe que "@UniqueID" é o identificador do registro cujo endereço você precisa. Isso retorna quatro e sempre quatro linhas contendo os dados necessários para o seu endereço.

ATUALIZAÇÃO: Se você precisar retornar isso como um conjunto de quatro colunas em vez de quatro linhas, basta colocá-lo em uma visualização e, em seguida, consultar a visualização com um Pivot . Incluí a exibição aqui para ser completa, pois tive que alterar um pouco o acima ao criar a exibição para que o campo uniqueID fosse incluído e nenhuma classificação fosse feita (a classificação agora é feita na consulta):
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 [email protected]) 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 

E então, quando você quiser extrair sua "linha" correspondente, gire-a de volta usando este SQL (observe que estou consultando novamente usando 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 [email protected]
) p PIVOT (Max([MailAddr]) for AddrCol in ([Addr1], [Addr2], [Addr3], [Addr4])
) as pvt

Isso retorna:
Addr1            Addr2                Addr3           Addr4
--------------   ------------------   -------------   ------------------ 
Address1         Westby WI  54667