最近进行周报相关的报表开发,需求如下:
- 对今年和去年的时间数据按周统计;
- 计算每周的上周开始时间,进行统计数据计算对应数据的环比;
- 计算每周去年同期开始时间,进行统计数据计算对应数据的同比;
- 每周四设为每周的第一天,按照今年的时间为标准;
首先看下实现的SQL:
SET DATEFIRST 3
SELECT DISTINCT
YEAR (ff.StartDate) AS YEAR,
weekCount,
StartDate,
CONVERT (
CHAR (10),
CASE
WHEN ff.weekCount = 53 THEN
DATEADD (DAY, 7, ff.StartDate)
ELSE
ff.EndDate
END,
120
) EndDate,
CONVERT (
CHAR (10),
DATEADD (WEEK, - 1, StartDate),
120
) StartDateLastWeek,
CONVERT (
CHAR (10),
DATEADD (yy, - 1, StartDate),
120
) AS StartDateLastYear,
CONVERT (
CHAR (10),
DATEADD (
yy,
- 1,
CONVERT (
CHAR (10),
CASE
WHEN ff.weekCount = 53 THEN
DATEADD (DAY, 7, ff.StartDate)
ELSE
ff.EndDate
END,
120
)
),
120
) AS EndDateLastYear
FROM
(
SELECT
DATEPART (WEEK, Date) AS weekCount,
MIN(Date) StartDate,
CONVERT (
CHAR (10),
DATEADD (
DAY,
(
SELECT
7 - (
SELECT
DATEPART (WEEKDAY, MIN(Date))
)
),
MIN(Date)
),
120
) AS EndDate
FROM
(
SELECT
Date
FROM
Repl_DJ_PerDay_Summary
WHERE
YEAR (Date) >= YEAR (DATEADD(yy, - 1, GETDATE()))
GROUP BY
Date
) ss
GROUP BY
DATEPART (WEEK, Date)
UNION ALL
SELECT
weekCount,
CONVERT (
CHAR (10),
DATEADD (yy, 1, StartDate),
120
) StartDate,
CONVERT (
CHAR (10),
DATEADD (yy, 1, EndDate),
120
) AS EndDate
FROM
(
SELECT
DATEPART (WEEK, Date) AS weekCount,
MIN(Date) StartDate,
CONVERT (
CHAR (10),
DATEADD (
DAY,
(
SELECT
7 - (
SELECT
DATEPART (WEEKDAY, MIN(Date))
)
),
MIN(Date)
),
120
) AS EndDate
FROM
(
SELECT
Date
FROM
Repl_DJ_PerDay_Summary
WHERE
YEAR (Date) >= YEAR (DATEADD(yy, - 1, GETDATE()))
GROUP BY
Date
) ss
GROUP BY
DATEPART (WEEK, Date)
) tt
) ff
WHERE
weekCount <> 1
ORDER BY
ff.StartDate,
weekCount;
逻辑:
- 设置DATEFIRST数据,周四作为一周的第一天(2020-01-02),并且作为一年的第一周;
- detepart函数没能实现跨年度的按周统计,使用了union all关联今年和去年的按周统计数据;
- 因为需要计算今年的去年的同比和环比,至少需要三年的数据,但是数据库中不一定只含有近两年的数据,按周统计只需要统计今年的去年的,对数据中的date做了一个处理,加了where条件,取近两年的时间跨度,时间YEAR (Date) >= YEAR (dateadd(yy ,- 1, getdate()));
- 计算每周的开始时间和结束时间;
- 计算每周的上周开始时间;
- 计算每周去年同期的开始时间和结束时间;
SQL执行结果如下: