4-5-4 National Retail Foundation Календарь CSV скачать или функцию, чтобы создать - PullRequest
4 голосов
/ 10 августа 2011

Я гуглил повсюду и не нашел этого. Розничный клиент, с которым я работаю, использует календарь NRFretail. Сайт NRF Календари Мне интересно, создавал ли кто-нибудь таблицу поиска / измерения с этими значениями.

Спасибо

Ответы [ 5 ]

4 голосов
/ 06 июля 2012

Вы можете найти модуль perl, который может генерировать календарь Retail 4-5-4 для любого года на CPAN: http://metacpan.org/pod/DateTime::Fiscal::Retail454

Это было написано специально для этой проблемы.

3 голосов
/ 23 ноября 2012

Алгоритмический вариант, который я использовал в прошлом, был (я перефразирую, как я это делал в Excel):

  • Начиная с даты, определите число недели (в диапазоне от 1 до53)
  • Из номера недели рассчитать номер периода (в диапазоне от 1 до 12) как:

    1+                              'one-based
    3*(INT((weeknum-1)/13))+        'start from the first week within a 13-week quarter
    IF(MOD(weeknum-1,13)>3,1,0)+    'adjust for weeks in the middle chunk
    IF(MOD(weeknum-1,13)>8,1,0)+    'and for weeks in the last chunk
    IF(weeknum>52,-1,0)             'and handle "leap week" every 6th year or so
    
0 голосов
/ 27 октября 2017

Сценарий ниже для создания таблицы для 4/5/4 розничного календаря на любой период времени.Он рассчитывает любой год, содержащий 52 или 53 недели.Неделя оформлена в американском стиле, начиная с воскресенья.

Я создал таблицу Calendar перед запуском следующего скрипта со следующей структурой и заполнил данные в "dbo.Calendar".Возможно, вы захотите использовать статью Аарона Бертрана https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/ для заполнения данных в таблице «Календарь»:

CREATE TABLE dbo.Calendar
(
  DateKey             INT         NOT NULL PRIMARY KEY,
  [Date]              DATE        NOT NULL,
  [Day]               TINYINT     NOT NULL,
  DaySuffix           CHAR(2)     NOT NULL,
  [Weekday]           TINYINT     NOT NULL,
  WeekDayShortName    VARCHAR(3)  NOT NULL,
  WeekDayLongName     VARCHAR(10) NOT NULL,
  IsWeekend           BIT         NOT NULL,
  IsHolidayUS         BIT         NOT NULL,
  HolidayUSText       VARCHAR(64) SPARSE,
  IsHolidayCA         BIT         NOT NULL,
  HolidayCAText       VARCHAR(64) SPARSE,
  DOWInMonth          TINYINT     NOT NULL,
  [DayOfYear]         SMALLINT    NOT NULL,
  WeekOfMonth         TINYINT     NOT NULL,
  WeekOfYear          TINYINT     NOT NULL,
  ISOWeekOfYear       TINYINT     NOT NULL,
  [Month]             TINYINT     NOT NULL,
  [MonthShortName]    VARCHAR(3)  NOT NULL,
  [MonthLongName]     VARCHAR(10) NOT NULL,
  [Quarter]           TINYINT     NOT NULL,  
  QuarterName         VARCHAR(6)  NOT NULL,  
  [Year]              INT         NOT NULL,  
  YYYYMM              CHAR(6)     NOT NULL,  
  MonthYear           CHAR(7)     NOT NULL,
  FirstDayOfMonth     DATE        NOT NULL,
  LastDayOfMonth      DATE        NOT NULL,
  FirstDayOfQuarter   DATE        NOT NULL,
  LastDayOfQuarter    DATE        NOT NULL,
  FirstDayOfYear      DATE        NOT NULL,
  LastDayOfYear       DATE        NOT NULL,
  FirstDayOfNextMonth DATE        NOT NULL,
  FirstDayOfNextYear  DATE        NOT NULL,
  PeriodID            INT         NULL
);
GO    

Сценарий создает таблицу «CalendarPeriods45» и заполняет данные.Таблица «CalendarPeriods454» связана с таблицей «Календарь» посредством «PeriodID».Сценарий был создан в Sql Server 2016, поэтому вам может потребоваться изменить «DROP TABLE IF EXISTS ...» на «IF OBJECT_ID ('dbo.CalendarPeriods454') IS NOT NULL DROP TABLE ...".

