【问题标题】:DAX Measure to calculate number of lost days in different year from total number of daysDAX Measure从总天数计算不同年份的损失天数
【发布时间】:2017-09-01 04:48:44
【问题描述】:

我正在尝试根据我创建的日历表计算特定年份的天数。

例如:我有 3 列。
事件、天数和该事件开始的日期

Event       DaysLost
Injury       30              25/12/2016  
Injury       588            06/08/2012

2016 年的天数 - 6
2017 年 - 24 天

对于第二种情况:

2012 年的天数 - 146
2013 年的天数 - 365
2014 年的天数 - 77

现在对于上述情况,2016 年只需计算 6 天,其余天数应自动计算在 2017 年。但我不知道该怎么做。

在我的输出中,我想将年份放在一个列中,并将该年丢失的天数放在该特定年份的前面。

我有一个日历表,我想要填充特定年份的天数。

我尝试通过获取结束日期、将天数添加到第一个开始日期以及如果天数超过当年剩余天数来计算它。从总天数中减去剩余天数,剩余天数应移至明年。但是如果天数延长很多年并在单词后列出,我无法弄清楚如何继续为明年添加天数。

2017 年 9 月 4 日 请看下面的excel解决方案

Excel solution of the problem

【问题讨论】:

  • 说实话我很困惑。您能否模拟一下您要实现的目标,并明确定义输入/所需的输出?你说你已经尝试了一些东西——你可能应该发布你得到的代码和结果(以及预期的结果)。
  • 我知道您提出了有关 DAX 的问题,但如果您愿意,我可以为您提供使用 Power Query 的解决方案。
  • 是的,我愿意接受任何解决方案。我用 excel 弄明白了。
  • 我刚刚在我的原始帖子中添加了 excel 解决方案的屏幕截图。请检查一下并告知是否可以使用 DAX 甚至是 powerquery。

标签: excel powerbi powerpivot dax


【解决方案1】:

0) 将 Excel 屏幕截图中的数据导入 Power BI 会导致此结果。

1)使用以下公式在该表中创建一个新列作为结束日期(以帮助未来的公式)。

EndDate = Injuries[First Start Date] + Injuries[Days]

你说你有一个日历表,所以你可以跳到第 3 步

2) 通过单击建模 -> 新表并输入以下公式来创建一个新表。这给出了一个包含年份列表的单列表。

Years = GENERATESERIES(2000, 2020, 1)

3) 使用以下公式创建另一个新表。这提供了一个表,其中包含初始数据表中的所有字段与刚刚创建的 Year 表交叉连接。该公式还筛选结果表以仅返回“年份”列中的值介于“首次开始日期”和“首次开始日期加天”之间的行。要了解有关CROSSJOIN 函数的更多信息,请查看文档here

InjuriesByYear = FILTER(
    CROSSJOIN(Years, Injuries),
    Years[Year] >= Injuries[First Start Date].[Year] &&
    Years[Year] <= Injuries[EndDate].[Year]
)

4) 创建从 InjuriesByYear 表返回到初始数据表和 Year 表的关系。这将有助于促进更好的报告工作。

5) 在 InjuriesByYear 表中,通过单击 Modeling -> New Column 并输入以下公式来创建一个新列。第一个IF 检查是否所有丢失的天数都在一年内。第二个IF 处理跨多个年份的日期,True 子句处理第一年,False 子句处理所有其他年份。

DayPerYear = IF(
    InjuriesByYear[Year] = InjuriesByYear[First Start Date].[Year] && InjuriesByYear[Year] = InjuriesByYear[EndDate].[Year], InjuriesByYear[Days],
    IF(
        InjuriesByYear[Year] = InjuriesByYear[First Start Date].[Year], DATEDIFF(InjuriesByYear[First Start Date], DATE(InjuriesByYear[First Start Date].[Year], 12, 31), DAY),
        DATEDIFF(DATE(InjuriesByYear[Year], 1, 1), MIN(InjuriesByYear[EndDate], DATE(InjuriesByYear[Year], 12, 31)), DAY) + 1
    )
)

