我已经为管理层创建了一份报告,该报告将在一个日期范围内按月累计所有内容。管理层现在已经决定,而不是按月计算,他们希望按期推迟。我们每年有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
答案 0 :(得分:1)
修改以下查询以满足您的需求:
;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来构建句点表,然后将其连接到ReportData
以根据您的要求进行汇总。我没有SQL Server 2005来测试它。它适用于2008年。如果你在2005年需要帮助,可以发布一个SQL小提琴。
答案 1 :(得分:0)
如果您还没有,请创建一个包含年份,期间号,开始日期和结束日期列的期间日历表。然后,当您需要参考期间时,您可以参考表格。当他们更改句点的定义时,您可以更改表格。当他们认为2月29日不算作28天之一时,您可以更改表格。当他们决定使用第一个星期一而不是第一个星期四作为年初时,您只需更改表格即可。最重要的是,改变明年的工作方式不会改变去年的工作方式。
然后,您只需加入表格即可确定您所处的时段。