DROP TABLE IF EXISTS dbo.CalendarPeriods454
CREATE TABLE dbo.CalendarPeriods454
(
  PeriodID            INT          NOT NULL PRIMARY KEY,
  StartDate           Date         NOT NULL,
  EndDate             Date         NOT NULL,
  [Days]              TINYINT      NOT NULL,
  PeriodOfYear        TINYINT      NOT NULL,
  PeriodShortName     VARCHAR(3)   NOT NULL,
  PeriodLongName      VARCHAR(10)  NOT NULL,
  [Year]              INT          NOT NULL,  
  [Quarter]           TINYINT      NOT NULL,  
  QuarterName         VARCHAR(6)   NOT NULL,  
  SalesReleaseDate    Date         NOT NULL,
  Season              VARCHAR(6)   NOT NULL
);
GO

DECLARE @StartDate datetime; -- date to load 
DECLARE @EndDate datetime; -- date to load 

SET @StartDate = '2000-01-30' -- should be beginning of the 454 Calendar year
SET @EndDate = '2041-01-30'
DECLARE @PeriodID INT;
SELECT @PeriodID = ISNULL(s.periodID,0) FROM (SELECT MAX(periodID) as periodID from CalendarPeriods454) as s
SET @PeriodID = @PeriodID + 1

DECLARE @PeriodOfYear TINYINT; --1 to 12
SET @PeriodOfYear = 1;

DECLARE @Days TINYINT ; --28 or 35
DECLARE @PeriodShortName VARCHAR(3);
DECLARE @PeriodLongName VARCHAR(10);
DECLARE @Year int;
SET @Year = Datepart(year,@StartDate);
DECLARE @Quarter TINYINT; --1 or 2 or 3 or 4

While @StartDate<=@EndDate
BEGIN

    SET @Days = (CASE @PeriodOfYear 
                        WHEN 1 THEN 28
                        WHEN 2 THEN 35
                        WHEN 3 THEN 28
                        WHEN 4 THEN 28
                        WHEN 5 THEN 35
                        WHEN 6 THEN 28
                        WHEN 7 THEN 28
                        WHEN 8 THEN 35
                        WHEN 9 THEN 28
                        WHEN 10 THEN 28
                        WHEN 11 THEN 35
                        WHEN 12 THEN 28
                    END)    

    -- Exclusion if need to add additional week at the end of the year,     check the last day of the period. 
    -- If last day of the period equal 26 or 27 january we add additional week
     IF @PeriodOfYear = 12 and (datepart(day,dateadd(day,@Days-1,@StartDate))=26 or datepart(day,dateadd(day,@Days-1,@StartDate))=27) 
         SET @Days = 35

     SET @PeriodShortName = (CASE @PeriodOfYear 
                        WHEN 1 THEN 'Feb'
                        WHEN 2 THEN 'Mar'
                        WHEN 3 THEN 'Apr'
                        WHEN 4 THEN 'May'
                        WHEN 5 THEN 'Jun'
                        WHEN 6 THEN 'Jul'
                        WHEN 7 THEN 'Aug'
                        WHEN 8 THEN 'Sep'
                        WHEN 9 THEN 'Oct'
                        WHEN 10 THEN 'Nov'
                        WHEN 11 THEN 'Dec'
                        WHEN 12 THEN 'Jan'
                    END) 

    SET @PeriodLongName = (CASE @PeriodOfYear 
                        WHEN 1 THEN 'February'
                        WHEN 2 THEN 'March'
                        WHEN 3 THEN 'April'
                        WHEN 4 THEN 'May'
                        WHEN 5 THEN 'June'
                        WHEN 6 THEN 'July'
                        WHEN 7 THEN 'August'
                        WHEN 8 THEN 'September'
                        WHEN 9 THEN 'October'
                        WHEN 10 THEN 'November'
                        WHEN 11 THEN 'December'
                        WHEN 12 THEN 'January'
                    END) 
    SET @Year = (CASE @PeriodOfYear 
                        WHEN 1 THEN Datepart(year,@StartDate)
                        ELSE @Year
                    END) 
    SET @Quarter = (CASE @PeriodOfYear 
                        WHEN 1 THEN 1
                        WHEN 2 THEN 1
                        WHEN 3 THEN 1
                        WHEN 4 THEN 2
                        WHEN 5 THEN 2
                        WHEN 6 THEN 2
                        WHEN 7 THEN 3
                        WHEN 8 THEN 3
                        WHEN 9 THEN 3
                        WHEN 10 THEN 4
                        WHEN 11 THEN 4
                        WHEN 12 THEN 4
                    END) 

    INSERT INTO dbo.CalendarPeriods454(PeriodID,StartDate,EndDate,[Days],PeriodOfYear,
    PeriodShortName,PeriodLongName,[Year],[Quarter],QuarterName,SalesReleaseDate,Season)
    --Calendar 454-454-454-454
    SELECT  
    PeriodID        = @PeriodID,
    StartDate       = @StartDate, 
    EndDate         = dateadd(day,@Days-1,@StartDate),
    [Days]          = @Days,
    PeriodOfYear    = @PeriodOfYear,
    PeriodShortName = @PeriodShortName,
    PeriodLongName  = @PeriodLongName,
    [Year]          = @Year,
    [Quarter]       = @Quarter, 
    QuarterName     =CONVERT(VARCHAR(6), CASE @Quarter WHEN 1 THEN 'First' 
                        WHEN 2 THEN 'Second' WHEN 3 THEN 'Third' WHEN 4 THEN 'Fourth' END),
    SalesReleaseDate = dateadd(day,4,@StartDate), 
    Season           = CASE WHEN  @PeriodOfYear>=1 and @PeriodOfYear<=6 THEN     'SPRING' ELSE 'FALL' END



    SET @StartDate = dateadd(day,@Days,@StartDate)
    SET @PeriodID = @PeriodID+1
    SET @PeriodOfYear = (CASE WHEN @PeriodOfYear+1 =13 THEN 1 ELSE @PeriodOfYear+1 END)
