使用财务周期创建报表

Createing a report using financial periods

我已经为管理层创建了一份报告,它将在一个日期范围内按月汇总所有内容。管理层现在决定,他们更愿意按期间而不是按月。我们一年有 13 个时期,每个时期是 28 天,除了最后一个时期是 29 或 30,这取决于它是否是闰年。第一个周期的开始总是 1-1-YYYY。所以现在我需要弄清楚每个时期的开始和结束是什么,然后把每个时期加起来。我不太确定该怎么做,因为每年的日期都会改变,他们可能想查看从上一年到当前期间的各个时期。附上我目前使用的代码和结果

SELECT 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, finspecteddate), 0) AS 'Date' 
    ,COUNT(*) AS Lots
    ,sum(flotSize) as 'Lot Size'
    ,sum(LReject) 'Lots Rejected'
    ,sum(fnumreject) as Rejected
    ,sum(fsampleSize) as 'Sample Size'
    ,sum(BDueDate) as 'Before Due Date'
FROM 
    ReportData
WHERE 
    finspecteddate >= '01-01-2014' 
    AND finspecteddate <= '10-15-2014' 
GROUP BY 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, finspecteddate), 0) 
ORDER BY 
    date

如果您还没有,请创建一个包含年份、期间编号、开始日期和结束日期列的期间日历 table。那么需要引用句点的时候,可以引用table。当他们改变句号的定义时,你可以改变table。当他们决定 2 月 29 日不算作 28 天之一时,您可以更改 table。当他们决定使用第一个星期一而不是第一个星期四作为一年的开始时,您只需更改 table。最重要的是,改变明年的运作方式不会改变去年的运作方式。

那你就加入table来确定你在哪个时期。

修改以下查询以满足您的需要:

;WITH Period AS (
    SELECT      1 AS ReportingPeriod,
                CAST('2013-01-01' AS datetime) AS PeriodStartDate,
                CAST('2013-01-28' AS datetime) AS PeriodEndDate
    UNION ALL
    SELECT      CASE
                    WHEN p.ReportingPeriod = 13 THEN 1
                    ELSE p.ReportingPeriod + 1
                END,
                CASE
                    WHEN p.ReportingPeriod = 13 THEN DATEADD(YEAR,YEAR(p.PeriodStartDate)-1899,'1900-01-01')
                    ELSE DATEADD(DAY,28,p.PeriodStartDate)
                END,
                CASE
                    WHEN p.ReportingPeriod = 12 THEN DATEADD(YEAR,YEAR(p.PeriodStartDate)-1900,'1900-12-31')
                    ELSE DATEADD(DAY,28,p.PeriodEndDate)
                END
    FROM        Period p
    WHERE       p.PeriodStartDate < '2017-12-03'
)

SELECT 
    P.PeriodStartDate
    ,P.PeriodEndDate
    ,COUNT(*) AS Lots
    ,sum(flotSize) as 'Lot Size'
    ,sum(LReject) 'Lots Rejected'
    ,sum(fnumreject) as Rejected
    ,sum(fsampleSize) as 'Sample Size'
    ,sum(BDueDate) as 'Before Due Date'
FROM 
    ReportData  R
INNER JOIN Period P ON R.finspecteddate >= P.PeriodStartDate AND R.finspecteddate <= P.PeriodEndDate
WHERE 
    finspecteddate >= '01-01-2014' 
    AND finspecteddate <= '10-15-2014' 
GROUP BY 
    P.PeriodStartDate
    ,P.PeriodEndDate
ORDER BY 
    P.PeriodStartDate

它使用递归 CTE 构建一个周期 table,然后将其连接到 ReportData 以根据您的要求进行聚合。我没有 SQL Server 2005 来测试它。它适用于 2008。Post SQL Fiddle 如果你在 2005 需要帮助。