Power BI Weeknum Iteration - PullRequest
       15

Power BI Weeknum Iteration

0 голосов
/ 13 февраля 2020

Моя цель - показать недельный номер на основе измененного календаря 4-4-5, начиная с воскресенья, используя код DAX или m, если это имеет больше смысла.

Это означает, что первое воскресенье января - неделя 1, и все недели должны быть полными (7 дней). В конце 2018 года была 53-я неделя, которая по определению продлилась бы до субботы 5 января 2009 года - первое воскресенье 2019 года было бы 6 января 2017 года, то есть недели 1. Мне не удалось сбросить функцию weeknum в каждый год. Если мои первые несколько календарных дней в году были 52 или 53 неделями, следующая неделя должна быть 1, но вместо этого начинается со 2 недели.

Попытка вычесть -1 неделя из выражений if, lookupvalue, et c всегда что-то сбрасывает.

Использование WEEKNUM(DATE,1) даст целые недели, начиная с воскресенья, если это не начало года.

Использование WEEKNUM(DATE,17) также даст полные недели, начиная с воскресенья, а затем продлит неделю предыдущего года, если она не полных 7 дней. (Неделя 53 распространяется на календарную неделю 1 следующего года.)

Проблема остается в том, что в следующем году неделя 1 либо частично, либо полностью заменяется неделей конца предыдущего года. По сути, я могу получить правильные результаты только в течение почти одного года, но не 5+ лет в таблице календаря.

У меня также есть столбцы для даты начала недели, конца недели и дня года (от 1 до 365/366). Любые предложения по логи c, чтобы повторять правильную неделю каждый год? Спасибо.

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Насколько я знаю, единственный способ сделать это - использовать несколько условий IF. Я сделал снимок, и, похоже, я получаю правильные значения. В следующих расчетах предполагается, что вы ищете неделю с воскресенья по субботу:

Weeknum Calc = 
        IF(WEEKDAY(DATE(YEAR('Calendar'[Date]),1,1))>1 && WEEKDAY(DATE(YEAR('Calendar'[Date])-1,1,1))=1 && WEEKNUM('Calendar'[Date])=1,53,
        IF(WEEKDAY(DATE(YEAR('Calendar'[Date]),1,1))>1 && WEEKDAY(DATE(YEAR('Calendar'[Date])-1,1,1))=2 && WEEKNUM('Calendar'[Date])=1 && MOD(YEAR('Calendar'[Date])-1,4)=0,53,
        IF(WEEKDAY(DATE(YEAR('Calendar'[Date]),1,1))>1 && WEEKNUM('Calendar'[Date])=1,52,
        IF(WEEKDAY(DATE(YEAR('Calendar'[Date]),1,1))>1,WEEKNUM('Calendar'[Date])-1,
        WEEKNUM('Calendar'[Date])
        ))))

Чтобы предоставить вам более подробную информацию об условиях IF:

Условие IF: Это номер первой несколько дней в году, если это не начинается в воскресенье. Если предыдущий год начался в воскресенье, то первая неделя этого года должна быть неделей 53

ЕСЛИ Условие 2: это число первых дней в году, если оно не начинается с Воскресенье. Этот случай указывает c, что предыдущий год является високосным. Если предыдущий год начинается в понедельник и если предыдущий год является високосным, то первая неделя этого года должна быть 53

ЕСЛИ Условие 3: это число первых дней в году, при условии, что это не начинается в воскресенье. Если первая неделя года не соответствует условиям 1 и 2, то первая неделя этого года должна быть неделей 52

ЕСЛИ Условие 4: это число всех остальных недель года. Если год не начинается в воскресенье, тогда номер недели должен быть weeknum-1

Иначе Условие: это число всех остальных недель в году. Если год начинается в воскресенье, то номер недели должен быть weeknum

Это должно дать вам желаемый результат.

1 голос
/ 13 февраля 2020

У меня есть аналогичное требование номера финансовой недели, Периода и dataid.

Я создал таблицу в базе данных, и она была импортирована в отчет poweri bi.

моя финансовая неделя начинается со второго марта воскресенья и номер финансовой недели в течение 10 лет с этого года.

скрипт ниже может помочь вам:

-- Create DI_Date diamension table:
CREATE TABLE APM_Reporting.di_date
(
     "datekey"              INTEGER     NOT NULL 
    ,"dateid"               DATE        NOT NULL  
    ,"day"                  INTEGER     NOT NULL
    ,"dayname"              VARCHAR(10) NOT NULL 
    ,"daynameshort"         VARCHAR(3)  NOT NULL
    ,"weekid"               INTEGER     NOT NULL  
    ,"financialweekid"      INTEGER     NOT NULL
    ,"monthid"              INTEGER     NOT NULL
    ,"monthname"            VARCHAR(25) NOT NULL 
    ,"periodid"             INTEGER     NOT NULL  
    ,"periodname"           VARCHAR(25) NOT NULL 
    ,"quarterid"            INTEGER     NOT NULL  
    ,"quartername"          VARCHAR(25) NOT NULL 
    ,"year"                 INTEGER     NOT NULL  
    ,"finyear"              VARCHAR(25) NOT NULL
    ,"created_timestamp"    DATETIME DEFAULT CURRENT_TIMESTAMP
    ,PRIMARY KEY (datekey)
);
-- Check if temp table exists and drop it if true
IF OBJECT_ID('tempdb..##Dates') IS NOT NULL
    DROP TABLE ##Dates
