日历报表

介绍 (Introduction)

There is a common need in reporting to aggregate or return data that is crunched based on date attributes. Calendars themselves can vary and provide differing insight into a business, data, and finance. They also assist in taking the intrinsically messy Gregorian calendar and making it easier to work with.

在报告中普遍需要聚合或返回基于日期属性处理的数据。 日历本身可以变化,并且可以提供对业务,数据和财务的不同见解。 它们还有助于获取本质上凌乱的格里高利历,并使其更易于使用。

所有关于公历 (All About the Gregorian Calendar)

Our most commonly used calendar is the Gregorian calendar. While very familiar to us, it is something that has grown organically over the course of millennia. As it evolved, no one considered modern financial reporting or data analytics needs that would be complicated by its structure.

我们最常用的日历是公历。 虽然对我们非常熟悉,但它在几千年的过程中有机地增长了。 随着它的发展,没有人认为现代财务报告或数据分析需求会因其结构而变得复杂。

For common everyday use, it is a fine calendar, but if our goal is to carefully analyze any data over time, then it has a variety of implicit shortcomings:

对于日常使用,这是一个很好的日历,但是如果我们的目标是随着时间的推移仔细分析任何数据,则它具有各种隐式缺点:

  • Months are not composed of the same number of days. They can have 28-31 days, making it difficult to compare one month to the next easily. 月不是由相同的天数组成。 他们可能有28-31天的时间,因此很难轻松地将一个月与下个月进行比较。
  • Months, quarters, and years can start on different weekdays, which can result in significant variations when comparing data year-to-year. 月份,季度和年份可以在不同的工作日开始,因此在逐年比较数据时可能会产生很大的差异。
  • The number of a given weekday in a month can vary. It’s possible for some months to contain 4 Mondays, while others have 5. 一个月中给定工作日的数量可以变化。 可能有几个月包含4个星期一,而另一些包含5个星期一。
  • The addition of a day for leap years does not significantly increase the length of the year, but does add a shift to dates for the remainder of the year that can affect year-to-year reporting in ways that do not occur in other years. leap年增加一天不会显着增加一年的长度,但是会增加该年剩余时间的日期偏移,这可能会影响其他年份的年度报告。
  • Common numbers used in math are 7, 28, 29, 30, 31, 365, and 366, which rarely result in clean or simple calculations. 数学中使用的常见数字是7、28、29、30、31、365和366,这些数字很少会导致干净或简单的计算。

These properties of our calendar are often tolerated and worked around, but can make our reporting efforts return data that is not as meaningful as it should be. For example, if the year starts on a Saturday, then the first week of the year contains one day, whereas it would contain seven days if it began on Sunday.

日历的这些属性通常是可以容忍的,并且可以解决,但是可以使我们的报告工作返回的数据不应该具有应有的意义。 例如,如果年份从星期六开始,则一年的第一周包含一天,而如果在星期日开始则包含7天。

The number of weekends in each month also vary, which for any business that has significantly higher or lower activity on weekends can also lead to inconsistent reporting. A business that sees 5% growth in March, but a 5% contraction in April would want those numbers to not be the result of calendar quirks, but instead actual events that require further examination.

每个月的周末数量也各不相同,这对于任何在周末活动量明显较高或较低的企业也可能导致报告不一致。 一家业务在3月增长5%,但在4月收缩5%的公司希望这些数字不是日历怪异的结果,而是需要进一步研究的实际事件。

In addition to these various inconveniences, not all countries use identical calendars. For example, much of the world has their weeks start on Monday, rather than Sunday. This may seem like a minor change, but it causes all calculations involving weeks to be adjusted. As a result, an event that occurs on a Sunday will belong to a different week in France than it would in the United States, and therefore would result in different metrics when broken down into weeks.

除了这些各种不便之外,并非所有国家/地区都使用相同的日历。 例如,世界上许多地方的星期从星期一开始,而不是星期日。 这似乎是一个很小的更改,但是它会导致涉及周数的所有计算都被调整。 结果,在周日发生的事件在法国与在美国属于不同的一周,因此将事件分解成几周后得出的度量标准也不同。

Lastly, businesses choose their own fiscal calendar, which may begin and end on a different set of months than our typical January-December calendar year. This can result in years beginning in July or October, and fiscal quarters beginning and ending similarly at any time of the year. There are many reasons why a company may want to start their calendar in a month besides January, such as the date of their founding, busy times of year, or to maintain consistency with the rest of their industry.

最后,企业选择自己的会计日历,该会计日历的开始和结束时间可以与典型的1月-12月日历年不同。 这可能导致年份从7月或10月开始,并且会计季度在每年的任何时候开始和结束。 公司可能要在除1月以外的一个月内启动日历的原因很多,例如成立日期,一年中的繁忙时间或与行业其他部分保持一致。

商家日历 (The Merchant Calendar)

The most common alternate calendar that is used when working with retail businesses is the Merchant Calendar. This calendar was first devised in the 1930s and breaks the year into more consistent time periods for months and quarters. Under the merchant (also known as the 4-5-4 calendar), each month contains 4 or 5 complete weeks. Each quarter contains three months, two with 4 months and one with 5 months.

与零售企业合作时,最常用的备用日历是商家日历。 该日历最早是在1930年代设计的,将一年分为几个月和几个季度的更一致的时间段。 在商家下(也称为4-5-4日历),每个月包含4或5个完整的星期。 每个季度包含三个月,两个为期四个月,一个为五个月。

