2013-08-16 4 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 столбца данных, я бы сначала отключил столбцы type_ds, expdt и comdt`, а затем применил функцию PIVOT.

Жестко закодирован версия запроса будет:

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

Смежные вопросы