0

I have a SQL select that I'm trying to set up as a View for use as a lookup in another script. This view has 14 columns, one of which is a 'RelationshipCode'. That can be one of 4 possible codes. My data currently has an Order Id, and 13 columns of data for a contact (Name, address, etc), but what I'd like is Order Id, and 12 columns of data for each of those 4 codes.

Current select:

SELECT  [OC].[OrderId]
      , [OC].[ContactFirstName]
      , [OC].[ContactLastName]
      , [OC].[Name]
      , [OC].[Address1]
      , [OC].[Address2]
      , [OC].[City]
      , [OC].[State]
      , [OC].[ZIP]
      , [OC].[RelationshipCode]
      , [OC].[ContactLookUpCode]
      , [OC].[ContactEmail]
      , [OC].[IsMarketingSource]
      , [CI].[UserID]
FROM    [dbo].[OrderContact] AS OC
        INNER JOIN [dbo].[Order] AS O
            ON [O].[Id] = [OC].[OrderId]
        LEFT JOIN [dbo].[ContactInformation] AS CI
            ON [CI].[ContactData] = [OC].[ContactEmail]
        LEFT JOIN [dbo].[Users] AS U
            ON [U].[UserID] = [CI].[UserID]
               AND [U].[Disabled] = 0
WHERE   ( ( [OC].[RelationshipCode] = 'L' )
          OR ( [OC].[RelationshipCode] = 'SB' )
          OR ( [OC].[RelationshipCode] = 'LB' )
          OR ( [OC].[RelationshipCode] = 'M' ) );

Example of the Order Contact Data

Example of the Order Contact Data

What I'm looking for is an output that has columns like so:

SELECT  [OC].[OrderId]
      , [OC].[ContactFirstName] AS [L_FirstName]
      , [OC].[ContactLastName] AS [L_LastName]
      , [OC].[Name] AS [L_Name]
      , [OC].[Address1] AS [L_Address1]
      , [OC].[Address2] AS [L_Address2]
      , [OC].[City] AS [L_City]
      , [OC].[State] AS [L_State]
      , [OC].[ZIP] AS [L_Zip]
      , [OC].[RelationshipCode] AS [L_RelationshipCode]
      , [OC].[ContactLookUpCode] AS [L_LookupCode]
      , [OC].[ContactEmail] AS [L_Email]
      , [OC].[IsMarketingSource] AS [L_IsMarketingSource]
      , [CI].[UserID] AS [L_UserId]

      , [OC].[ContactFirstName] AS [SB_FirstName]
      , [OC].[ContactLastName] AS [SB_LastName]
      , [OC].[Name] AS [SB_Name]
      , [OC].[Address1] AS [SB_Address1]
      , [OC].[Address2] AS [SB_Address2]
      , [OC].[City] AS [SB_City]
      , [OC].[State] AS [SB_State]
      , [OC].[ZIP] AS [SB_Zip]
      , [OC].[RelationshipCode] AS [SB_RelationshipCode]
      , [OC].[ContactLookUpCode] AS [SB_LookupCode]
      , [OC].[ContactEmail] AS [SB_Email]
      , [OC].[IsMarketingSource] AS [SB_IsMarketingSource]
      , [CI].[UserID] AS [SB_UserId]

      , [OC].[ContactFirstName] AS [LB_FirstName]
      , [OC].[ContactLastName] AS [LB_LastName]
      , [OC].[Name] AS [LB_Name]
      , [OC].[Address1] AS [LB_Address1]
      , [OC].[Address2] AS [LB_Address2]
      , [OC].[City] AS [LB_City]
      , [OC].[State] AS [LB_State]
      , [OC].[ZIP] AS [LB_Zip]
      , [OC].[RelationshipCode] AS [LB_RelationshipCode]
      , [OC].[ContactLookUpCode] AS [LB_LookupCode]
      , [OC].[ContactEmail] AS [LB_Email]
      , [OC].[IsMarketingSource] AS [LB_IsMarketingSource]
      , [CI].[UserID] AS [LB_UserId]

      , [OC].[ContactFirstName] AS [M_FirstName]
      , [OC].[ContactLastName] AS [M_LastName]
      , [OC].[Name] AS [M_Name]
      , [OC].[Address1] AS [M_Address1]
      , [OC].[Address2] AS [M_Address2]
      , [OC].[City] AS [M_City]
      , [OC].[State] AS [M_State]
      , [OC].[ZIP] AS [M_Zip]
      , [OC].[RelationshipCode] AS [M_RelationshipCode]
      , [OC].[ContactLookUpCode] AS [M_LookupCode]
      , [OC].[ContactEmail] AS [M_Email]
      , [OC].[IsMarketingSource] AS [M_IsMarketingSource]
      , [CI].[UserID] AS [M_UserId]

The idea being that I'd have an order id, and all the contacts that went with it, on one record. (Trying to prevent some N+1 issues on the end-user-interface.)

