Mi sugerencia cuando trabaja con SQL dinámico es escribir siempre la consulta codificada primero, para que pueda obtener la lógica correcta y luego convertirla a SQL dinámico.
Dado que está intentando pivotar 3 columnas de datos, primero descentraría el type_ds
, expdt
y columnas comdt`, luego aplique la función PIVOT.
La versión codificada de la consulta será:
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
Consulte SQL Fiddle con demostración . Ahora que tiene una versión funcional de la consulta, puede convertirla fácilmente a SQL dinámico:
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
Consulte SQL Fiddle con demostración