如何实现动态形成列的计算

时间:2017-07-10 10:21:56

标签: sql sql-server tsql

我有动态脚本:

SET @cols = stuff((SELECT DISTINCT ','+Quotename(CONVERT(DATE, Start_dt)) 
             FROM   Events
             WHERE  Start_dt >= Cast(Dateadd(day, -1, Getdate()) AS DATE)
             ORDER  BY Start_dt DESC
             FOR xml path('')) ,1,1,'')
--Print @cols

SET @select_cols = stuff((SELECT DISTINCT ',Max('+Quotename(CONVERT(DATE, Start_dt))+') as '+Quotename(CONVERT(DATE, t)) 
             FROM   Events
             WHERE  Start_dt >= Cast(Dateadd(day, -1, Getdate()) AS DATE)
             ORDER  BY Start_dt DESC
             FOR xml path('')) ,1,1,'')
--Print @select_cols

Select @query = '

Select Name, tableName,'+@select_cols+'
        from (
SELECT      Name,
            tableName,
            Cnt
    FROM  Table1 l 

            WHERE Name=''Employee'' AND
                     Start_dt >= CAST(dateadd(day, -1, getdate()) as date))T
PIVOT (MAX(Cnt)FOR Start_dt IN ('+@cols+') )PVT
GROUP BY  Name, tableName
'

EXEC   (@query)

并获得像这样的输出

 Name     TableName  [2017-07-10]   [2017-07-09]

 mohan     Employee    10020     10080

我想对两个日期列的计数实施计算

    Name      TableName  [2017-07-10]   [2017-07-09]   Difference  Percentage

    mohan      Employee      10020          10080        60           0.6%

我如何在此查询中实现此计算。

静态百分比计算:

case when [2017-07-09] > [2017-07-10]
                then cast(round (([2017-07-09] - [2017-07-10]) *1. / [2017-07-09] * 100, 2) as decimal(3,1)) 
                else 0
           end as [%]

如何在动态

中添加此计算

2 个答案:

答案 0 :(得分:0)

您可以添加一个查询以获取@diff_cols,如下所示

declare @diff_cols varchar(max)

Set @diff_Cols = stuff((SELECT  '-Max('+Quotename(CONVERT(DATE, Start_dt))+') '
             FROM   Events
             WHERE  Start_dt >= Cast(Dateadd(day, -1, Getdate()) AS DATE)
             group by Start_dt
             ORDER  BY Start_dt DESC
             FOR xml path('')) ,1,1,'')

并修改您的动态查询,如下所示:

Select @query = '

Select Name, tableName,'+@select_cols+', Difference = '+@diff_cols+', [Percentage] =    case when QuoteName(ParseName(replace(@cols,'','',''.''),2)) > QuoteName(ParseName(replace(@cols,'','',''.''),1))
                then cast(round ((QuoteName(ParseName(replace(@cols,'','',''.''),2)) - QuoteName(ParseName(replace(@cols,'','',''.''),1))) *1. / QuoteName(ParseName(replace('[2017-07-10],[2017-07-09]','','',''.''),1))* 100, 2) as decimal(3,1)) 
                else 0
           end as [%]
        from (
SELECT      Name,
            tableName,
            Cnt
    FROM  Table1 l 

            WHERE Name=''Employee'' AND
                     Start_dt >= CAST(dateadd(day, -1, getdate()) as date))T
PIVOT (MAX(Cnt)FOR Start_dt IN ('+@cols+') )PVT
GROUP BY  Name, tableName
'

Select @query -- check your query and then execute as below
EXEC   (@query)

答案 1 :(得分:0)

或类似的东西(我没有测试过它)

    SET @cols = stuff((SELECT DISTINCT ','+Quotename(CONVERT(DATE, Start_dt)) 
                 FROM   Events
                 WHERE  Start_dt >= Cast(Dateadd(day, -1, Getdate()) AS DATE)
                 ORDER  BY Start_dt DESC
                 FOR xml path('')) ,1,1,'')
    --Print @cols

    SET @select_cols = stuff((SELECT DISTINCT ',Max('+Quotename(CONVERT(DATE, Start_dt))+') as '+Quotename(CONVERT(DATE, t)) 
                 FROM   Events
                 WHERE  Start_dt >= Cast(Dateadd(day, -1, Getdate()) AS DATE)
                 ORDER  BY Start_dt DESC
                 FOR xml path('')) ,1,1,'')
    --Print @select_cols

/* --- line changed --- */
    Select @query = 'SELECT A.*' 
            +', ' + REPLACE(@cols,',','-')+' AS Difference' +', ('+ REPLACE(@cols,',','-') +')/'+SUBSTRING(@cols, CHARINDEX(@cols,',')-1)+' AS Percentage FROM ('
    +
    'Select Name, tableName,'+@select_cols+'
            from (
    SELECT      Name,
                tableName,
                Cnt
        FROM  Table1 l 

                WHERE Name=''Employee'' AND
                         Start_dt >= CAST(dateadd(day, -1, getdate()) as date))T
    PIVOT (MAX(Cnt)FOR Start_dt IN ('+@cols+') )PVT
    GROUP BY  Name, tableName
    ) A
    '

    EXEC   (@query)