日历2019全年日历表

介绍 (Introduction)

There is a common need in reporting to aggregate or return data that is crunched based on date attributes. These may include weekdays, holidays, quarters, or time of year. While any of this information can be calculated on the fly, a calendar table can save time, improve performance, and increase the consistency of data returned by our important reporting processes. In my previous article, you could learn about designing of a calendar table.

在报告中普遍需要聚合或返回基于日期属性处理的数据。 这些可能包括工作日,节假日,季度或一年中的时间。 尽管可以即时计算任何此类信息,但日历表可以节省时间,提高性能并提高我们重要报告流程返回的数据的一致性。 在我的上一篇文章中 ,您可以了解有关日历表设计的知识。

实施日历表 (Implementing a Calendar Table)

When the design process for a calendar table is complete, we can begin creating our date-related data. In this article, we will run through the remaining TSQL needed to create rows in Dim_Date, add holiday metrics, and demo a few uses of the data. As has been the theme thus far, creativity, flexibility, and customization are key to making this a success. Only use data elements you need, and feel free to add more as needed.

日历表的设计过程完成后,我们可以开始创建与日期相关的数据。 在本文中,我们将遍历在Dim_Date中创建行,添加假日指标并演示数据的一些使用所需的其余TSQL。 作为迄今为止的主题,创造力,灵活性和定制性是成功实现这一目标的关键。 仅使用所需的数据元素,并随时根据需要添加更多元素。

At this point, let’s create a row in Dim_Date for the current date being processed:

此时,让我们在Dim_Date中为当前正在处理的日期创建一行:


INSERT INTO dbo.Dim_Date(Calendar_Date, Calendar_Date_String, Calendar_Month, Calendar_Day, Calendar_Year,
Calendar_Quarter, Day_Name, Day_of_Week, Day_of_Week_in_Month, Day_of_Week_in_Year,
Day_of_Week_in_Quarter, Day_of_Quarter, Day_of_Year, Week_of_Month, Week_of_Quarter, Week_of_Year,
Month_Name, First_Date_of_Week, Last_Date_of_Week, First_Date_of_Month, Last_Date_of_Month,
First_Date_of_Quarter, Last_Date_of_Quarter, First_Date_of_Year, Last_Date_of_Year, Is_Holiday,
Is_Holiday_Season, Holiday_Name, Holiday_Season_Name, Is_Weekday, Is_Business_Day,
Previous_Business_Day, Next_Business_Day, Is_Leap_Year, Days_in_Month)SELECT@Date_Counter AS Calendar_Date,@Calendar_Date_String AS Calendar_Date_String,@Calendar_Month AS Calendar_Month,@Calendar_Day AS Calendar_Day,@Calendar_Year AS Calendar_Year,@Calendar_Quarter AS Calendar_Quarter,@Day_Name AS Day_Name,@Day_of_Week AS Day_of_Week,@Day_of_Week_in_Month AS Day_of_Week_in_Month,@Day_of_Week_in_Year AS Day_of_Week_in_Year,@Day_of_Week_in_Quarter AS Day_of_Week_in_Quarter,@Day_of_Quarter AS Day_of_Quarter,@Day_of_Year AS Day_of_Year,@Week_of_Month AS Week_of_Month,@Week_of_Quarter AS Week_of_Quarter,@Week_of_Year AS Week_of_Year,@Month_Name AS Month_Name,@First_Date_of_Week AS First_Date_of_Week,@Last_Date_of_Week AS Last_Date_of_Week,@First_Date_of_Month AS First_Date_of_Month,@Last_Date_of_Month AS Last_Date_of_Month,@First_Date_of_Quarter AS First_Date_of_Quarter,@Last_Date_of_Quarter AS Last_Date_of_Quarter,@First_Date_of_Year AS First_Date_of_Year,@Last_Date_of_Year AS Last_Date_of_Year,0 AS Is_Holiday,0 AS Is_Holiday_Season,NULL AS Holiday_Name,NULL AS Holiday_Season_Name,@Is_Weekday AS Is_Weekday,@Is_Business_Day AS Is_Business_Day, -- Will be populated with weekends to start.NULL AS Previous_Business_Day,NULL AS Next_Business_Day,@Is_Leap_Year AS Is_Leap_Year,@Days_in_Month AS Days_in_MonthSELECT @Date_Counter = DATEADD(DAY, 1, @Date_Counter);
END