Each year begins on a Sunday and ends on a Saturday, allowing any time period we analyze to have consistent data across weekdays. An upshot of this is that most holidays now occur in the same exact time period each year. This removes the complexity of an important business day occurring within different weeks.

每年开始于星期日,结束于星期六,这使我们分析的任何时间段在工作日内具有一致的数据。 结果是,大多数假期现在都在每年的相同确切时间段内发生。 这消除了在不同星期内发生的重要工作日的复杂性。

It is important to note that the merchant calendar is implemented differently by different businesses based on their activity over the course of the year. Many companies will commonly begin it in February, in an effort to completely encapsulate the end-of-year holidays in a single calendar year. Others choose to begin in July, October, or in January, depending on their business needs. For our work here, we will follow the recommendation of the National Retail Federation and begin it in February. Shifting the calendar to begin during other times of the year is relatively simple, and could benefit a business that is not retail-oriented, or has differing priorities and reporting needs.

重要的是要注意,商户日历是根据不同的企业在一年中的活动来不同地实施的。 许多公司通常会在2月开始它,以完全封装单个日历年中的年末假期。 其他人则根据他们的业务需求选择在7月,10月或1月开始。 对于我们在这里的工作,我们将遵循国家零售联合会的建议,并于2月开始实施。 将日历更改为在一年中其他时间开始比较简单,并且可以使非零售业务或优先级和报告需求不同的业务受益。

The following shows the first two months of the merchant calendar for 2017 – 2019. Note that the first day can consist of a day near the end of January or the beginning of February. This is based solely on the day of week the year begins on and is consistent from year-to-year.

下图显示了2017-2019年商户日历的前两个月。请注意,第一天可以包括1月底或2月初附近的一天。 这完全基于一年中开始的一周中的某天,并且每年都保持一致。

Note that each month of the year will always have the same number of weeks (4 or 5). For reference, it’s possible to calculate the first day of the merchant year as follows:

请注意,一年中的每个月始终具有相同的星期数(4或5)。 作为参考,可以如下计算商户年份的第一天:


DATEADD(DAY, 28 + CASE DATEPART(WEEKDAY, @First_Date_of_Year) WHEN 1 THEN 0 ELSE 8 - DATEPART(WEEKDAY, @First_Date_of_Year) END, @First_Date_of_Year);

This results in the start of the merchant year being on the Sunday closest to the start of February. The end of the year follows similarly:

这导致商人年度的开始在最接近2月初的星期日。 年末类似地:

The first eye-catching callout is the extra week in 2017-2018. As with any calendar that is constructed based on non-scientific methods, the year length does not fully account for the time it takes for Earth to revolve around the sun. As a result, we need to implement leap years every 6-7 years in order to ensure that the calendar does not continue to drift over time.

第一个引人注目的标注是2017-2018年的额外一周。 与任何基于非科学方法构造的日历一样,年份长度并不能完全说明地球绕太阳旋转所花费的时间。 因此,我们需要每6-7年执行一次leap年,以确保日历不会随着时间的推移而继续漂移。

Implementing a leap year is relatively simple: Add a week to the end of a year in which the first day would no longer be the closest Sunday to the start of February. This pushes the first day of the calendar to the correct day, but introduces a major complexity into the calendar in that about 15% of all years will have an entire extra week.

实施a年相对简单:在年末增加一个星期,其中第一天将不再是距二月初最近的星期日。 这将日历的第一天推到正确的日期,但给日历带来了很大的复杂性,因为所有年份中约15%的时间将整整一周。

Different businesses manage this extra week differently. Some simply include it as-is and will have occasional years/months/quarters with higher numbers. Others restate their calendar by removing the first week of the year (typically a slow business week) completely, and renumber all other weeks accordingly. It’s also acceptable to simply leave off the extra week from reporting as that final week is also a relatively slow business week in many industries.

不同的企业对这额外一周的管理方式不同。 有些只是按原样包含它,并且偶尔会有更高的数字的年份/月份/季度。 其他人则通过完全删除一年中的第一周(通常是缓慢的工作周)来重述日历,并相应地重新编号所有其他周。 也可以简单地将多余的一周时间从报告中删除,因为最后一周在许多行业中也是相对较慢的工作周。

All of these methods of implementing and restating the merchant calendar are accepted for GAAP use, and most other common accounting and business reporting practices.

GAAP以及大多数其他常见的会计和业务报告惯例均接受了所有实现和重新设置商家日历的方法。

We can create a number of columns within a calendar table that manage various merchant calendar metrics, similarly to how we create metrics based on the standard Gregorian calendar. Any variables here are either ones derived from the Gregorian calendar, or those we have already calculated below and are reusing. Here are the merchant calendar aspects we will work with in this example:

我们可以在日历表中创建许多列来管理各种商户日历指标,类似于我们基于标准公历创建指标的方式。 这里的任何变量要么是从公历中派生的变量,要么是我们已经在下面计算出并正在重用的变量。 这是在此示例中我们将使用的商户日历方面:

Merchant calendar: First day of year:

商家日历:一年的第一天:


DATEADD(DAY, 28 + CASE DATEPART(WEEKDAY, @First_Date_of_Year) WHEN 1 THEN 0 ELSE 8 - DATEPART(WEEKDAY, @First_Date_of_Year) END, @First_Date_of_Year);