PKD
  • 685
  • 1
  • 13
  • 37
  • I'll also admit that a Pivot might not be what's needed here - perhaps a Cross Apply? I'm open to pretty much anything that does the trick and doesn't bring the server to a crashing halt. – PKD Dec 07 '15 at 21:29
  • 1
    You could add joins specific to each relationship type; provided you are always limited to 4. If there are more you could dynamic pivot to show each of the columns for each relationship several dynamic pivot examples already on stack for SQL-Server [Here's one](http://stackoverflow.com/questions/18657214/sql-server-dynamic-pivot-over-5-columns) if not dynamic. Think creating a CTE for each query for each relationship type then simply joining them back to base set on key'd values. – xQbert Dec 07 '15 at 21:44

2 Answers2

1

One way is to do conditional aggregation:

SELECT  [OC].[OrderId]

      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[ContactFirstName] END) AS [L_FirstName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[ContactLastName] END) AS [L_LastName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[Name] END) AS [L_Name]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[Address1] END) AS [L_Address1]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[Address2] END) AS [L_Address2]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[City] END) AS [L_City]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[State] END) AS [L_State]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[ZIP] END) AS [L_Zip]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[RelationshipCode] END) AS [L_RelationshipCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[ContactLookUpCode] END) AS [L_LookupCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[ContactEmail] END) AS [L_Email]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [OC].[IsMarketingSource] END) AS [L_IsMarketingSource]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'L' THEN  [CI].[UserID] END) AS [L_UserId]

      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[ContactFirstName] END) AS [SB_FirstName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[ContactLastName] END) AS [SB_LastName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[Name] END) AS [SB_Name]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[Address1] END) AS [SB_Address1]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[Address2] END) AS [SB_Address2]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[City] END) AS [SB_City]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[State] END) AS [SB_State]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[ZIP] END) AS [SB_Zip]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[RelationshipCode] END) AS [SB_RelationshipCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[ContactLookUpCode] END) AS [SB_LookupCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[ContactEmail] END) AS [SB_Email]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [OC].[IsMarketingSource] END) AS [SB_IsMarketingSource]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'SB' THEN  [CI].[UserID] END) AS [SB_UserId]

      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[ContactFirstName] END) AS [LB_FirstName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[ContactLastName] END) AS [LB_LastName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[Name] END) AS [LB_Name]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[Address1] END) AS [LB_Address1]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[Address2] END) AS [LB_Address2]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[City] END) AS [LB_City]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[State] END) AS [LB_State]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[ZIP] END) AS [LB_Zip]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[RelationshipCode] END) AS [LB_RelationshipCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[ContactLookUpCode] END) AS [LB_LookupCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[ContactEmail] END) AS [LB_Email]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [OC].[IsMarketingSource] END) AS [LB_IsMarketingSource]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'LB' THEN  [CI].[UserID] END) AS [LB_UserId]

      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[ContactFirstName] END) AS [M_FirstName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[ContactLastName] END) AS [M_LastName]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[Name] END) AS [M_Name]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[Address1] END) AS [M_Address1]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[Address2] END) AS [M_Address2]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[City] END) AS [M_City]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[State] END) AS [M_State]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[ZIP] END) AS [M_Zip]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[RelationshipCode] END) AS [M_RelationshipCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[ContactLookUpCode] END) AS [M_LookupCode]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[ContactEmail] END) AS [M_Email]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [OC].[IsMarketingSource] END) AS [M_IsMarketingSource]
      , MAX(CASE WHEN [OC].[RelationshipCode] = 'M' THEN  [CI].[UserID] END) AS [M_UserId]
FROM    [dbo].[OrderContact] AS OC
        INNER JOIN [dbo].[Order] AS O
            ON [O].[Id] = [OC].[OrderId]
        LEFT JOIN [dbo].[ContactInformation] AS CI
            ON [CI].[ContactData] = [OC].[ContactEmail]
        LEFT JOIN [dbo].[Users] AS U
            ON [U].[UserID] = [CI].[UserID]
               AND [U].[Disabled] = 0
WHERE   ( ( [OC].[RelationshipCode] = 'L' )
          OR ( [OC].[RelationshipCode] = 'SB' )
          OR ( [OC].[RelationshipCode] = 'LB' )
          OR ( [OC].[RelationshipCode] = 'M' ) )
GROUP BY [OC].[OrderId]
Felix Pamittan
  • 31,544
  • 7
  • 41
  • 67
1

Avoiding all those CASE -WHEN-END instances can be done like this, which may be a performance improvement on a large data set.

