【问题标题】:Power BI Weeknum IterationPower BI Weeknum 迭代
【发布时间】:2020-02-13 17:59:16
【问题描述】:

我的目标是根据修改后的 4-4-5 日历从周日开始使用 DAX 或 m 代码显示星期数(如果更有意义的话)。

这意味着 1 月的第一个星期日是第 1 周,所有周都应该是整周(7 天)。 2018 年底有第 53 周,根据定义将延长到 2019 年 1 月 5 日星期六 - 2019 年的第一个星期日将是 2019 年 1 月 6 日,即第 1 周。我无法在每年。如果我一年中的前几个日历日是第 52 周或第 53 周,那么下周应该是第 1 周,而是从第 2 周开始。

试图通过 if 语句、lookupvalue 等减去 -1 weeknum 总是会抛出一些问题。

使用WEEKNUM(DATE,1) 将给出从星期日开始的整周,除非是年初。

使用WEEKNUM(DATE,17) 也会从周日开始给出整周,如果不是整整 7 天,还会延长上一年结束的一周。 (第 53 周延长到明年的日历第 1 周)。

问题仍然存在,进入明年,第 1 周部分或全部被上一年结束的一周所取代。基本上,我只能在将近一年的时间内获得适当的结果,但不能在日历表中获得 5 年以上的结果。

我还有一周开始日期、一周结束日期和一年中日期的列(1 到 365/366)。关于每年迭代正确的星期数的逻辑有什么建议吗?谢谢。

【问题讨论】:

    标签: date powerbi dax week-number


    【解决方案1】:

    据我所知,这样做的唯一方法是使用一堆 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 条件 1:这是对一年中的前几天进行编号,前提是它不是从星期日开始的。如果上一年从星期日开始,那么今年的第一周应该是第 53 周

    IF 条件 2:这是对一年的前几天进行编号,前提是它不是从星期日开始的。这种情况特定于上一年是闰年。如果上一年从星期一开始,如果上一年是闰年,那么今年的第一周应该是 53

    IF 条件 3:这是对一年中的前几天进行编号,前提是它不是从星期日开始的。如果一年的第一周不满足条件1和条件2,那么今年的第一周应该是第52周

    IF 条件 4:这是对一年中的所有其他周进行编号。如果一年不是从星期日开始的,那么周数应该是 weeknum-1

    ELSE 条件:这是对一年中的所有其他星期进行编号。如果年份从星期日开始,则周数应为 weeknum

    这应该会给你想要的结果。

    【讨论】:

    • 非常感谢。我正在研究你的逻辑,这非常接近。从 2018 年到 2019 年,我没有预期的第 53 周。这就是 weeknum-1 变得棘手的地方。如果我找到解决方案,我会回复,但同样,这非常接近。
    • 2018 年第 1 周从 1 月 7 日开始,也就是说最后一周是第 52 周,对吧?我在这里错过了什么吗?
    • 我明白你在说什么。我的基础是 Excel 报告,我正在 PBI 中重新制作/扩展。但是,如果您的计算是在去年年初(在我的情况下为 2014 年 1 月 1 日)开始的,那么事情就不准确了。例如,2014 年并没有完全遵循 4 4 5 模式(刚刚注意到这一点)。 2014 年: 一月 (4) 二月 (4) 三月 (5) 四月 (4) 五月 (4) 六月 (5) 七月 (4) 八月 (5) 九月 (4) 十月 (4) 十一月 (5) 十二月 (4 )。这显然会在未来改变数字。需要重新考虑这一点。
    • 看来你还有很长的路要走;)祝你好运
    【解决方案2】:

    我对财务周数、Period 和 dataid 有类似的要求。

    我在数据库中创建了表格,并已将其导入到 poweri bi 报告中。

    我的财务周从 3 月 2 日星期日开始,从今年开始 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      相关资源
      最近更新 更多