Merchant calendar: First day of next year:

商家日历:明年第一天:


DATEADD(DAY, 28 + CASE DATEPART(WEEKDAY, @First_Date_of_Next_Year) WHEN 1 THEN 0 ELSE 8 - DATEPART(WEEKDAY, @First_Date_of_Next_Year) END, @First_Date_of_Next_Year);

Merchant calendar: First day of last year:

商家日历:去年第一天:


DATEADD(DAY, 28 + CASE DATEPART(WEEKDAY, @First_Date_of_Last_Year) WHEN 1 THEN 0 ELSE 8 - DATEPART(WEEKDAY, @First_Date_of_Last_Year) END, @First_Date_of_Last_Year);

It is worth noting that some of these values may not be needed explicitly in reporting, but do make our ability to populate additional metrics easier. Feel free to omit anything that you don’t find directly useful in your implementation. These calculations also reply on values we determined in previous articles (such as the first date of the year) and can be acquired fairly easily.

值得注意的是,在报告中可能不需要明确使用其中一些值,但确实使我们能够轻松填充其他指标。 随意忽略您在实现中没有直接用处的任何内容。 这些计算还可以根据我们在先前文章中确定的值(例如一年中的第一天)进行答复,并且可以很容易地获得。

If the date being processed happens to be before the beginning of the merchant calendar year, which will tend to happen when making calculations at the start of the year, we can adjust accordingly:

如果要处理的日期恰好在商户日历年的开始日期之前(通常会在当年年初进行计算时发生),我们可以相应地进行调整:


IF @Date_Counter < @Merchant_First_Date_of_Year
BEGINSELECT @Merchant_First_Date_of_Next_Year = @Merchant_First_Date_of_Year;SELECT @Merchant_First_Date_of_Year = @Merchant_First_Date_of_Last_Year;SELECT @Merchant_First_Date_of_Last_Year = DATEADD(DAY, 28 + CASE DATEPART(WEEKDAY, @First_Date_of_Two_Years_Ago) WHEN 1 THEN 0 ELSE 8 - DATEPART(WEEKDAY, @First_Date_of_Two_Years_Ago) END, @First_Date_of_Two_Years_Ago);
END

Merchant calendar last date of the year:

商家日历的最后日期:


DATEADD(DAY, -1, @Merchant_First_Date_of_Next_Year);

Merchant day of the year:

一年中的商家日期:


DATEADD(DAY, -1, @Merchant_First_Date_of_Next_Year);

Merchant week of the year:

一年中的商家周:


((@Merchant_Day_of_Year - 1) / 7) + 1;

Merchant calendar month:

商家日历月:


CASE -- 4-5-4 monthly scheduleWHEN @Merchant_Week_of_Year BETWEEN 1 AND 4 THEN 1 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 5 AND 9 THEN 2 -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 10 AND 13 THEN 3 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 14 AND 17 THEN 4 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 18 AND 22 THEN 5 -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 23 AND 26 THEN 6 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 27 AND 30 THEN 7 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 31 AND 35 THEN 8 -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 36 AND 39 THEN 9 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 40 AND 43 THEN 10 -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 44 AND 48 THEN 11 -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 49 AND 53 THEN 12 -- 4 weeks (5 weeks during 4-5-4 leap years, in which case we add the final week, 53, into a 4-5-5 month)
END;

Merchant calendar quarter:

商家日历季度:


CASEWHEN @Merchant_Calendar_Month BETWEEN 1 AND 3 THEN 1WHEN @Merchant_Calendar_Month BETWEEN 4 AND 6 THEN 2WHEN @Merchant_Calendar_Month BETWEEN 7 AND 9 THEN 3WHEN @Merchant_Calendar_Month BETWEEN 10 AND 12 THEN 4
END;

Is merchant leap year:

是商人leap年:


CASE DATEDIFF(DAY, @Merchant_First_Date_of_Year, @Merchant_Last_Date_of_Year)WHEN 363 THEN 0ELSE 1
END;

The merchant leap year is a unique concept when compared to our standard leap years, but can be calculated very easily at this point by finding the number of days in the year, which will either be 363 or 370, and adjust accordingly.

与我们的标准leap年相比,商户leap年是一个独特的概念,但此时可以很容易地计算出这一天,方法是查找一年中的天数(可以是363或370),并进行相应的调整。

Merchant first date of the month:

商家每月的第一天:


CASEWHEN @Merchant_Day_of_Year <= 28 THEN DATEADD(DAY, -1 * @Merchant_Day_of_Year + 1, @Date_Counter) -- Month 1 (Start)WHEN @Merchant_Day_of_Year BETWEEN 29 AND 63 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 28) + 1, @Date_Counter) -- Month 2 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 64 AND 91 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 63) + 1, @Date_Counter) -- Month 3 (5 weeks)WHEN @Merchant_Day_of_Year BETWEEN 92 AND 119 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 91) + 1, @Date_Counter) -- Month 4 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 120 AND 154 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 119) + 1, @Date_Counter) -- Month 5 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 155 AND 182 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 154) + 1, @Date_Counter) -- Month 6 (5 weeks)WHEN @Merchant_Day_of_Year BETWEEN 183 AND 210 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 182) + 1, @Date_Counter) -- Month 7 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 211 AND 245 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 210) + 1, @Date_Counter) -- Month 8 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 246 AND 273 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 245) + 1, @Date_Counter) -- Month 9 (5 weeks)WHEN @Merchant_Day_of_Year BETWEEN 274 AND 301 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 273) + 1, @Date_Counter) -- Month 10 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 302 AND 336 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - 301) + 1, @Date_Counter) -- Month 11 (4 weeks)
WHEN @Merchant_Day_of_Year >= 336 THEN DATEADD(DAY, -1 * (@Merchant_Day_of_Year - (CASE WHEN @Is_Merchant_Leap_Year = 0 THEN 336 ELSE 343 END)) + 1, @Date_Counter) -- Month 12 (5 weeks) through End of year (4 or 5 weeks, depending on 4-5-4 leap year status)
END;