END

-- Table Calendar was created before at a daily grain
-- we need to update Calendar Table to set PeriodID to link Calendar and 
alter table [dbo].DateDimension add PeriodID    INT 
alter table   [dbo].DateDimension add FW    varchar(2)
;with cte
as
(
select DateKey
       , ((ROW_NUMBER() over(Order by DateKey asc)-1) / 7) + 1 as 'FW'
       , Cal454.PeriodID 'FM'
FROM [dbo].DateDimension as C1
--FROM [dbo].Calendar as C1
INNER JOIN [dbo].[CalendarPeriods454] as Cal454
ON Cal454.StartDate<=C1.Date AND Cal454.EndDate>=C1.Date
)
UPDATE  c1
SET c1.PeriodID = cte.FM  
    ,c1.FW = cte.FW 
FROM [dbo].DateDimension as C1
join cte 
on c1.DateKey = cte.DateKey
0 голосов
/ 26 января 2017

Прикреплено csv с календарем на 2005–2025 гг. Со следующими данными:

RatailCalendar-4-5-4

DataNumber : дата в числовом формате

Год : Год

Квартал : Квартал (число)

Месяц : Месяц (число)

Неделя : неделя

Дата данных : дата в строковом формате

День : номер дня

DayName: Day описание (на итальянском)

CommercialWeek : коммерческая неделя, рассчитанная с DateTime :: Fiscal :: Retail454

CommercialMonth : коммерческий месяц по nrf.com 4-5-4 розничный календарь

CommercialYear : коммерческий год на основе nrf.com 4-5-4 розничных календаря

StartWeek : начать коммерческую неделю, рассчитанную с помощью DateTime :: Fiscal :: Retail454

EndWeek : конец коммерческой недели, рассчитанный с DateTime :: Fiscal :: Retail454

Это скрипт perl, используемый для генерации календаря:

use DateTimeX::Fiscal::Fiscal5253;
use Data::Dumper;
use Data::Dumper::Table;
use DBI;
use strict;
use JSON;
use warnings;

my $fc = DateTimeX::Fiscal::Fiscal5253->new(
end_month => 1,
end_dow => 7,
end_type => 'closest',
leap_period => 'last',
year => 2019,    
);

my $filename = 'report.txt';
open(my $fh, '>', $filename) or die "Could not open file '$filename'$!"; 

print $fh Dumper(\$fc);
close $fh;

Основное отличие от розничного календаря nrf.com 4-5-4 заключается в том, что неделя форматируется в «итальянском стиле», начиная с понедельника.

Надеюсь, это поможет.

0 голосов
/ 10 августа 2011

