0

我无法在 SQL 语句中将当前日期的 12 个月用于我的 Stimulsoft 报告。sql 表结构是这样的(图 1),注意我是巴西人,所以文化设置为 pt-BR (dd/mm/yyyy)

这是 SQL 表

http://img534.imageshack.us/img534/1093/clipboard02xva.jpg

我想做这个,过去 12 个月的当前日期是 01/02/2013 所以我们采取:

| DACP_Id | FEB 2012 | MAR 2012 | ABR 2012 ... | FEB 2013

... 以及回到 2013 年 2 月的所有月份。数据透视表中月份内的行是当前月份的 DACP_Value。

我是 SQL 新手,所以希望您能提供帮助 :) 谢谢。

4

2 回答 2

1

从有限的样本数据中很难判断是否DACP_Id会重复多行和多日期。但是如果你想要PIVOT一个未知数量的日期或者可以随时更改的日期,那么你将需要使用动态 SQL。

您的代码将与此类似:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(DateName(month, DACP_date) +'_'+cast(Datepart(year, DACP_Date) as varchar(10))) 
                    from yourtable  
                    group by Datepart(month, DACP_date), Datepart(year, DACP_Date), DACP_date
                    order by DACP_date
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
    = 'select DACP_id, '+@cols+'
       from
       (
         select DACP_id, 
            DateName(month, DACP_date) +''_''+cast(Datepart(year, DACP_Date) as varchar(10)) date, 
            DACP_Value 
         from yourtable
       ) p
       pivot
       (
          sum(DACP_Value)
          for date in('+@cols+')
       ) piv'

execute(@query)

请参阅带有演示的 SQL Fiddle

正如您从演示中看到的那样,您会在该月获得多行,这是因为DACP_ID样本数据中的 是不同的。但这将是您在不提前知道值的情况下进行调整的方式。

于 2013-02-01T12:01:07.430 回答
0

我倾向于不使用动态枢轴,并处理应用程序代码中的标头:

WITH Data AS
(   SELECT  DACP_ID,
            DACP_Value,
            [MonthNum] = 12 - DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP)
    FROM    T
    WHERE   DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP) BETWEEN 0 AND 12
)   
SELECT  *
FROM    Data
        PIVOT
        (   SUM(DACP_Value)
            FOR MonthNum IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
        ) pvt;

如果您真的需要 Columns 标题,请使用:

DECLARE @Col NVARCHAR(MAX) = 
    (   SELECT  ', ' + QUOTENAME(CONVERT(VARCHAR, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - (12 - Number), 0), 112)) + ' = [' + CAST(number AS VARCHAR) + ']'
        FROM    Master..spt_values
        WHERE   Type = 'P'
        AND     number BETWEEN 0 AND 12
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)');


DECLARE @SQL NVARCHAR(MAX) = 
        N'WITH Data AS
        (   SELECT  DACP_ID,
                    DACP_Value,
                    [MonthNum] = 12 - DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP)
            FROM    T
            WHERE   DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP) BETWEEN 0 AND 12
        )   
        SELECT  DACP_ID' + @Col + '
        FROM    Data
                PIVOT
                (   SUM(DACP_Value)
                    FOR MonthNum IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
                ) pvt;';

EXECUTE SP_EXECUTESQL @SQL;

您可以112在将日期转换为 varchar 为各种数字时更改该值,以更改列标题中日期的格式(如问题中所述,103 将为您提供 dd/mm/yyyy)。


SQL Fiddle(无耻地从@bluefeet 那里偷来,他打败了我的答案)。我在这里留下了这个答案,因为它略有不同,因为它将提供 13 列(去年和当前月份),无论表中是否存在该月的数据。

于 2013-02-01T12:04:10.860 回答