Merchant last date of the month:

商家本月的最后日期:


CASEWHEN @Merchant_Week_of_Year BETWEEN 1 AND 4 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 5 AND 9 THEN DATEADD(DAY, 34, @Merchant_First_Date_of_Month) -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 10 AND 13 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 14 AND 17 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 18 AND 22 THEN DATEADD(DAY, 34, @Merchant_First_Date_of_Month) -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 23 AND 26 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 27 AND 30 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 31 AND 35 THEN DATEADD(DAY, 34, @Merchant_First_Date_of_Month) -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 36 AND 39 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 40 AND 43 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month) -- 4 weeksWHEN @Merchant_Week_of_Year BETWEEN 44 AND 48 THEN DATEADD(DAY, 34, @Merchant_First_Date_of_Month) -- 5 weeksWHEN @Merchant_Week_of_Year BETWEEN 49 AND 53 THEN CASE -- 4 weeks (5 weeks during 4-5-4 leap years, in which case we add the final week, 53, into a 4-5-5 month)WHEN @Is_Merchant_Leap_Year = 0 THEN DATEADD(DAY, 27, @Merchant_First_Date_of_Month)WHEN @Is_Merchant_Leap_Year = 1 THEN DATEADD(DAY, 34, @Merchant_First_Date_of_Month)END
END;

Merchant first date of the quarter:

季度的商家首个日期:


CASEWHEN @Merchant_Day_of_Year <= 91 THEN DATEADD(DAY, -1 * @Merchant_Day_of_Year + 1, @Date_Counter) -- Month 1 (Start)WHEN @Merchant_Day_of_Year BETWEEN 92 AND 182 THEN DATEADD(DAY, -1 * @Merchant_Day_of_Year + 92, @Date_Counter) -- Month 4 (4 weeks)WHEN @Merchant_Day_of_Year BETWEEN 183 AND 273 THEN DATEADD(DAY, -1 * @Merchant_Day_of_Year  + 183, @Date_Counter) -- Month 7 (4 weeks)WHEN @Merchant_Day_of_Year >= 274 THEN DATEADD(DAY, -1 * @Merchant_Day_of_Year + 274, @Date_Counter) -- Month 10 (4 weeks)
END;

Merchant last date of the quarter:

商家本季度的最后日期:


CASEWHEN @Merchant_Calendar_Quarter = 1 THEN DATEADD(DAY, 90, @Merchant_First_Date_of_Quarter)WHEN @Merchant_Calendar_Quarter = 2 THEN DATEADD(DAY, 90, @Merchant_First_Date_of_Quarter)WHEN @Merchant_Calendar_Quarter = 3 THEN DATEADD(DAY, 90, @Merchant_First_Date_of_Quarter)WHEN @Merchant_Calendar_Quarter = 4 THEN CASEWHEN @Is_Merchant_Leap_Year = 0 THEN DATEADD(DAY, 90, @Merchant_First_Date_of_Quarter)ELSE DATEADD(DAY, 97, @Merchant_First_Date_of_Quarter)END
END;

Merchant first date of the week:

商家的第一天:


DATEADD(DAY, -1 * ((DATEDIFF(DAY, @Merchant_First_Date_of_Month, @Date_Counter) % 7) + 1) + 1, @Date_Counter);

Merchant last date of the week:

商家一周的最后日期:


DATEADD(DAY, 6, @Merchant_First_Date_of_Week);

There are many other ways we can calculate these metrics. The queries presented are one way to do it, though in no way are superior or better than any others you might think up. In addition, you can determine any date part or date-related metric and add it to this data set with minimal effort.

我们还有许多其他方法可以计算这些指标。 提出的查询是执行此查询的一种方法,尽管它绝不会比您可能想到的任何其他查询更好或更好。 此外,您可以轻松确定任何日期部分或与日期相关的指标,并将其添加到此数据集中。

ISO日历 (The ISO Calendar)

Another attempt to normalize calendars and allow for easier reporting (especially internationally) is the ISO calendar. In this calendar, all weeks and years begin on Monday. A year will have 52 weeks a majority of the time, and 53 weeks when a leap year is required in order to keep the calendar in sync with the time of year.

ISO日历是对日历进行规范化并允许更轻松地报告(尤其是在国际范围内)的另一种尝试。 在此日历中,所有星期和年份均从星期一开始。 一年中的大部分时间将有52周,而需要year年以使日历与一年中的时间保持同步时,一年将有53周。

The first day of the ISO year always begins on the Monday of the week that contains January 4th, regardless of whether that date is part of the current Gregorian year or the previous one. This automatically controls leap years based on when this first week falls. The following is an illustration of the ISO calendar structure for 2016-2017:

ISO年份的第一天始终从包含1月4 的一周的星期一开始,无论该日期是当前格里高利历年的一部分还是上一年。 这会根据第一周的时间自动控制leap年。 以下是2016-2017年ISO日历结构的说明:

The horizontal axis shows the weekdays of the ISO calendar and the vertical axis shows the weeks. Since the calendar is uniform across days, weeks, and months, it can be structured as a grid. Note that the ISO calendar does not contain months—a date is comprised solely of a year, week, and day, without any further groupings. As a result, one way to write an ISO date is using the following notation: “2017-W5-3”. This indicates that it is ISO year 2017, week 5, day 3. Because of the uniformity, it is very easy to compare year-on-year metrics without the need for any significant adjustments.

横轴显示ISO日历的工作日,纵轴显示周。 由于日历在几天,几周和几个月内是统一的,因此可以将其构造为网格。 请注意,ISO日历不包含月份-日期仅由年,周和日组成,没有任何其他分组。 因此,一种写入ISO日期的方法是使用以下表示法:“ 2017-W5-3”。 这表明它是ISO年度2017,第5周,第3天。由于具有统一性,因此可以轻松比较年度指标,而无需进行任何重大调整。

The leap year may be accounted for in similar ways to the merchant calendar in that we may include it for completeness or remove a week to normalize to 52 weeks. There are no official standards for this adjustment, and this calendar is often presented as a method of achieving completeness and uniformity rather than directly conforming to specific business needs.

year年的计算方式与商家日历类似,因为我们可能出于完整原因将其包括在内,也可以删除一周以标准化为52周。 此调整没有官方标准,并且此日历通常被视为实现完整性和统一性的一种方法,而不是直接符合特定的业务需求。

We can calculate a handful of example metrics using the ISO calendar, as follows:

我们可以使用ISO日历来计算一些示例指标,如下所示:

ISO Week of Year:

每年的ISO周:


SELECT @ISO_Week_of_Year = DATEPART(ISO_WEEK, @Date_Counter);

We get the easy way out on this one and can use a SQL Server built-in function to determine the ISO week of year, which will save us some time and TSQL complexity later on!

我们可以轻松解决这一问题,并且可以使用SQL Server内置函数来确定一年中的ISO周,这将为我们节省一些时间和以后的TSQL复杂性!

ISO First Date of the Week:

ISO每周的第一个日期:


CASEDATEPART(WEEKDAY, @Date_Counter) = 2 THEN @Date_CounterWHEN DATEPART(WEEKDAY, @Date_Counter) = 1 THEN DATEADD(DAY, -6, @Date_Counter)ELSE DATEADD(DAY, -1 * (DATEPART(WEEKDAY, @Date_Counter) - 2), @Date_Counter)
END;

ISO Last Date of the Week:

ISO本周的最后日期:


DATEADD(DAY, 6, @ISO_First_Date_of_Week);

ISO Day of Week:

ISO星期几:


CASEWHEN DATEPART(WEEKDAY, @Date_Counter) = 1 THEN 7ELSE DATEPART(WEEKDAY, @Date_Counter) -1
END

ISO Day of Year:

ISO年度日期:


(@ISO_Week_of_Year - 1) * 7 + @ISO_Day_of_Week;

ISO Year:

ISO年:


CASEWHEN @Week_of_Year > 49 AND @ISO_Week_of_Year < 3 THEN @Calendar_Year + 1WHEN @Week_of_Year < 3 AND @ISO_Week_of_Year > 49 THEN @Calendar_Year - 1ELSE @Calendar_Year
END;

Note that the ISO year and Gregorian year may not match up. If the ISO year begins on December 28th, the year will be notated as the following year on the Gregorian calendar. For example, if the standard year ends on Tuesday, December 31, 2019, and the ISO year begins on Monday, December 30th, then the ISO year would be 2020, and not 2019.

请注意,ISO年和公历年可能不匹配。 如果ISO年份从12月28 开始,则该年份将在公历中标记为第二年。 例如,如果标准年在2019年12月31日星期二结束,而ISO年在12月30 星期一开始,则ISO年将是2020年而不是2019年。

ISO String:

ISO字串:


CAST(@ISO_Year AS VARCHAR(6)) + '-W' + CAST(@ISO_Week_of_Year AS VARCHAR(2)) + '-' + CAST(@ISO_Day_of_Week AS VARCHAR(1));

The ISO string is the standard way to display an ISO week, accounting for the ISO year, week, and day. There are many ways to refer to an ISO date, but this captures the three components necessary to allow us to quickly and easily understand the time of year and its meaning. While the day of year could also be used to determine both week and day of week, doing so would be challenging for a human that is not lightning fast (and accurate) with mental arithmetic.

ISO字符串是显示ISO星期的标准方法,说明ISO年,周和日。 引用ISO日期的方法有很多,但这捕获了使我们能够快速而轻松地了解一年中的时间及其含义的三个必要组成部分。 尽管一年中的某天也可以用于确定一周和一周中的某天,但对于用心算术不能快速(准确)闪电的人来说,这样做将是一个挑战。

In summary, the ISO calendar is a another way to normalize dates so that calendar structures are greatly simplified. By eliminating the need for months, and by ensuring that weeks and years start on the same day (Monday) and have consistent numbers of days (364 or 371), many calculations that are normally complex become trivial within this framework.

