一百万种方法可以做到这一点,在我的大多数系统中,我都有一个日期维度表,用于报告和其他各种我想按各种日期标准过滤的东西。您可以使用 MSSQL 的 DATEPART 和 DATENAME 函数轻松构建这样的表。
示例脚本(这是我的一些旧代码):
-- =============================================
-- Build Dimension Date Table
-- =============================================
DECLARE @StartDate as smalldatetime, @EndDate as smalldatetime
SET @StartDate = '04/01/2010'
SET @EndDate = '03/31/2011'
BEGIN
SELECT
DATEPART(dy, @StartDate) as DAY_OF_YEAR,
CASE
WHEN DATENAME(qq,@StartDate)-1=0 THEN
4
ELSE
DATENAME(qq,@StartDate)-1
END AS FISCAL_PERIOD,
DATENAME(m,@StartDate) AS MONTH_DESC,
DATEPART(m,@StartDate) AS MONTH_NUM,
DATEPART(qq,@StartDate) AS QUARTER_NUM,
CONVERT(smalldatetime, CONVERT(CHAR(10),@StartDate,110)) AS SALES_DATE,
REPLACE(CONVERT(CHAR(10),@StartDate,06),' ','-') AS SALES_DATE_SPL,
DATEPART(yy,@StartDate) AS YEAR_NUM,
DATEPART(d,@StartDate) AS DAY_OF_MONTH,
CASE
WHEN DATEPART(m,@StartDate)< 4 THEN
DATENAME(yy,@StartDate)-1
ELSE
DATENAME(yy,@StartDate)
END AS FISCAL_YEAR,
CASE
WHEN DATEPART(m,@StartDate)>3 THEN
DATEPART(m,@StartDate)-3
ELSE
12-(3-DATEPART(m,@StartDate))
END AS FISCAL_MONTH
INTO OLAP_DATE_DIMENSION
SELECT @StartDate = @StartDate + 1
END
WHILE (@StartDate <= @EndDate)
BEGIN
BEGIN
INSERT INTO OLAP_DATE_DIMENSION SELECT
DATEPART(dy, @StartDate) as DAY_OF_YEAR,
CASE
WHEN DATENAME(qq,@StartDate)-1=0 THEN
4
ELSE
DATENAME(qq,@StartDate)-1
END AS FISCAL_PERIOD,
DATENAME(m,@StartDate) AS MONTH_DESC,
DATEPART(m,@StartDate) AS MONTH_NUM,
DATEPART(qq,@StartDate) AS QUARTER_NUM,
CONVERT(smalldatetime, CONVERT(CHAR(10),@StartDate,110)) AS SALES_DATE,
REPLACE(CONVERT(CHAR(10),@StartDate,06),' ','-') AS SALES_DATE_SPL,
DATEPART(yy,@StartDate) AS YEAR_NUM,
DATEPART(d,@StartDate) AS DAY_OF_MONTH,
CASE
WHEN DATEPART(m,@StartDate)< 4 THEN
DATENAME(yy,@StartDate)-1
ELSE
DATENAME(yy,@StartDate)
END AS FISCAL_YEAR,
CASE
WHEN DATEPART(m,@StartDate)>3 THEN
DATEPART(m,@StartDate)-3
ELSE
12-(3-DATEPART(m,@StartDate))
END AS FISCAL_MONTH
END
SELECT @StartDate = @StartDate + 1
END
获得所需数据后(可能加载 20 年,10 年,10 年向前和 10 年),您所要做的就是选择您想要的数据。由于您想要返回当前月份,因此我会查询 YEAR/MONTH = OLDEST DATE ALLOWED 的所有内容。
例子:
SELECT *
FROM OLAP_DATE_DIMENSION
WHERE SALES_DATE <= CONVERT(CHAR(10),GETDATE(),110))
AND DAY_OF_MONTH = '1'
ORDER BY SALES_DATE DESC;
** 这个针对上表的查询(这可能超出了您的需要),将返回今天之前表中每个月的每个月的第一天。然后,您可以利用各种日期部分创建一个漂亮的显示标签以显示在您的选择中(例如 2010 年 3 月、2010 年 2 月、2010 年 1 月等)。
希望这是有道理的,唯一的长期“维护”任务是使用额外年份的数据更新您的表格。由于每年只有 365 天,因此您可以真正加载大量数据,而对系统的影响很小。如果您的页面获得大量点击,您可以缓存结果,以便数据在内存中!