Here we insert a row into our calendar table, increment @Date_Counter, and go back to the start of our loop. Some columns are left NULL intentionally, as we will be populating them below. Holidays and business days can be calculated in a set-based fashion once all of our other data has been inserted into the calendar table.

在这里,我们在日历表中插入一行,递增@Date_Counter ,然后返回到循环的开始。 有些列有意保留为NULL,因为我们将在下面填充它们。 一旦我们所有其他数据都已插入日历表,就可以基于集合的方式计算假日和工作日。

Holiday calculations are completely up to you. Include whatever holidays are relevant, needed for reporting, or helpful in understanding business activity. If holidays are not needed then you may leave out those columns, as well as much of the remaining code in this article. For the examples below, we’ve included wide variety of holidays that are calculated in different ways. For example, President’s day is on the 3rd Monday in February, which can be determined using the month (2), day of week (Monday), and day-of-week-in-month (3). Alternatively, US independence day is simple as it can be determined using only the month (7) and day (4).

假期的计算完全取决于您。 包括与报告有关或需要的假日,或有助于理解业务活动的任何假日。 如果不需要放假,则可以忽略这些列以及本文中其余的大部分代码。 对于下面的示例,我们包含了各种假日,这些假日以不同的方式计算。 例如,总统的日子是在3 星期一在二月,这可以使用一个月(2),星期几(星期一)来确定,以及(3)周在一个月中某一天的。 另外,美国独立日很简单,因为它可以仅使用月份(7)和日期(4)确定。

 -- New Year's Day: 1st of JanuaryUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'New Year''s Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 1AND Dim_Date.Calendar_Day = 1AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Martin Luther King, Jr. Day: 3rd Monday in January, beginning in 1983UPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Martin Luther King, Jr. Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 1AND Dim_Date.Day_of_Week = 2AND Dim_Date.Day_of_Week_in_Month = 3AND Dim_date.Calendar_Year >= 1983AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- President's Day: 3rd Monday in FebruaryUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'President''s Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 2AND Dim_Date.Day_of_Week = 2AND Dim_Date.Day_of_Week_in_Month = 3AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Valentine's Day: 14th of FebruaryUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Valentine''s Day'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 2AND Dim_Date.Calendar_Day = 14AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Saint Patrick's Day: 17th of MarchUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Saint Patrick''s Day'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 3AND Dim_Date.Calendar_Day = 17AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Mother's Day: 2nd Sunday in MayUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Mother''s Day'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 5AND Dim_Date.Day_of_Week = 1AND Dim_Date.Day_of_Week_in_Month = 2AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Memorial Day: Last Monday in MayUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Memorial Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 5AND Dim_Date.Day_of_Week = 2AND Dim_Date.Day_of_Week_in_Month = (SELECT MAX(Dim_Date_Memorial_Day_Check.Day_of_Week_in_Month) FROM dbo.Dim_Date Dim_Date_Memorial_Day_Check
WHERE Dim_Date_Memorial_Day_Check.Calendar_Month = Dim_Date.Calendar_Month                                             AND
Dim_Date_Memorial_Day_Check.Day_of_Week = Dim_Date.Day_of_WeekAND
Dim_Date_Memorial_Day_Check.Calendar_Year = Dim_Date.Calendar_Year)AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Father's Day: 3rd Sunday in JuneUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Father''s Day'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 6AND Dim_Date.Day_of_Week = 1AND Dim_Date.Day_of_Week_in_Month = 3AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Independence Day (USA): 4th of JulyUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Independence Day (USA)',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 7AND Dim_Date.Calendar_Day = 4AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Labor Day: 1st Monday in SeptemberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Labor Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 9AND Dim_Date.Day_of_Week = 2AND Dim_Date.Day_of_Week_in_Month = 1AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Columbus Day: 2nd Monday in OctoberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Columbus Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 10AND Dim_Date.Day_of_Week = 2AND Dim_Date.Day_of_Week_in_Month = 2AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Halloween: 31st of OctoberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Halloween'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 10AND Dim_Date.Calendar_Day = 31AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Veteran's Day: 11th of NovemberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Veteran''s Day',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 11AND Dim_Date.Calendar_Day = 11AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Thanksgiving: 4th Thursday in NovemberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Thanksgiving',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 11AND Dim_Date.Day_of_Week = 5AND Dim_Date.Day_of_Week_in_Month = 4AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Election Day (USA): 1st Tuesday after November 1st, only in even-numbered years.  Always in the range of November 2-8.UPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Election Day (USA)'FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 11AND Dim_Date.Day_of_Week = 3AND Dim_Date.Calendar_Day BETWEEN 2 AND 8AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;-- Christmas: 25th of DecemberUPDATE Dim_dateSET Is_Holiday = 1,Holiday_Name = 'Christmas',Is_Business_Day = 0FROM dbo.Dim_dateWHERE Dim_Date.Calendar_Month = 12AND Dim_Date.Calendar_Day = 25AND Dim_date.Calendar_Date BETWEEN @Start_Date AND @End_Date;