总之,ISO日历是标准化日期的另一种方法,因此可以大大简化日历结构。 通过消除对月份的需求,并确保数周和数年在同一天(星期一)开始并且具有一致的天数(364或371),在此框架内,许多通常很复杂的计算变得微不足道。

财政日历 (Fiscal Calendars)

Fiscal calendars can begin on January 1st and end on December 31st, but many businesses and agencies choose to shift the year-end to another time of year. For example, colleges often end their fiscal calendars over the summer, in conjunction with a quieter and more consistent time of year for their bookkeeping. The US government ends their fiscal year on September 30th. Retail organizations may choose to start their fiscal year in February in order to be sufficiently done with all of the previous end-of-year’s business.

会计日历可以从1月1 开始,到12月31 结束,但是许多企业和代理机构选择将年末转换为一年中的其他时间。 例如,大学通常会在夏季结束其财务日历,同时每年更安静,更一致地进行簿记。 美国政府于9月30 结束其会计年度。 零售组织可以选择从2月开始其会计年度,以便充分处理上一年度末的所有业务。

For the purpose of this demo, we’ll use a fiscal year that begins on October 1st and ends on September 30th. Many of our metrics do not change with a shift such as this. The only metrics that will need to be adjusted are those related to the quarter and year, while weeks and months will not change. Here are a few examples of what we’d expect to see when shifting a calendar to account for a different fiscal year:

就本演示而言,我们将使用从10月1 开始到9月30 结束的会计年度。 我们的许多指标不会随这种变化而变化。 唯一需要调整的指标是与季度和年度相关的指标,而几周和几个月不变。 以下是一些示例,这些示例期望在将日历转换为不同会计年度时看到的内容:

Fiscal First Date of the Year:

年度首个日期:


CASEWHEN @Calendar_Month IN (10, 11, 12) THEN DATEADD(DAY, -1 * @Day_of_Quarter + 1, @Date_Counter)ELSE DATEADD(DAY, -1 * @Day_of_Year - 91, @Date_Counter)
END

Fiscal Last Date of the Year:

财政年度的最后日期:


DATEADD(DAY, -1, DATEADD(YEAR, 1, @Fiscal_First_Date_of_Year));

Fiscal Day of the Year:

年度财务日:


DATEDIFF(DAY, @Fiscal_First_Date_of_Year, @Date_Counter) + 1;

Fiscal Week of the Year:

年度财政周:


(@Fiscal_Day_of_Year + DATEPART(WEEKDAY, @Fiscal_First_Date_of_Year) - DATEPART(WEEKDAY, @Date_Counter)) / 7 + 1;

Fiscal Quarter:

财政季度:


CASEWHEN @Calendar_Quarter = 4 THEN 1ELSE @Calendar_Quarter + 1
END;

Fiscal Month:

会计月份:


CASEWHEN @Calendar_Month BETWEEN 10 AND 12 THEN @Calendar_Month - 9ELSE @Calendar_Month + 3
END;

The calculations here base our results on the difference between the start and end of the fiscal year, or on the difference between the standard calendar and the fiscal calendar. Any of these formulas could be shifted to account for fiscal calendars that begin or end on any other time of the year.

此处的计算基于会计年度开始和结束之间的差额,或基于标准日历和会计日历之间的差额得出的结果。 这些公式中的任何一个都可以转换为考虑在每年其他时间开始或结束的会计日历。

Fiscal calendars have immense use within accounting and business analytics. Being able to adjust a calendar to fit perfectly around an organization’s needs allows us to improve all reporting on their data. Calculating fiscal metrics is generally simple and many date attributes can be shared across calendars as a shifting of quarters does not change days of the week or any specific date subcomponents.

财务日历在会计和业务分析中具有巨大的用途。 能够调整日历以使其完全适合组织的需求,这使我们能够改善有关其数据的所有报告。 通常,计算财务指标很简单,并且可以在日历之间共享许多日期属性,因为季度的变动不会更改星期几或任何特定的日期子组件。

实作 (Implementation)

In practice, we will create a calendar table and then add on columns for any additional calendars we would like to use. As a result, we’ll be able to compare metrics between each directly. In our demo below, we will build a calendar table and add merchant, ISO, and fiscal metrics to the same table. I did not include every common calculation as it’d be overkill, but using what is here, determining additional data elements should be pretty easy!

实际上,我们将创建一个日历表,然后为要使用的其他日历添加列。 结果,我们将能够直接比较每个指标。 在下面的演示中,我们将构建一个日历表,并将商户,ISO和财务指标添加到同一表中。 我没有列出所有常见的计算方法,因为这过高了,但是使用此处的内容,确定其他数据元素应该非常容易!

Please download Calendar table script that will build a calendar table, create a stored procedure that populates it, and execute it for a 6 year range, and then select the results out of that table.

请下载日历表脚本,该脚本将构建一个日历表,创建一个填充该日历表的存储过程,并执行6年范围,然后从该表中选择结果。

After executing the script above, we can view the results:

执行完上面的脚本后,我们可以查看结果:

There are far too many columns to easily display here, but we now have a calendar table that contains a variety of standard date components, as well as additional ones that pertain to the merchant, ISO, and fiscal calendars.

这里有太多列无法轻松显示,但是我们现在有了一个日历表,其中包含各种标准日期组件,以及与商户,ISO和财政日历有关的其他组件。

