2013-08-16 5 views
1

J'ai trois tables. J'ai besoin de scinder les valeurs des lignes en colonnes.SQL Server: lignes dans les colonnes

Tableau 1: [Approval_Type]

App_ID Type_Ds 
2 RMC2 
1 RMC1 

Tableau 2: [Project]

Pro_id Summary 
1 PROJECT1 
2 PROJECT2 

Tableau: 3 [Prj_App]

App_Id Pro_Id ExpDt       ComDt 
1 2 2010-06-05       2010-07-06 
1 1 1999-05-05      1999-05-06 
2 1 1900-01-01      1900-01-05 

Je veux montrer mon résultat que

Pro_Id RMC2 RMC2ExpeDt RMC2ComDt RMC1 RMC1ExpeDt RMC1ComDt 
1   RMC2  1900-01-01 1900-01-05 RMC1 1999-05-05 1999-05-06 
2   NULL  NULL    NULL RMC1 2010-06-05 2010-07-06 

Ci-dessous est ma requête qui retourne

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

SELECT @SQL1 = STUFF((SELECT ',' + QUOTENAME(Type_Ds) + ',' + QUOTENAME(Type_Ds + ' Expected Date') + ',' + QUOTENAME(Type_Ds + ' Completed Date') 
        from dbo.AppType 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'')   
     print @SQL1 

SET @SQL = 'SELECT * 
      FROM ( SELECT A.Pro_Id, 
           Type_DS 
         FROM dbo.Project A left join [dbo].[Prj_App] B on A.Pro_id = B.Pro_Id 
         right outer join dbo.AppType C on B.App_Id = C.App_ID 
        ) data 
        PIVOT 
        ( MAX(Type_DS) 
         FOR Type_DS IN (' + @SQL1 + ') 
        ) pvt1           
        where Pro_Id is not null' 

print @SQL 
EXECUTE SP_EXECUTESQL @SQL 

Pro_Id RMC2 RMC2ExpeDt RMC2ComDt RMC1 RMC1ExpeDt RMC1ComDt 
1 RMC2 NULL  NULL    RMC1 NULL  NULL 
2 NULL NULL  NULL    RMC1 NULL  NULL. 

quelqu'un peut-il aider là-dessus ...

+0

S'il vous plaît modifier vous la question et d'améliorer la mise en page: remplacer les onglets avec des espaces –

+0

Ma suggestion serait pour commencer par la requête sans utiliser SQL dynamique, puis le convertir en SQL dynamique. Pouvez-vous publier les données de table pour 'Prj_Prd'? – Taryn

+0

Édité ma question en fonction des commentaires. J'ai enlevé Prj_Prd qui est ajouté, cette table ne sera pas dans une image. – sk7730

Répondre

2

Ma suggestion lorsque vous travaillez avec SQL dynamique est d'écrire toujours la requête codée en dur première , donc vous pouvez obtenir la logique correcte, puis le convertir en SQL dynamique.

Puisque vous essayez de faire pivoter 3 colonnes de données, je voudrais d'abord déplier les colonnes type_ds, expdt et comdt`, puis appliquer la fonction PIVOT.

La version codée en dur de la requête sera:

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           

Voir SQL Fiddle with Demo. Maintenant que vous avez une version de travail de la requête, vous pouvez facilement le convertir en SQL dynamique:

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 

Voir SQL Fiddle with Demo

+0

Merci beaucoup, ça fonctionne bien – sk7730

Questions connexes