Note that each holiday definition not only designates and names a holiday, but adjusts Is_Business_Day accordingly. This allows us to determine for each holiday whether it is a business day (do nothing) or not (set it to zero). We also constrain holiday assignments to the date range provided in the stored procedure parameters.

请注意,每个假日定义不仅指定和命名假日,而且会相应地调整Is_Business_Day 。 这使我们能够确定每个假期是否是工作日(不做任何事情)(不设零)。 我们还将假期分配限制为存储过程参数中提供的日期范围。

Also note that these are all of the literal holidays as they are defined. Oftentimes, holidays that happen to fall on weekends will have an observed national holiday on Monday. This is not accounted for here, but could easily be adjusted for later on if needed. For example, we could search the table for any instances of Christmas that fall on Saturday or Sunday and immediately change the holiday to be on Monday, and append “Observed” to the holiday name. It’s an extra step that could be applied in a set-based fashion to any group of holidays, incrementing 2 days if Saturday and 1 day if Sunday.

还要注意,这些都是定义的所有文字假日。 通常,恰逢周末的假期在星期一有一个法定的国定假日。 这在这里没有考虑,但是可以根据需要轻松进行调整。 例如,我们可以在表格中搜索星期六或星期日的圣诞节实例,然后立即将假日更改为星期一,并在假日名称后附加“ Observed”。 这是一个额外的步骤,可以套用方式套用到任何一组假期,如果星期六则增加2天,星期日则增加1天。


WITH CTE_Business_Days AS (SELECTBusiness_Days.Calendar_DateFROM dbo.Dim_Date Business_DaysWHERE Business_Days.Is_Business_Day = 1
)
UPDATE Dim_Date_CurrentSET Previous_Business_Day = CTE_Business_Days.Calendar_Date
FROM dbo.Dim_Date Dim_Date_Current
INNER JOIN CTE_Business_Days
ON CTE_Business_Days.Calendar_Date = (SELECT MAX(Previous_Business_Day.Calendar_Date) FROM CTE_Business_Days Previous_Business_DayWHERE Previous_Business_Day.Calendar_Date < Dim_Date_Current.Calendar_Date)
WHERE Dim_Date_Current.Calendar_Date BETWEEN @Start_Date AND @End_Date;
WITH CTE_Business_Days AS (SELECTBusiness_Days.Calendar_DateFROM dbo.Dim_Date Business_DaysWHERE Business_Days.Is_Business_Day = 1
)
UPDATE Dim_Date_CurrentSET Next_Business_Day = CTE_Business_Days.Calendar_Date
FROM dbo.Dim_Date Dim_Date_Current
INNER JOIN CTE_Business_Days
ON CTE_Business_Days.Calendar_Date = (SELECT MIN(Next_Business_Day.Calendar_Date) FROM CTE_Business_Days Next_Business_DayWHERE Next_Business_Day.Calendar_Date > Dim_Date_Current.Calendar_Date)
WHERE Dim_Date_Current.Calendar_Date BETWEEN @Start_Date AND @End_Date;

With holidays and business days defined, we can use (somewhat messy) common table expressions to determine the previous and next business days. These calculations can be very useful in understanding how business reacts to the start or end of a streak of business days or non-business days. For example, does work pile up over long weekends, resulting in an influx of business on the next work day?