Having this data side-by-side allows us to report off of multiple calendars using the same dimension table. We can then compare and not only see how data changes across calendars, but this analysis can let us understand which would be the best calendar to use for a given business, and from there fine-tune our metrics to return the most useful data.

并排使用这些数据可以使我们使用同一维度表报告多个日历。 然后,我们可以进行比较,不仅可以查看日历之间的数据变化情况,而且可以通过此分析使我们了解对于给定的业务,哪种日历将是最佳日历,然后从中调整指标以返回最有用的数据。

好处与缺点 (Benefits & Drawbacks)

No calendar is perfect. Those that are more uniform tend to be far more at odds with our day-to-day processes. For example, the ISO calendar is very easy to understand, but does not correlate well with how we manage calendars outside of the reporting world. Less uniform calendars, such as those based solely on lunar or solar cycles, will offer inconsistent and potentially difficult data challenges, as we try to report month-on-month, quarter-on-quarter, or year-on-year.

没有日历是完美的。 那些更加统一的企业往往与我们的日常工作相矛盾。 例如,ISO日历非常易于理解,但与我们在报告世界之外管理日历的方式并没有很好的关联。 当我们尝试逐月,按季度或按年报告时,不太统一的日历(例如仅基于农历或太阳周期的日历)将提供不一致且可能困难的数据挑战。

A specific business should choose the correct calendars for use in different applications. If one size fits all, then that greatly simplifies communication and reporting across an entire organization. If not, then it will need to be decided for which applications a given calendar is used, and ensure that no confusion arises as a result.

特定企业应选择正确的日历以用于不同的应用程序。 如果一个人适合,那么这将大大简化整个组织的沟通和报告。 如果没有,那么将需要确定使用给定日历的应用程序,并确保不会引起混淆。

客制化 (Customization)

Building a calendar table and adding new calendars is a process that is highly customizable. In addition to choosing the calendars to use, we have complete control over which data elements to include. Some businesses create their own unique calendar that accommodates their specific needs when no other adequate one exists. For example, some businesses will avoid the leap year problem by cutting out or adding days year-on-year, thus removing data points, but keeping the calendar uniform regardless of the year.

建立日历表和添加新日历是高度可定制的过程。 除了选择要使用的日历之外,我们还可以完全控制要包括的数据元素。 一些企业创建自己的独特日历,以在没有其他适当日历时满足其特定需求。 例如,某些企业可以通过按年减少或增加天数来避免the年问题,从而删除数据点,但无论年份如何都保持日历统一。

The examples presented here are only a fraction of the possible metrics that can be calculated. A year can be defined and subdivided in many different ways, each of which could spawn a wide variety of attributes that we could track.

此处提供的示例只是可以计算的可能指标的一小部分。 可以用许多不同的方式来定义和细分年份,每种方式都可以产生我们可以跟踪的各种属性。

In previous articles, we have delved into a variety of date parts, as well as holidays and seasons. These can be integrated into any calendar and used in order to track data change over specific time periods, days, or groups of days.

在以前的文章中,我们深入研究了各种日期部分以及假日和季节。 这些可以集成到任何日历中,并用于跟踪特定时间段,几天或几天内数据的变化。

Calendar tables are made for this variability. Add anything that is missing and remove anything that seems unnecessary. Dimension tables such as this can be modified easily as the data volume is low and the cost to repopulate it is small. Even if you compute 50 years of data, the row count for all of that would fall around 18,262. As a result, your table could afford to be wide if all of the columns were needed. Keeping data types compact by using DATE, TINYINT, BIT, or SMALLINT greatly improves performance and reduces storage size.

为此创建了日历表。 添加缺少的所有内容,并删除似乎不必要的所有内容。 由于数据量少且重新填充数据的成本小,因此可以轻松修改此类维表。 即使您计算50年的数据,所有这些数据的行数也将落在18,262左右。 因此,如果需要所有列,则您的表可以负担得起。 通过使用DATE,TINYINT,BIT或SMALLINT保持数据类型紧凑,可以大大提高性能并减小存储大小。

结论 (Conclusion)

Our ability to customize and use calendar data does not stop with our standard Gregorian calendar. When our calendar fails us, we can look towards others in order to fill our business, reporting, and analysis needs.

我们自定义和使用日历数据的能力并不止于我们的标准公历。 当我们的日历失败时,我们可以着眼于其他人,以满足我们的业务,报告和分析需求。

Merchant, ISO, and fiscal calendars are all options that can be utilized in order to increase the flexibility of your data and make it more relevant to your business needs. Once utilized, any number of metrics can be calculated within each calendar, referencing date parts, time of year, or relative time of year. Feel free to customize and make the solution fit your needs, removing unneeded columns and adding any that could be useful. As with any flexible solution, your imagination is the limit and if you can conceive of a metric that could be of value, then it can be architected, implemented, and applied to any analysis that benefits from a calendar table!

可以使用商户日历,ISO日历和财务日历,以增加数据的灵活性并使其与业务需求更加相关。 一旦使用,就可以在每个日历中计算任何数量的指标,参考日期部分,一年中的时间或一年中的相对时间。 可以随意自定义并使解决方案适合您的需求,删除不需要的列并添加任何有用的内容。 与任何灵活的解决方案一样,您的想象力是极限,如果您可以构想可能有价值的指标,则可以设计,实施该指标并将其应用于受益于日历表的任何分析!

Previous articles in this series:

本系列以前的文章:

  • Designing a Calendar Table设计日历表
  • Implementing and Using Calendar Tables实施和使用日历表

