在PowerBI中使用DAX进行左外连接(多对多关系)

时间:2017-07-08 15:42:27

标签: sql join business-intelligence powerbi dax

如何在DAX中进行左连接?当我尝试添加关系或使用左外连接DAX函数时,我得到以下错误(见下文)。任何想法将不胜感激!

创建关系时出错: You can't create a relationship between these two columns becasue one of the columns must have unique values.

尝试使用NaturalLeftOuterJoin()时出错 No common join columns detected. The join function 'NATURALLEFTOUTERJOIN' requires at-least one common join column.

作为参考,我正在尝试创建损益表的计算行。

例如:

  • 收入:100
  • 费用:80
  • 利润:20(收入 - 成本)

我的表格如下:

Fact table:
╔═══════════╦═════════╦═══════════╦════════╗
║ YearMonth ║ StoreID ║ AccountID ║ Amount ║
╠═══════════╬═════════╬═══════════╬════════╣
║ 2017-01   ║ A       ║         1 ║    100 ║
║ 2017-01   ║ B       ║         1 ║    200 ║
║ 2017-01   ║ A       ║         2 ║    -50 ║
║ 2017-01   ║ B       ║         2 ║    -50 ║
║ 2017-02   ║ A       ║         1 ║     20 ║
║ 2017-02   ║ B       ║         1 ║    150 ║
║ 2017-02   ║ B       ║         2 ║    -20 ║
╚═══════════╩═════════╩═══════════╩════════╝

Template table:
╔════════════╦═══════════╦═════════╗
║ TemplateID ║ AccountID ║  Line   ║
╠════════════╬═══════════╬═════════╣
║        105 ║         1 ║ Revenue ║
║        105 ║         2 ║ Cost    ║
║        105 ║         1 ║ Profit  ║
║        105 ║         2 ║ Profit  ║
╚════════════╩═══════════╩═════════╝

在SQL中,这非常简单 - 我只在AccountID字段上执行左外连接,为Profit行创建记录,如下所示:

 SELECT 
       f.[YearMonth]
      ,f.[StoreID]
      ,f.[AccountID]
      ,f.[Amount]
      ,t.[TemplateID]
      ,t.[AccountID]
      ,t.[Line]
  FROM [dbo].[Fact] f
  left join [dbo].[Templates] t
  on f.[AccountID] = t.[AccountID]

结果:

╔═══════════╦═════════╦═══════════╦════════╦════════════╦═══════════╦═════════╗
║ YearMonth ║ StoreID ║ AccountID ║ Amount ║ TemplateID ║ AccountID ║  Line   ║
╠═══════════╬═════════╬═══════════╬════════╬════════════╬═══════════╬═════════╣
║ 2017-01   ║ A       ║         1 ║    100 ║        105 ║         1 ║ Revenue ║
║ 2017-01   ║ B       ║         1 ║    200 ║        105 ║         1 ║ Revenue ║
║ 2017-02   ║ A       ║         1 ║     20 ║        105 ║         1 ║ Revenue ║
║ 2017-02   ║ B       ║         1 ║    150 ║        105 ║         1 ║ Revenue ║
║ 2017-01   ║ A       ║         2 ║    -50 ║        105 ║         2 ║ Cost    ║
║ 2017-01   ║ B       ║         2 ║    -50 ║        105 ║         2 ║ Cost    ║
║ 2017-02   ║ B       ║         2 ║    -20 ║        105 ║         2 ║ Cost    ║
║ 2017-01   ║ A       ║         1 ║    100 ║        105 ║         1 ║ Profit  ║
║ 2017-01   ║ B       ║         1 ║    200 ║        105 ║         1 ║ Profit  ║
║ 2017-02   ║ A       ║         1 ║     20 ║        105 ║         1 ║ Profit  ║
║ 2017-02   ║ B       ║         1 ║    150 ║        105 ║         1 ║ Profit  ║
║ 2017-01   ║ A       ║         2 ║    -50 ║        105 ║         2 ║ Profit  ║
║ 2017-01   ║ B       ║         2 ║    -50 ║        105 ║         2 ║ Profit  ║
║ 2017-02   ║ B       ║         2 ║    -20 ║        105 ║         2 ║ Profit  ║
╚═══════════╩═════════╩═══════════╩════════╩════════════╩═══════════╩═════════╝

然后我可以像这样转动它:

╔═════════╦═════════╦═════════╗
║  Line   ║ Store A ║ Store B ║
╠═════════╬═════════╬═════════╣
║ Revenue ║     120 ║     350 ║
║ Cost    ║     -50 ║     -70 ║
║ Profit  ║      70 ║     280 ║
╚═════════╩═════════╩═════════╝

在DAX中似乎要复杂得多 - 希望有人可以证明我错了!我读过双向过滤可能允许多对多关系,但我无法让它在这里工作。我尝试这样做的原因是加入DAX而不是SQL,因为我有几个语句模板,如果可以通过DAX动态完成,则不希望多个加载具有非常相似的数据。谢谢!

1 个答案:

答案 0 :(得分:2)

是否有任何理由需要Template表,而不是计算的虚拟表?因为仅从示例数据中我看到事实表不必要地重复(7 - > 14行)(可能我错过了一些关键点)。

如果没有,您只需在DAX中编写一些Measures即可在Power BI中进行计算(这正是Power BI的强大功能),并且只需要Fact表。 / p>

<强> DAX:

收入:

Revenue = 
CALCULATE(
    SUM('Fact'[Amount]),
    FILTER(
        'Fact',
        'Fact'[Amount] > 0
    )
)

费用:

Cost = 
CALCULATE(
    SUM('Fact'[Amount]),
    FILTER(
        'Fact',
        'Fact'[Amount] < 0
    )
)

利润:

Profit = [Revenue] + [Cost]

然后,您可以使用Matrix可视化来获得所需的结果:

result

P.S。如果您确实需要将收入/成本/利润放在行而不是列中,则可能需要转动数据或将计算写为新的Column(而不是Measure)。这是由于Power BI中的product limitation