在定义了假日和工作日之后,我们可以使用(有些混乱)通用表表达式来确定上一个和下一个工作日。 这些计算对于理解业务如何对工作日或非工作日的开始或结束做出React非常有用。 例如,是否在漫长的周末增加了工作量,导致下一个工作日大量涌入业务?

Holiday seasons are another consideration that may be useful when determining how business reacts to the lead-up to a holiday, a season, or proximity to a holiday. For this example, we’ll populate the Christmas holiday season:

假日季节是另一个考虑因素,在确定企业对假日,季节或临近假日的准备情况有何React时可能会有用。 对于此示例,我们将填充圣诞节假期季节:

 WITH CTE_Thanksgiving AS (SELECTDim_date.Calendar_Date AS Thanksgiving_DateFROM dbo.Dim_dateWHERE Dim_date.Holiday_Name = 'Thanksgiving')UPDATE Dim_dateSET Is_Holiday_Season = 1FROM dbo.Dim_dateINNER JOIN CTE_ThanksgivingON DATEPART(YEAR, CTE_Thanksgiving.Thanksgiving_Date) = DATEPART(YEAR, Dim_date.Calendar_Date)WHERE (Dim_Date.Calendar_Month = 11 AND Dim_Date.Calendar_Date >= CTE_Thanksgiving.Thanksgiving_Date)OR (Dim_Date.Calendar_Month = 12 AND Dim_Date.Calendar_Day < 25);
END
GO

In this TSQL, we define Thanksgiving and use that date to create a sequence of dates between it and Christmas, which becomes our holiday season. Seasons can vary widely based on business needs, encompassing times of year, holidays, weather, or special events. If desired, we could add and populate a day of season column, in order to track how many days into a given season we are (or how many remain).

在此TSQL中,我们定义感恩节并使用该日期在圣诞节和圣诞节之间创建一个日期序列,该日期成为我们的假期。 季节会根据业务需求而变化很大,包括一年中的时间,节假日,天气或特殊事件。 如果需要,我们可以添加并填充“季节的一天”列,以跟踪给定季节中有多少天(或剩余多少天)。

That’s the end of the proc! Now, let’s test it out:

程序结束了! 现在,让我们对其进行测试:


EXEC dbo.Populate_Dim_Date@Start_Date = '1/1/2015', -- Start of date range to process@End_Date = '1/1/2030'; -- End of date range to process

This takes about seven seconds to run and generates 5480 rows of date data for our use. The results look like this:

运行大约需要七秒钟,并生成5480行日期数据供我们使用。 结果如下:

All scripts in this article are attached at the end to allow for easy tinkering. Feel free to download and modify to your heart’s content!

本文中的所有脚本都附在最后,以方便进行修补。 随时下载并修改您的内心内容!

客制化 (Customization)

A calendar table can be customized and adjusted to meet your business needs. If ¾ of these columns are unnecessary, then feel free to remove them. If there are additional metrics that are useful to your applications or reports, then feel free to add them! If a piece of data can be derived from a date, then it might be useful here.

可以自定义和调整日历表,以满足您的业务需求。 如果这些列中的¾是不必要的,请随时将其删除。 如果还有其他对您的应用程序或报告有用的指标,请随时添加它们! 如果可以从日期中导出一条数据,则在此处可能很有用。

The purpose of a calendar table is to improve the efficiency of reports or processes that require calculations to be made based on date components. In addition, we centralize the calendar data, which ensures consistency across any code that requires it. This is preferable to calculating these metrics on-the-fly every time we need them.

日历表的目的是提高需要基于日期成分进行计算的报告或流程的效率。 另外,我们集中了日历数据,以确保所有需要它的代码之间的一致性。 这比每次我们需要即时计算这些指标都更好。

性能 (Performance)

In our examples, we generated quite a few different columns, but you’re free to use as many or as few as makes sense for your application. This is a scenario in which there is no need to fear a wide table as most metrics will be relatively small (such as BIT, DATE, or TINYINT). Additionally, we have total control over the row count in a calendar table. For example, 75 years of data would result in a relatively lean 365 * 75 + 19 (27,394) rows of data (one row per date).