资料下载 (Downloads)

  • Calendar table script日历表脚本

看更多 (See more)

Consider these free tools for SQL Server that improve database developer productivity.

考虑使用这些免费SQL Server工具来提高数据库开发人员的生产力。

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

  • Merchant/4-5-4 calendar details, from the National Retail Federation 全国零售联合会的商家/ 4-5-4日历详细信息
  • List of DATEPART options, including ISO_WEEK DATEPART选项的列表,包括ISO_WEEK
  • A relatively in-depth Wikipedia entry on fiscal calendars 财政日历上相对深入的Wikipedia条目
  • A very colorful PDF of the official 2017 ISO calendar 官方2017 ISO日历的彩色PDF

翻译自: https://www.sqlshack.com/implementing-different-calendars-in-reporting/

日历报表

日历报表_在报表中实施不同的日历相关推荐

  1. linux查看日历命令_在Linux中使用命令行日历和日期功能

    linux查看日历命令 我一直对历史日期感兴趣,并确定事件发生在一周的实际哪一天. 独立宣言在一周的哪一天签署? 我是星期几出生的? 1876年7月4日是星期几? 我知道您可以使用搜索引擎来回答许多这 ...

  2. 使用游标显示销售报表_协助报表开发之 MongoDB join mysql

    集算器 SPL 语言支持处理多样性数据源,通过 SPL 对 MongoDB 集合与 MySql 表进行 join 关联,不仅简化了对 MongoDB 数据的操作,而且有利于与其它报表工具的方便集成.若 ...

  3. java课程设计日历记事本_《Java程序设计》课程设计日历记事本.doc

    <Java程序设计>课程设计日历记事本 PAGE PAGE 2 本科生课程设计 课程名称 Java程序设计课程设计 课程编号 j1620011 题目 日历记事本 学号 2008116222 ...

  4. python实现日历功能_使用python生成markdown格式的日历

    文章目录 作用: 使用python生成日报中的日历 参考: 代码:# coding=utf-8 def is_leap_year(year): # 判断是否为闰年 if year % 4 == 0 a ...

  5. js php 实现日历签到_【原】js 签到用日历

    最近做的一个项目中,需要用到一个日历来记录你的签到,网上找了一些,感觉挺庞大的,所以就自己写了一个,记录一下自己写这个日历的经过 html代码: MonTueWedThuFriSatSun css代码 ...

  6. java编写日历思路_使用JAVA写一个简单的日历

    JAVA写一个简单的日历import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDat ...

  7. 计算机会计课程试题及答案,计算机会计第2次作业_报表_附答案

    计算机会计第2次作业_报表_附答案 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 . . . . .<计算机会计>课程作业 ...

  8. python能代替做表格吗_做报表三年却被淘汰:别学python和Excel,这才是你该会的工具...

    我们每一个人,每天无时无刻都在生产数据,一分钟内,微博上新发的数据量超过10万,b站的视频播放量超过600万......这么庞大的数据量,预示着大数据时代,懂数据是每个人的必备技能. 前几天看朋友圈, ...

  9. java 报表_市占率第一的Java报表工具 - FineReport报表工具

    作为国产Java报表工具的优秀代表,FineReport报表工具不仅仅在报表设计的简单易用上表现出极大的优势,更在数据分析等复杂报表处理能力和报表管理等报表综合应用上凸显出其报表技术的成熟和领先. 一 ...

最新文章

  1. R语言_基本统计分析
  2. ecshop后台实现用ajax动态修改/更新用户评论的时间
  3. stm32l0的停止模式怎么唤醒_最强家庭娱乐系统+儿童模式,小度在家智能屏X8开售抢先体验...
  4. javascript中原型模式创建对象特点分析
  5. 梦想——似乎忘记了是什么了
  6. 一次函数的斜率公式_直线斜率k的公式
  7. 【MIT 6.S081】实验四:traps (实验暂停)
  8. python绘制缓和曲线_CAD绘制缓和曲线说明
  9. Python实现双线性插值、最近邻插值、三次内插法
  10. 可以嵌入ppt的课堂点名器_利用Python实现课堂点名器!辅导员大大的夸赞了我!...
  11. FPGA之通信算法工程师面试题3
  12. 企业级代码静态测试工具Helix QAC——从应用层级保证代码质量和安全
  13. 求一元二次方程的解法c语言,一元二次方程的解法(全)
  14. ESP32/ESP32S2直连腾讯云,实现微信小程序控制
  15. #LeetCode15. 三数之和 @FDDLC
  16. 安科瑞三相电流互感器的规格参数(安科瑞-卓宋兰)
  17. 【vue3】vue3+ts+vite项目设置路径别名
  18. 认识信道(零):天线的极化
  19. KR通过Server酱通知
  20. C# 使用163 SMTP发送邮件

热门文章

  1. mysql 驱动名称_mysql驱动名更新
  2. pyqt5 列表内添加按钮
  3. 初学 快速幂 的理解
  4. JTable 的使用
  5. listview与adapter用法
  6. spring数据源、连接池配置
  7. 每隔一段时间自动执行一次某个方法(使用线程)[C#]
  8. Asp.Net访问Oracle 数据库 执行SQL语句和调用存储过程
  9. Web存储—获取Cookie
  10. 超声声场模拟_3D打印全息透镜聚焦超声在低成本脑成像中的应用