正常枢轴转换为动态或任何其他

时间:2017-07-11 08:45:06

标签: sql sql-server tsql

我有这种数据的表格

ID  name      St_dt     points
1   Mohan   2017-07-10   50
1   Mohan   2017-07-07   30

我想要像这样的结果集

输出

   ID   name    2017-07-10  2017-07-07  Difference  %
    1   Mohan       50        30           20      66.7

我已经实现了Pivot功能并实现了上述结果

示例脚本

Select 
ID,
name,
[2017-07-10],
[2017-07-07],
[Difference] = [2017-07-10] - [2017-07-07],
case when [2017-07-10] > [2017-07-07] 
                then cast(round (([2017-07-10] - [2017-07-07]) *1. / [2017-07-07] * 100, 2) as decimal(3,1)) 
                else 0
           end as [%]
from  ( 
select ID,name,St_dt,points from Table
)T
PIVOT (MAX(points)FOR St_dt IN ([2017-07-10],[2017-07-07]) )PVT

到目前为止这很好,但是当我尝试在Dynamic Pivot中实现同样的目标时我会在百分比计算中面对问题。我如何在动态中实现。

希望我的问题很清楚

请检查我的动态查询,直到差异计算无法实现动态百分比计算

动态脚本

DECLARE @cols  AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';
DECLARE @select_cols AS NVARCHAR(MAX)=''; 
DECLARE @diff_cols varchar(MAX) = '';

SELECT @cols = @cols + QUOTENAME(St_dt) + ',' FROM (select distinct CONVERT(DATE,St_dt)St_dt from #T
 ) as tmp ORDER BY St_dt desc
SELECT @cols = substring(@cols, 0, len(@cols)) 
select @cols 

Set @diff_Cols = stuff((SELECT  '-Max('+Quotename(CONVERT(DATE, St_dt))+') '
             FROM   #T

             group by St_dt
             ORDER  BY St_dt DESC
             FOR xml path('')) ,1,1,'')

select @diff_cols


Select @query = '

Select ID,name,
'+@cols+',
Difference = '+@diff_cols+'


        from (
SELECT      ID,name,St_dt,points
    FROM #T


                    )T
PIVOT (MAX(Points)FOR St_dt IN ('+@cols+') )PVT
GROUP BY ID,name,'+@cols+'

'
EXEC    (@query)

1 个答案:

答案 0 :(得分:0)

请尝试以下操作,它可能对您有所帮助

IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
Declare @Table TABLE (ID INT,name VARCHAR(50),St_dt DATE,points INT)
INSERT INTO @Table
SELECT 1,'Harini','2017-07-10',50 Union all
SELECT 1,'Harini','2017-07-07',30

SELECT * INTO #TempTable FROM @Table

DECLARE @Sql NVARCHAR(max)
    ,@SelectSQL NVARCHAR(max)
    ,@COlumns NVARCHAR(max)
    ,@Previousday NVARCHAR(max)
    ,@Difference NVARCHAR(max)
    ,@CurrentDay NVARCHAR(max)


SELECT @COlumns=STUFF((SELECT  ', '+ QUOTENAME(CAST(St_dt AS VARCHAR(10)))FROM #TempTable GROUP BY St_dt ORDER BY St_dt DESC FOR XML PATH('')),1,1,'')
SELECT @SelectSQL = STUFF((
        SELECT  ', ' + 'ISNULL( MAX( ' + QUOTENAME(CAST(St_dt AS VARCHAR(10))) +' )'+ ',' + '''0''' + ') AS ' + QUOTENAME(CAST(St_dt AS VARCHAR(10)))
        FROM #TempTable GROUP BY St_dt ORDER BY ST_DT DESC
        FOR XML PATH('')
        ), 1, 1, '')


SELECT @CurrentDay=SUBSTRING(@COlumns,CHARINDEX(',',@COlumns)+1,LEN(@COlumns)),@Previousday=SUBSTRING(@COlumns,0,CHARINDEX(',',@COlumns))

SET @Difference=@Previousday+' - '+ @CurrentDay

SET @Sql=N'

SELECT ID,name,'+@SelectSQL+', [Difference]='+@Difference+',
CASE WHEN '+@Previousday+' > '+@CurrentDay+' THEN 
                CAST(ROUND (('+@Difference+') *1./'+@CurrentDay+'* 100, 2) AS DECIMAL(3,1))  ELSE 0  END AS [%]
                FROM (
                    SELECT ID,name,St_dt,points FROM #TempTable
                    )Src
                    PIVOT
                    (
                    MAX(points) FOR St_dt IN ('+@COlumns+')
                    )AS PVT

           Group by PVT.ID,PVT.name,
                    PVT.'+@CurrentDay+',PVT.'+@Previousday+''



PRINT @Sql
EXECute(@Sql)

结果

ID  name    2017-07-10  2017-07-07  Difference  %
------------------------------------------------------
1   Harini   50          30          20         66.7