2013-08-16 72 views
1

我有三個表。我需要將行值轉換爲列。SQL Server:成列的行

表1:[Approval_Type]

App_ID Type_Ds 
2 RMC2 
1 RMC1 

表2:[Project]

Pro_id Summary 
1 PROJECT1 
2 PROJECT2 

表: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 

我想顯示我的結果作爲

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 

下面是我的查詢返回

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. 

任何人都可以在上面幫...

+0

請編輯你的問題,提高了佈局:空格替換 –

+0

我的建議是標籤首先對不使用動態sql的查詢進行調整,然後將其轉換爲動態SQL。你可以發佈「Prj_Prd」的表格數據嗎? – Taryn

+0

根據評論編輯我的問題。我刪除了額外添加的Prj_Prd,該表不會顯示在圖片中。 – sk7730

回答

2

我當你使用動態SQL的建議是始終編寫查詢第一個硬編碼,所以你可以得到正確的邏輯,然後將其轉換爲動態SQL。

既然你正試圖轉動數據的3列我首先UNPIVOT的type_dsexpdt和comdt`列,然後應用旋轉功能。

查詢的硬編碼的版本將是:

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           

SQL Fiddle with Demo。現在,你有查詢的工​​作版本,您可以輕鬆地將其轉換爲動態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 

SQL Fiddle with Demo

+0

非常感謝,它工作正常 – sk7730