-- Create temporary table for pre-load
  CREATE TABLE ##Dates(
                DateValue Date 
                      )
;                      
-- Declare Start Date
  DECLARE @start DATE = GETDATE() - 396
  DECLARE @end DATE = DATEADD(year, 10,@start)
  WHILE @start < @end
  BEGIN
    INSERT INTO  ##Dates(DateValue)
    VALUES(@start)  
    SET @start = DATEADD(dd,1,@start)
  END
  ;
-- Insert generated data to di_date
INSERT INTO APM_Reporting.di_date 
(
    "datekey",
    "dateid",
    "day",
    "dayname",
    "daynameshort",
    "weekid",
    "financialweekid",
    "monthid",
    "monthname",
    "periodid",
    "periodname",
    "quarterid",
    "quartername",
    "year",
    "finyear"
)

SELECT 
    YEAR(DateValue)*10000+MONTH(DateValue)*100+DAY(DateValue) AS "datekey"
    ,DateValue "dateid"
    ,DAY(DateValue) "day"
    ,DATENAME(dw, DateValue) "dayname"
    ,LEFT(DATENAME(dw,DateValue),3) "daynameshort"
    ,DATEPART(WK,DateValue) "weekid"
    ,CASE
    WHEN DATEPART(WK,DateValue) < 11 THEN DATEPART(WK,DateValue)+42
    ELSE DATEPART(WK,DateValue) - 10
    END AS  "financialweekid"
    ,DATEPART(MM, DateValue) "monthid"
    ,DATENAME(MM,DateValue) "monthname"
    ,CAST(
    CONCAT(
        (CASE 
            WHEN DATEPART(WK,DateValue) BETWEEN 1 and 10 THEN DATEPART(YYYY,DateValue)-1
            ELSE DATEPART(YYYY,DateValue)
        END)
    ,
    CASE
        WHEN DATEPART(WK,DateValue)  BETWEEN '11' AND '14' THEN '01'
        WHEN DATEPART(WK,DateValue)  BETWEEN '15' AND '18' THEN '02'
        WHEN DATEPART(WK,DateValue)  BETWEEN '19' AND '22' THEN '03'
        WHEN DATEPART(WK,DateValue)  BETWEEN '23' AND '26' THEN '04'
        WHEN DATEPART(WK,DateValue)  BETWEEN '27' AND '30' THEN '05'
        WHEN DATEPART(WK,DateValue)  BETWEEN '31' AND '34' THEN '06'
        WHEN DATEPART(WK,DateValue)  BETWEEN '35' AND '38' THEN '07'
        WHEN DATEPART(WK,DateValue)  BETWEEN '39' AND '42' THEN '08'
        WHEN DATEPART(WK,DateValue)  BETWEEN '43' AND '46' THEN '09'
        WHEN DATEPART(WK,DateValue)  BETWEEN '47' AND '50' THEN '10'
        WHEN DATEPART(WK,DateValue)  BETWEEN '51' AND '53' THEN '11'
        WHEN DATEPART(WK,DateValue)  BETWEEN '01' AND '02' THEN '11'
        WHEN DATEPART(WK,DateValue)  BETWEEN '03' AND '06' THEN '12'
        WHEN DATEPART(WK,DateValue)  BETWEEN '06' AND '53' THEN '13'
    ELSE '00'
    END) AS INTEGER) AS "periodid"
    ,CONCAT('P',
    CASE
        WHEN DATEPART(WK,DateValue)  BETWEEN '11' AND '14' THEN '01'
        WHEN DATEPART(WK,DateValue)  BETWEEN '15' AND '18' THEN '02'
        WHEN DATEPART(WK,DateValue)  BETWEEN '19' AND '22' THEN '03'
        WHEN DATEPART(WK,DateValue)  BETWEEN '23' AND '26' THEN '04'
        WHEN DATEPART(WK,DateValue)  BETWEEN '27' AND '30' THEN '05'
        WHEN DATEPART(WK,DateValue)  BETWEEN '31' AND '34' THEN '06'
        WHEN DATEPART(WK,DateValue)  BETWEEN '35' AND '38' THEN '07'
        WHEN DATEPART(WK,DateValue)  BETWEEN '39' AND '42' THEN '08'
        WHEN DATEPART(WK,DateValue)  BETWEEN '43' AND '46' THEN '09'
        WHEN DATEPART(WK,DateValue)  BETWEEN '47' AND '50' THEN '10'
        WHEN DATEPART(WK,DateValue)  BETWEEN '51' AND '53' THEN '11'
        WHEN DATEPART(WK,DateValue)  BETWEEN '01' AND '02' THEN '11'
        WHEN DATEPART(WK,DateValue)  BETWEEN '03' AND '06' THEN '12'
        WHEN DATEPART(WK,DateValue)  BETWEEN '06' AND '53' THEN '13'
    ELSE '00'
    END) "periodname"
    ,DATEPART(Q,DateValue) "quarterid"
    ,CONCAT('Q',DATEPART(Q,DateValue)) "quartername"
    ,DATENAME(YYYY,DateValue) "year"
    ,CASE
    WHEN DATEPART(WK,DateValue)  BETWEEN '11' AND '53' THEN CONCAT(DATENAME(YYYY,DateValue),'-',DATENAME(YYYY,DateValue)+1)
    ELSE CONCAT(DATENAME(YYYY,DateValue)-1,'-',DATENAME(YYYY,DateValue))
    END AS "finyear"
FROM ##Dates;
...