在我们的示例中,我们生成了很多不同的列,但是您可以随意使用对您的应用程序有意义的任意数量的列。 在这种情况下,由于大多数指标相对较小(例如BIT,DATE或TINYINT),因此无需担心表的宽度过大。 此外,我们可以完全控制日历表中的行数。 例如,75年的数据将导致相对精简的365 * 75 + 19(27,394)行数据(每个日期一行)。

This is a reporting table that we can add more rows to later at a future time. That being said, if we intentionally only include a few years, we need to remember to add more in the future, or reports may stop functioning correctly. In addition, for forecasting and predictive analytics, we may need to span many years in the future, even if our current data set does not extend that far. Of course, if we know for certain that we will never need data before or after any given date, then by all means include only the data that is needed.

这是一个报告表,我们以后可以在以后添加更多行。 话虽这么说,但如果我们有意只添加几年,则需要记住在将来添加更多内容,否则报告可能会无法正常运行。 此外,对于预测和预测分析,即使我们当前的数据集没有扩展那么多,我们仍可能需要跨越很多年。 当然,如果我们确定在任何给定日期之前或之后都不需要数据,则务必只包括所需的数据。

With regards to data types, be sure to choose the smallest possible types for a given column. DATE is preferable to DATETIME, BIT smaller than INT, and consider using TINYINT or SMALLINT instead of INT. For example, the day number within a given year will never be larger than 366 or smaller than 1, therefore a SMALLINT is more than enough for this column.

关于数据类型,请确保为给定的列选择最小的类型。 DATE优于DATETIME,BIT小于INT,并考虑使用TINYINT或SMALLINT代替INT。 例如,给定年份内的天数永远不会大于366或小于1,因此SMALLINT对于此列已绰绰有余。

在报表中使用日历表 (Using a Calendar Table in Reporting)

Using a calendar table optimally requires that we add a date key to reporting tables, index, and join the calendar table on that column. To test this, let’s use Sales.SalesOrderHeader in AdventureWorks:

最佳地使用日历表要求我们向报表表添加日期键,进行索引并在该列上联接日历表。 为了测试这一点,让我们在AdventureWorks中使用Sales.SalesOrderHeader


ALTER TABLE sales.SalesOrderHeader ADD Order_Date_Key AS CAST(OrderDate AS DATE);
CREATE NONCLUSTERED INDEX IX_SalesOrderHeader_Order_Date_Key ON sales.SalesOrderHeader(Order_Date_Key);

This creates a date key for joining om SalesOrderHeader and indexes it.

这将创建一个日期键以连接om SalesOrderHeader并为其建立索引。


SELECT*
FROM sales.SalesOrderHeader
INNER JOIN dbo.Dim_Date
ON SalesOrderHeader.Order_Date_Key = Dim_Date.Calendar_Date;

This returns no results (!?):

这将不返回任何结果(!?):

The calendar data we created spanned 2015 – 2030, but the data in SalesOrderHeader is older. As a result, our INNER JOIN returns no matches and we get nothing back. To resolve this, we’ll add more data to our calendar table:

我们创建的日历数据跨度为2015年至2030年,但SalesOrderHeader中的数据较旧。 结果,我们的INNER JOIN不返回任何匹配,并且我们什么也得不到。 要解决此问题,我们将向日历表添加更多数据:


EXEC dbo.Populate_Dim_Date@Start_Date = '1/1/2000', -- Start of date range to process@End_Date = '12/31/2014'; -- End of date range to process

This runs in about a second, and when we rerun our SELECT, we get results:

这大约需要一秒钟,当我们重新运行SELECT时,我们得到结果:

Now, let’s try out a few queries:

现在,让我们尝试一些查询:


SELECTSalesOrderHeader.TerritoryID,SUM(SalesOrderHeader.SubTotal) AS Sub_Total,COUNT(*) AS Number_of_Orders
FROM sales.SalesOrderHeader
INNER JOIN dbo.Dim_Date
ON SalesOrderHeader.Order_Date_Key = Dim_Date.Calendar_Date
WHERE Dim_Date.Holiday_Name = 'Christmas'
GROUP BY SalesOrderHeader.TerritoryID
ORDER BY SUM(SalesOrderHeader.SubTotal) DESC;

This tells us which territories were responsible for the most sales on Christmas, ordered by the most on top and fewest on the bottom:

