sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server:rader i kolumner

Mitt förslag när du arbetar med dynamisk SQL är att alltid skriva frågan hårdkodad först, så att du kan få logiken korrekt och sedan konvertera den till dynamisk SQL.

Eftersom du försöker pivotera tre kolumner med data skulle jag först ta bort type_ds , expdt och comdt` kolumner, använd sedan PIVOT-funktionen.

Den hårdkodade versionen av frågan kommer att vara:

SELECT  *
FROM    
(   
  select pro_id,
    type_ds = case 
                when col ='type_ds' 
                then type_ds 
                else type_ds+col end,
    value
  from
  (
     SELECT A.Pro_Id,
       c.Type_DS,
       convert(varchar(10), b.ExpDt, 120) ExpDt, 
       convert(varchar(10), b.ComDt, 120) ComDt
     FROM  dbo.Project A  
     left join [dbo].[Prj_App] B 
        on A.Pro_id = B.Pro_Id
     right outer join dbo.Approval_Type C 
        on B.App_Id = C.App_ID
   ) s
   cross apply
   (
      select 'type_ds', type_ds union all
      select 'expdt', expdt union all
      select 'comdt', comdt
   ) c (col, value)
) data
PIVOT
(   
  MAX(value)
  FOR Type_DS IN (RMC2, RMC2expdt, RMC2comdt,
                   RMC1, RMC1expdt, RMC1comdt) 
) pvt1                                        

Se SQL-fiol med demo . Nu när du har en fungerande version av frågan kan du enkelt konvertera den till dynamisk SQL:

DECLARE @SQL1 NVARCHAR(MAX) = ''
DECLARE @SQL NVARCHAR(MAX) = ''

SELECT  @SQL1 = STUFF((SELECT ',' + QUOTENAME(Type_Ds) + ',' +  QUOTENAME(Type_Ds + 'ExpDt') + ',' + QUOTENAME(Type_Ds + 'ComDt')
                    from dbo.Approval_Type 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')   


SET @SQL = 'SELECT  *
            FROM    
            (   
              select pro_id,
                type_ds = case 
                            when col =''type_ds'' 
                            then type_ds 
                            else type_ds+col end,
                value
              from
              (
                 SELECT A.Pro_Id,
                   c.Type_DS,
                   convert(varchar(10), b.ExpDt, 120) ExpDt, 
                   convert(varchar(10), b.ComDt, 120) ComDt
                 FROM  dbo.Project A  
                 left join [dbo].[Prj_App] B 
                    on A.Pro_id = B.Pro_Id
                 right outer join dbo.Approval_Type C 
                    on B.App_Id = C.App_ID
               ) s
               cross apply
               (
                  select ''type_ds'', type_ds union all
                  select ''expdt'', expdt union all
                  select ''comdt'', comdt
               ) c (col, value)
           ) data
           PIVOT
           (   
              MAX(value)
              FOR Type_DS IN (' + @SQL1 + ') 
           ) pvt1 '

--print @SQL
EXECUTE SP_EXECUTESQL @SQL

Se SQL-fiol med demo




  1. Än en gång:lagrad procedur kontra TV-UDF

  2. Rails Migration Skapa tabell Primär nyckel

  3. ASP MVC MsSql till MySQL migrering

  4. Jämför exekveringsplaner i SQL Server