在日历中保存年月日有用吗Table

Is it useful to save Year, Month and Date in the Calendar Table

我正在使用日历 table 来保存日期信息。 table 我的初步目的是确定工作日和休假日(包括周末和节假日)。 table 中的字段是

使用年、月和日字段起初似乎很有用,尤其是设置假期,但事后看来我想我可以只使用 DATEPART(yyyy, [Date]) 来获取年以及类似的月和日。这些字段还有任何其他用途吗?

如果性能是一个因素,那么影响有多大?日历 table 只有 100 年的数据,即 ~36,500 条记录,一些叶子可以为所有 100 年预置,一些每年落在不同日期(~5 条记录)的叶子可以每年设置一次.考虑性能差异是否值得?

总结

使用单独的字段来保存年月日信息有什么用吗?性能差异是否大到足以被打扰?

编辑 1

从执行计划来看,我什至没有看到任何性能差异,所以主要是这些字段还有其他用途吗?

编辑 2

有些人似乎误解了这个问题。我的问题不是如何创建日历 table 或对日历中字段的看法 table。我的问题是,是否 ANY 使用了 [Year][Month][Day] 字段。

我已经经历了这种过程的几个不同的迭代,这就是我过去实现它的方式。

这是一个起点。在每场比赛中,停止处理进一步的规则。

  • 如果是星期六,就是周末。
  • 如果是星期天,就是周末。
  • 如果是 1 月 1 日,则为假期(元旦)。
  • 如果是 1 月 2 日并且是星期一,则为假期(庆祝元旦)。
  • 如果是一月的第三个星期一,则为假期(MLK Day)。
  • 如果是二月的第三个星期一,则为假期(总统日)。
  • 如果是五月的最后一个星期一,则为假期(阵亡将士纪念日)。
  • 如果 7 月 3 日是星期五,则为假期(庆祝独立日)。
  • 如果是 7 月 4 日,则为假期(独立日)。
  • 如果 7 月 5 日是星期一,则为假期(独立日)。
  • 如果是 9 月的第一个星期一,则为假期(劳动节)。
  • 如果是10月的第2个星期一,则为节假日(哥伦布纪念日)。
  • 如果 11 月 10 日是星期五,则为假期(纪念退伍军人节)。
  • 如果是 11 月 11 日,则为假期(退伍军人节)。
  • 如果 11 月 12 日是星期一,则为假期(庆祝退伍军人节)。
  • 如果是11月的第四个星期四,则为假期(感恩节)。
  • 如果是 11 月的第 4 个星期五并且不是 11 月 22 日,则为假期(黑色星期五)。
  • 如果 11 月 29 日是星期五,则为假期(黑色星期五)。
  • 如果 12 月 24 日是星期五,则为假期(平安夜)。
  • 如果是 12 月 25 日,则为假期(圣诞节)。
  • 如果 12 月 26 日是星期一,则为假期(节礼日)。
  • 如果是 12 月 31 日,并且是星期五,则为假期(除夕夜)。
  • 如果满足上述条件中的none,则为工作日。

通过这种方式,您可以遍历规则并识别工作日、周末和节假日。您可以使用这些字段存储这些规则:

  • 月份
  • 一个月中的第几天
  • 星期几
  • 周数
  • 年份

算法的工作原理如下。

  • 如果[Year] > 0,则此规则只影响当年的日期;否则,无论年份如何,此规则均有效。
  • 如果[Month] > 0,则此规则只影响该月的日期;否则,无论月份如何,此规则均有效。
  • 如果 [Day Of Month] > 0 AND [Day of Week] == 0,则此规则会影响当月那天的日期。
  • 如果 [Day of Month] == 0 AND [Day of Week] > 0,则此规则会影响一周中那一天的日期。
  • 如果 [Day of Month] == 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6,此规则会影响 [Day of Week][Week Number] 基数实例。例如,如果 [Day of Week] = @Monday[Week Number] = 1,则此规则会影响该月的第一个星期一。
  • 如果 [Day of Month] > 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6,则此规则影响 [Day of Week] 落在 [Day of Month] 或之后的 [Week Number] 个基数实例;如果 [Day of Week][Week Number] 个基数实例落在 [Day of Month] 之前,则此规则会影响 [Day of Week][Week Number] + 1 个基数实例。我把这个介绍给了黑色星期五的算法。
  • 如果 [Day of Month] == 0 AND [Day of Week] > 0 AND [Week Number] == 6,则此规则会影响一个月内 [Day of Week] 的最后一个实例。

使用此算法和这 22 条规则,您不必为所有内容都存储一个条目。这将涵盖您的所有 U.S。一个世纪的联邦假期。您可以添加带有确切日期的请假条目 ([Year][Month][Day of Month])。

日历表很小。正如您所指出的,即使您明确存储年份和月份,您所谈论的存储容量也可以覆盖 100 年。行宽不是问题。

如果您保留它们,请将它们设为计算列以强制与 [date] 保持一致。如果您希望它们也物理存在,请将它们设为持久计算列。

CREATE TABLE Calendar (
  [date] date NOT NULL PRIMARY KEY
 ,[year]  AS ISNULL(DATEPART(year,[date]),0)
 ,[month] AS ISNULL(DATEPART(month,[date]),0)
 ,[day]   AS ISNULL(DATEPART(day,[date]),0)
 ,[type] int NOT NULL DEFAULT 0
)

DECLARE @date_from date = '2000-01-01'
DECLARE @date_to   date = '2099-12-31'

INSERT Calendar ([date])
SELECT TOP(1+DATEDIFF(day,@date_from, @date_to))
  DATEADD(day,ROW_NUMBER() OVER(ORDER BY (SELECT 1))-1,@date_from)
FROM master.dbo.spt_values a, master.dbo.spt_values b