这告诉我们哪些地区是圣诞节销售最多的地区,按顶部最多,底部最少的顺序排列:


SELECTDim_Date.Calendar_Month,SUM(SalesOrderHeader.SubTotal) AS Monthly_Order_Total,COUNT(*) AS Monthly_Order_Count
FROM sales.SalesOrderHeader
INNER JOIN dbo.Dim_Date
ON SalesOrderHeader.Order_Date_Key = Dim_Date.Calendar_Date
WHERE Dim_Date.Day_Name = 'Sunday'
GROUP BY Dim_Date.Calendar_Month
ORDER BY Dim_Date.Calendar_Month;

This query groups orders by month, so we can see which months have the most and fewest orders:

此查询按月对订单进行分组,因此我们可以查看哪个月的订单最多和最少:

These may seem like simple examples, but many reporting and analytics programs expect simple dimensions for consumption. Having the month number or day name is often required in order to perform any calculations using those columns. If we decide to take things further and crunch more complex uses of date components, then having the dimensions pre-calculated will save immense time and ensure that work is possible, let along efficient.

这些看似简单的示例,但是许多报告和分析程序希望使用简单的维度进行消费。 为了使用这些列执行任何计算,通常需要具有月份数字或日期名称。 如果我们决定更进一步,对日期分量进行更复杂的使用,那么预先计算尺寸将节省大量时间,并确保可以进行工作,并且效率很高。

结论 (Conclusion)

Calendar tables are extremely useful in any reporting, analytics, or even OLTP use case in which we need to frequently join data on data-related attributes. Not only can they greatly improve performance, but they simplify our code and allow reporting engines to consume that data with ease. As a bonus, we gain maintainability as we can retain a single copy of calendar data in one place. This reduces the likelihood of coding mistakes when operating on date data, especially when the calculations are complex.

日历表在任何报告,分析甚至OLTP用例中都非常有用,在这种情况下,我们需要频繁地将数据关联到与数据相关的属性上。 它们不仅可以极大地提高性能,而且可以简化我们的代码,并使报表引擎可以轻松使用该数据。 另外,由于可以将日历数据的一个副本保留在一个地方,因此我们具有可维护性。 这样可以减少对日期数据进行操作时出现编码错误的可能性,尤其是在计算复杂时。

One area of calendar tables that was intentionally omitted from this was alternate calendars. There are many uses for the ISO, 4-5-4, and a variety of fiscal calendars that can be joined into our standard calendar data. We’ll tackle this in a future article and build on the work we have completed here!

日历表中有意忽略的一个区域是备用日历。 ISO,4-5-4和多种会计日历有很多用途,可以将其加入我们的标准日历数据中。 我们将在以后的文章中解决这个问题,并在此基础上完成我们的工作!

Other articles in this series:

本系列的其他文章:

  • Designing a Calendar Table 设计日历表
  • Implementing Different Calendars in Reporting 在报表中实施不同的日历

参考资料和进一步阅读 (References and Further Reading)

  • Date and Time Data Types and Functions (Transact-SQL)日期和时间数据类型和函数(Transact-SQL)
  • Create a Date type Dimension创建日期类型维度
  • Data Types (Transact-SQL)数据类型(Transact-SQL)
  • Using Common Table Expressions使用公用表表达式

You can download all scripts in this article here.

您可以在此处下载本文中的所有脚本。

Always check your results and make sure that calendar data is correct. It’s easy to update and replace, so do not hesitate to apply sufficient scrutiny as this data is intended to be used in many places.

始终检查结果,并确保日历数据正确。 它很容易更新和替换,因此不要犹豫,进行足够的审查,因为该数据打算在许多地方使用。

翻译自: https://www.sqlshack.com/implementing-and-using-calendar-tables-2/

日历2019全年日历表