with rawData as (
  SELECT OC.[OrderId]
        ,OC.[ContactFirstName]
        ,OC.[ContactLastName]
        ,OC.[Name]
        ,OC.[Address1]
        ,OC.[Address2]
        ,OC.[City]
        ,OC.[State]
        ,OC.[ZIP]
        ,OC.[RelationshipCode]
        ,OC.[ContactLookUpCode]
        ,OC.[ContactEmail]
        ,OC.[IsMarketingSource]
        ,CI.[UserID]
  FROM [dbo].[OrderContact]            OC
  JOIN [dbo].[Order]                   O  ON O.[Id]           = OC.[OrderId]
  LEFT JOIN [dbo].[ContactInformation] CI ON CI.[ContactData] = OC.[ContactEmail]
  LEFT JOIN [dbo].[Users]              U  ON U.[UserID]       = CI.[UserID]
                                         AND U.[Disabled]     = 0
  cross apply (values
     ('L'),('SB'),('LB'),('M') 
  unpvt(RelationshipCode)
  where unpvt.RelationshipCode = OC.RelationshipCode
)
,L  as (select * from rawData where relationshipCode = 'L' )
,LB as (select * from rawData where relationshipCode = 'BL' )
,SB as (select * from rawData where relationshipCode = 'SB' )
,M  as (select * from rawData where relationshipCode = 'M' )

select
     OC.OrderID
    ,isnull(L.[ContactFirstName],'')  as L_ContactFirstName
    ,isnull(L.[ContactLastName],'')   as L_ContactLastName
    ,isnull(L.[Name],'')              as L_Name
    ,isnull(L.[Address1],'')          as L_Address1
    ,isnull(L.[Address2],'')          as L_Address2
    ,isnull(L.[City],'')              as L_City
    ,isnull(L.[State],'')             as L_State
    ,isnull(L.[ZIP],'')               as L_ZIP
    ,isnull(L.[RelationshipCode],'')  as L_RelationshipCode
    ,isnull(L.[ContactLookUpCode] ,'')as L_ContactLookUpCode
    ,isnull(L.[ContactEmail],'')      as L_ContactEmail
    ,isnull(L.[IsMarketingSource],'') as L_IsMarketingSource

    ,isnull(SB.[UserID],'')            as SB_UserID
    ,isnull(SB.[ContactFirstName],'')  as SB_ContactFirstName
    ,isnull(SB.[ContactLastName],'')   as SB_ContactLastName
    ,isnull(SB.[Name],'')              as SB_Name
    ,isnull(SB.[Address1],'')          as SB_Address1
    ,isnull(SB.[Address2],'')          as SB_Address2
    ,isnull(SB.[City],'')              as SB_City
    ,isnull(SB.[State],'')             as SB_State
    ,isnull(SB.[ZIP],'')               as SB_ZIP
    ,isnull(SB.[RelationshipCode],'')  as SB_RelationshipCode
    ,isnull(SB.[ContactLookUpCode],'') as SB_ContactLookUpCode
    ,isnull(SB.[ContactEmail],'')      as SB_ContactEmail
    ,isnull(SB.[IsMarketingSource],'') as SB_IsMarketingSource

    ,isnull(LB.[UserID],'')            as LB_UserID
    ,isnull(LB.[ContactFirstName],'')  as LB_ContactFirstName
    ,isnull(LB.[ContactLastName],'')   as LB_ContactLastName
    ,isnull(LB.[Name],'')              as LB_Name
    ,isnull(LB.[Address1],'')          as LB_Address1
    ,isnull(LB.[Address2],'')          as LB_Address2
    ,isnull(LB.[City] ,'')             as LB_City
    ,isnull(LB.[State] ,'')            as LB_State
    ,isnull(LB.[ZIP],'')               as LB_ZIP
    ,isnull(LB.[RelationshipCode],'')  as LB_RelationshipCode
    ,isnull(LB.[ContactLookUpCode],'') as LB_ContactLookUpCode
    ,isnull(LB.[ContactEmail],'')      as LB_ContactEmail
    ,isnull(LB.[IsMarketingSource],'') as LB_IsMarketingSource

    ,isnull(M.[UserID],'')            as M_UserID
    ,isnull(M.[ContactFirstName],'')  as M_ContactFirstName
    ,isnull(M.[ContactLastName],'')   as M_ContactLastName
    ,isnull(M.[Name],'')              as M_Name
    ,isnull(M.[Address1],'')          as M_Address1
    ,isnull(M.[Address2] ,'')         as M_Address2
    ,isnull(M.[City],'')              as M_City
    ,isnull(M.[State],'')             as M_State
    ,isnull(M.[ZIP],'')               as M_ZIP
    ,isnull(M.[RelationshipCode],'')  as M_RelationshipCode
    ,isnull(M.[ContactLookUpCode],'') as M_ContactLookUpCode
    ,isnull(M.[ContactEmail],'')      as M_ContactEmail
    ,isnull(M.[IsMarketingSource],'') as M_IsMarketingSource
    ,isnull(M.[UserID],'')            as M_UserID
from [dbo].[OrderContact] OC
left join  L on  L.OrderID  = OC.OrderID
left join SB on SB.OrderID  = OC.OrderID
left join LB on LB.OrderID  = OC.OrderID
left join  M on  M.OrderID  = OC.OrderID
Pieter Geerkens
  • 11,775
  • 2
  • 32
  • 52