см. http://www.nrf.com/modules.php?name=Documents&op=viewlive&sp_id=6019

4-5-4 или 4-4-5 календари используются для предоставления последовательных длин месяцев от года к году, вместо того, чтобы сообщать о ежемесячных продажах с 1-31 января месяцаянваря начинается в воскресенье и заканчивается в субботу.Таким образом, в месяце всегда одинаковое количество выходных, а праздники не смещаются, что делает возможным сравнение месячных продаж из года в год

за кулисами много возни, но 4-5-Опубликовано 4 календаря - см. Ссылку выше.

Похоже, вы пытаетесь использовать их в качестве измерения для хранилища данных звездной схемы?Вы ищете советы по реализации этого?

Я действительно должен был сделать какую-то настоящую работу этим вечером

******************* Feb06
[[29, 30, 31, 1, 2, 3, 4],
 [5, 6, 7, 8, 9, 10, 11],
 [12, 13, 14, 15, 16, 17, 18],
 [19, 20, 21, 22, 23, 24, 25]]
******************* Mar06
[[26, 27, 28, 1, 2, 3, 4],
 [5, 6, 7, 8, 9, 10, 11],
 [12, 13, 14, 15, 16, 17, 18],
 [19, 20, 21, 22, 23, 24, 25],
 [26, 27, 28, 29, 30, 31, 1]]
******************* Apr06
[[2, 3, 4, 5, 6, 7, 8],
 [9, 10, 11, 12, 13, 14, 15],
 [16, 17, 18, 19, 20, 21, 22],
 [23, 24, 25, 26, 27, 28, 29]]

вышеизложенное кажется правильным для глаз на календари NRF

это из-за нижеизложенного уродства, но это может помочьтебе 15 лет

import calendar
calendar.setfirstweekday(calendar.SUNDAY)
import datetime
import pprint


def addweek(yr):
    d = datetime.date(yr, 12, 31)
    if d.weekday() in (6,0,1):
        return True
    else:
        return False

def printday(d):
    print d.day,
    if d.weekday() == 5:
        print


def wksinthismth(cal):
    seq = [len(mth) for mth in cal]
    #print "seq", seq

    #special - but really need dates in cal
    if (len(seq) % 11 == 0 ) and len(seq) != 0 and addweek(2006):

        return 5

    try:
        lenlastmth = seq[-1]
    except:
        #print "fail4"
        return 4

    try:
        lenprevmth = seq[-2:-1][0]
    except:
        #print "fail5"
        return 5

    try:
        lenprevprevmth = seq[-3:-2][0]
    except:
        lenprevprevmth = 4


    if lenprevmth == []:return 5

    if  (lenlastmth == 4 and lenprevmth == 5 and lenprevprevmth == 5):
        #long january just passed
        return 5

    #print lenlastmth, lenprevmth
    if (lenlastmth == 4 and lenprevmth == 4) :
        #print "ok5"
        return 5
    else:
        #print "ok4"
        return 4

oneday = datetime.timedelta(days=1)
startdate = datetime.date(2006,1,29)
thisdate = startdate
cal = []
thismth = []
thiswk = []

for i in range(800):
    thiswk.append(thisdate.day)
    if thisdate.weekday() == 5: #week over, decide how format it
        wks = wksinthismth(cal)
        if len(thismth) <= wks-1:
            thismth.append(thiswk)
        else:
            cal.append(thismth)
            thismth = []
            thismth.append(thiswk)
        thiswk = []

    thisdate += oneday

mthslist = ['Feb06',
'Mar06',
'Apr06',
'May06',
'Jun06',
'Jul06',
'Aug06',
'Sept06',
'Oct06',
'Nov06',
'Dec06',
'Jan07',
'Feb07',
'Mar07',
'Apr07',
'May07',
'Jun07',
'Jul07',
'Aug07',
'Sept07',
'Oct07',
'Nov07',
'Dec07',
'Jan08',
'Feb08',
'Mar08',
'Apr08',
'May08',
'Jun08',
'Jul08',
'Aug08',
'Sept08',
'Oct08',
'Nov08',
'Dec08',
]
i = 0
for mth in cal:
    print "*******************", mthslist[i]
    pprint.pprint(mth)
    i += 1


# start week on Sun
# if 31 dec is S M T then add week in Jan
print [len(mth) for mth in cal]
...