日历2019全年日历表_实施和使用日历表相关推荐

  1. mysql 日历表_如何创建mysql日历表

    本文主要向大家介绍了如何创建mysql日历表,通过具体的代码向大家展示,希望对大家学习mysql有所帮助. 首先我们先创建自己需要的日历表(先查询是否存在创建表):drop table if exis ...

  2. 日历2019日历备注_如何在Windows 10日历应用中使用Google日历

    日历2019日历备注 With the arrival of Windows 10, we've been greeted with a new slew of functionality-based ...

  3. 华米科技2019全年出货量达4230万台 营收增幅超五成

    [TechWeb]3月13日,华米科技(NYSE:HMI)发布了2019第四季度及全年财报.2019年四季度,公司营业收入达21.114亿元(合3.033亿美元),同比增幅为72.4%:调整后的净利润 ...

  4. miniui展示日历能点击_万物有时 节气日历 2020 | 预售

    凡事都有定期, 天下万务都有定时. 栽种有时,拔出所栽种的,也有时. 哭有时,笑有时.寻找有时,失落有时. 保守有时,舍弃有时.喜爱有时,恨恶有时. 争战有时,和好有时. -<传道书>- ...

  5. 京都计算机学院放假时间表,2019全年放假时间表

    原标题:2019全年放假时间表 期中考已经结束了,期末还会远吗?--而孩子们期盼的寒假也将来了! 根据教育局网站公布的南京市中小学生2018-2019学年度校历,南京市中小学生寒假时间:2019年1月 ...

  6. 2019日历全年一张_带上这份2019全年活动日历,旅行打卡不迷路

    1 月 January 上海双年展 始创于1996年的上海双年展是中国最具影响力的国际当代艺术展之一.本届双年展的主题为"禹步",这一主题源于中国古代神话的神秘步伐.本届上海双年展 ...

  7. 电力行业信息系统安全等级保护基本要求_重磅 | 国家标准电力信息系统安全等级保护实施指南将于2019年7月实施(附全文)...

    近日获悉,国家标准<电力信息系统安全等级保护实施指南> 将于2019年7月起实施.据了解,本标准由国家能源局提出,由全国电力监管标准化技术委员会(SAC/TC296)归口. 本标准起草单位 ...

  8. php如何生成一年的日历表_使用php动态生成一个日历,附源码。【简单实用】

    日历在web开发中是非常常用的一个功能,网上搜也能找到一大堆日历组件,大部分是js组件. 因为再开发过程中需要使用到日历的功能,又不想下载什么日历组件.所以就自己动手写了一个简单的php生成日历的功能 ...

  9. java jsp中的日历表_用JSP实现一个日历程序

    出处:http://www.chinabs.net/webj2ee/default.asp?infoid=257 String month; %> year =request.getParame ...

最新文章

  1. GNU/LINUX(KaliUbuntu)安装chrome浏览器
  2. firefox 3.0 在 windows 下的编译
  3. 苹果汽车自动驾驶又出新信号:正与多家激光雷达供应商谈判
  4. ansys里面自带chemkin_ANSYS CHEMKINPRO复杂化学反应快速仿真
  5. discuz常用操作说明
  6. ubuntu16.04安装及卸载anaconda3
  7. 我的2014--菜鸟慢慢在长大
  8. Microsoft Word2010 中设置和取消英文首字母大写
  9. 漫画研发之九:浑水好摸鱼
  10. APISpace 通用文字识别OCR API
  11. Fer2013表情识别Group_Project_Document
  12. Google Cardboard
  13. RPC框架Kitex入门
  14. php怎么切取部分歌曲,怎么把歌曲里的某一段剪切出来-歌曲怎么剪切,音频剪切软件...
  15. 集成学习方法及应用,破解AI实践难题
  16. 【读论文】RFN-Nest: An end-to-end residual fusion network for infrared and visible images
  17. nginx 禁止恶意域名解析
  18. Win11提示Windows无法访问指定设备路径或文件的三种解决方法
  19. PHP表单处理的案例分析
  20. 对Halting Problem的漂亮解释

热门文章

  1. python字典应用实例_Python中的字典应用实例
  2. python二十四点_python实现24点游戏(地球上最短的24点游戏代码?)
  3. linux中cat、more、less命令区别详解
  4. C++变量作用域、生存期、存储类别
  5. React Native按钮详解|Touchable系列组件使用详解
  6. 追梦软件路,愿不忘初心
  7. 实验四_078_刘玲志
  8. 初解vue脚手架vue-cli,及demo示例(一)
  9. Guacamole 介绍以及架构
  10. 创建你的第一个游戏Pong——让我们编写Pong