DAX Measure:仅首先动态考虑每个组,然后整体返回它们的计数

Sey*_*our 4 dax powerbi powerbi-desktop

我们正在努力解决一个可能比我想象的更简单的问题。我只是卡住了。

问题在于定义的DAX Measure动态计数只有首先在访问期间为每一个病人非第一次访问必须分配 BLANK()值。在讨论目标之前,请让我介绍一下场景。

  1. 场景:
    我们有一个由一个事实表 ( F_Visits) 和两个维度 ( D_Customer; D_Calendar)组成的模型。 F_Visits有 100 万条记录,包含顾客对服装店的所有访问。它的字段是:
    Visit Id:增量唯一编号,它是表的自然键
    Customer Fk: 事实表
    Calendar Fk中维度 D_Customer 的外键:事实表中维度 D_Calendar 的外键
    Quantity: 访问中购买的布件
    Amount数: 花费的美元金额在访问中
    Seller:为客户服务的员工姓名

  2. 目标:
    创建一个度量:

    • 动态(基于时间段选择)
    • 对于每个客户内的每次访问,1如果它是所选时间段内该患者的第一个访问,则返回该值该时间段内的最小访问 ID),忽略不是每个客户所选时间段内第一个访问的访问
    • 总体(总计)此度量需要返回选定时间段内所有患者首次就诊的总数

过去两周我一直在在线社区上搜索,但没有发现像我这样的问题。一个类似(但不同)的如下:总结 Power BI 中首次出现的不同值 与该问题相比的主要区别在于,对于不是该患者的第一个访问,此问题的度量需要为 BLANK()所选期间。
3. 示例:

+----------+-------------+-------------+----------+--------+--------+
| Visit Id | Customer FK | Calendar FK | Quantity | Amount | Seller |
+----------+-------------+-------------+----------+--------+--------+
|        1 | John        |    20170101 |        1 |     10 | Rick   |
|        2 | John        |    20180101 |        2 |     15 | Morty  |
|        3 | John        |    20180101 |        3 |     17 | Eric   |
|        4 | John        |    20190101 |        2 |     17 | Eric   |
|        5 | Mark        |    20170101 |        1 |     17 | Eric   |
|        6 | Mark        |    20180101 |        3 |     12 | Eric   |
|        7 | Jack        |    20190101 |        0 |      0 | Rick   |
+----------+-------------+-------------+----------+--------+--------+
Run Code Online (Sandbox Code Playgroud)
  1. 解决方案:用户现在过滤 Calendar FK = 2018。这将排除一些访问,并且动态计算度量以仅计算每个患者在所选时间段内的第一次访问:

详细表

+----------+-------------+-------------+----------+--------+--------+---------+
| Visit Id | Customer FK | Calendar FK | Quantity | Amount | Seller | Measure |
+----------+-------------+-------------+----------+--------+--------+---------+
|        2 | John        |    20180101 |        2 |     15 | Morty  | 1       |
|        3 | John        |    20180101 |        3 |     17 | Eric   | BLANK() |
|        6 | Mark        |    20180101 |        3 |     12 | Eric   | 1       |
+----------+-------------+-------------+----------+--------+--------+---------+
Run Code Online (Sandbox Code Playgroud)

总计

+-------+
| Total |
+-------+
|     2 |
+-------+
Run Code Online (Sandbox Code Playgroud)

卖家总计

+--------+---------+
| Seller | Measure |
+--------+---------+
| Morty  | 1       |
| Eric   | 1       |
| Rick   | BLANK() |
+--------+---------+
Run Code Online (Sandbox Code Playgroud)

除了需要在前端动态计算外,该方法没有具体要求。

更新

请参阅问题DAX:避免 ALL() 导致矩阵中维度属性的显示不正确

gre*_*gyb 6

First Visit =
// Make a table of all patients in context and their first visit id in context
VAR PatientFirstVisits =
  ADDCOLUMNS (
    VALUES ( 'F_Visits'[Customer Fk] ),
    "MinVisitId", CALCULATE (
        MIN ( 'F_Visits'[Visit Id] ),
        ALL ( 'F_Visits'[Visit Id], 'F_Visits'[Seller] ), // note: fragile
        ALLSELECTED ( 'D_Calendar' )
    )
  )
RETURN
  // Count the Visit Ids that are associated with one of the patient-visit pairs in
  // PatientFirstVisits
  CALCULATE ( 
    DISTINCTCOUNT ( 'F_Visits'[Visit Id] ),
    KEEPFILTERS ( TREATAS ( PatientFirstVisits, 'F_Visits'[Customer Fk], 'F_Visits'[Visit Id] ) )
  )
Run Code Online (Sandbox Code Playgroud)

请注意脆弱部分,最佳实践是构建仅包含 FK 和可聚合事实的事实表,即在事实表中没有任何描述性属性。注释部分脆弱的原因是,您需要将添加到ALL事实的任何新描述性列添加到可能以该度量结束的视觉中。如果你把卖家拉到一个昏暗的地方,你可以重构如下:

First Visit = 
VAR PatientFirstVisits =
  ADDCOLUMNS (
    VALUES ( 'F_Visits'[Customer Fk] ),
    "MinVisitId", CALCULATE (
        MIN ( 'F_Visits'[Visit Id] ),
        ALL ( 'F_Visits'[Visit Id] ),
        ALLSELECTED ( 'D_Calendar' ),
        ALL ( 'Seller' )
    )
  )
RETURN
  CALCULATE ( 
    DISTINCTCOUNT ( 'F_Visits'[Visit Id] ),
    KEEPFILTERS ( TREATAS ( PatientFirstVisits, 'F_Visits'[Customer Fk], 'F_Visits'[Visit Id] ) )
  )
Run Code Online (Sandbox Code Playgroud)

根据我的经验,表中的列比模型中的表更不稳定。我的意思是,我通常看到列中的流失(以某种方式添加、删除、重构)比表中的流失要多得多。通过拉出“卖方”暗淡,您可以这样做,ALL ( 'Seller' )而不必担心跟踪列。

这是正在采取的措施:

在视觉上测量

编辑:一个基于评论的版本,询问我们是否可以做一个COUNTROWS版本而不是DISTINCTCOUNT. VAR 将是相同的,所以我只是在RETURN.

...
RETURN
  // Count the Visit Ids that are associated with one of the patient-visit pairs in
  // PatientFirstVisits
  COUNTROWS ( 
    INTERSECT (
      GROUPBY( 'F_visits', 'F_visits'[Customer FK], 'F_visits'[Visit Id] ),
      PatientFirstVisits
    )
  )
Run Code Online (Sandbox Code Playgroud)

在这里,我们只是将 VAR 表和来自事实的上下文中的值相交。对于详细信息行,该相交为 1 行或为空,它是未经 'F_Visits'[Visit Id] 过滤的总数。