6) 要全面测试,请创建如下配置的数据透视表。按照这些步骤,数据透视表应该与您的 Excel 解决方案相匹配。

【讨论】:

  • 非常感谢先生。你是救主。但是,在已经存在的日历表和新创建的年表之间创建了关系,并打开了双向过滤器。在您的帮助下,我首先实现了我想要的。不能感谢你!非常非常感谢你。感谢您的时间和精力!!!
  • @jjgg - 我很乐意提供帮助。如果它解决了您的问题,您能否帮我(和社区)一个忙并接受我的回答?
【解决方案2】:

这是一种基于 Power Query 的方法...

我是从这个开始的:

然后我通过单击“添加列”选项卡和“自定义列”按钮添加了一个自定义列,并完成如下弹出窗口:

...然后单击“确定”。

然后我通过选择该新列并单击“转换”选项卡,然后单击“数据类型和日期”来更改该新列的类型。

然后我添加了另一个自定义列,像这样完成弹出窗口:

然后我添加了另一个自定义列,像这样完成弹出窗口:

然后我添加了另一个自定义列,完成如下弹出窗口:

然后我通过单击列顶部的 并展开到新行来展开我添加的最后一列。

然后我添加了一个最终的自定义列,像这样完成弹出窗口:

最后,我按 Event、DaysLost、Started 和 Year 列进行分组,并通过单击 Transform 选项卡和 Group By 按钮对 DaysLostForYear 列求和,并完成如下所示的弹出窗口:

我最终得到了这个:

您可能想要一个不同的分组,但这应该会让您接近。它显示了与每次受伤的总损失天数相关的年份中损失了多少天。例如,第一次伤害持续时间为 30 天,从 2016 年 12 月 25 日开始:其中 7 天发生在 2016 年,23 天发生在 2017 年。第二次伤害为 588 天,从 2012 年 8 月 6 日开始:148天数分别是 2012 年、2013 年 365 天和 2014 年 75 天。

请注意,我将开始日期视为丢失的一天。 另请注意,我考虑了闰年。

我希望这会有所帮助。

查询代码如下:

let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Event", type text}, {"DaysLost", Int64.Type}, {"Started", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Ended", each Date.AddDays([Started],[DaysLost]-1)),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Ended", type date}}),
#"Added Custom3" = Table.AddColumn(#"Changed Type1", "DaysYearStarted", each Number.From(Date.From(Text.From(Date.Year([Started]))&"/12/31")-[Started])+1),
#"Added Custom4" = Table.AddColumn(#"Added Custom3", "DaysYearEnded", each Number.From([Ended]-Date.From(Text.From(Date.Year([Ended])-1)&"/12/31"))),
#"Added Custom5" = Table.AddColumn(#"Added Custom4", "Year", each List.Numbers(Date.Year([Started]),Date.Year([Ended])-Date.Year([Started])+1)),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom5", "Year"),
#"Added Custom1" = Table.AddColumn(#"Expanded Custom", "DaysLostForYear", each if [Year]=Date.Year([Started]) then [DaysYearStarted] else
 if [Year]=Date.Year([Ended]) then [DaysYearEnded] else
 if Date.IsLeapYear([Year]) then 366 else 365),
#"Grouped Rows" = Table.Group(#"Added Custom1", {"Event", "DaysLost", "Started", "Year"}, {{"DaysLostForYear", each List.Sum([DaysLostForYear]), type number}})
in
#"Grouped Rows"

【讨论】:

  • 嘿!如果您查看我下面的屏幕截图并查询代码,我没有得到我想要的结果。我希望能够在最后创建一个数据透视表,并将年份放在一行中,并将每年丢失的天数作为值。能否请你帮忙?例如:如果您查看第一个声明“29955115”,它只有 54 天丢失,并且从“2017 年 4 月 27 日”开始,因此它应该只计算 2017 年的 54 天,而不是计算 249 天。请帮忙。提前致谢
  • @jjgg,我没有看到你的屏幕截图和查询代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2017-06-24
相关资源
最近更新 更多