sql - 当表之间建立关系时,幕后发生了什么?
问题描述
这个问题不仅限于 Power BI,但它会帮助我解释我的问题。
如果您在 Power BI 中有多个表,则可以通过将列从一个表拖到另一个表来建立它们之间的关系,如下所示:
您可以通过单击出现的行来编辑该关系:
顺便说一下,这是两个表的结构:
# Table1
A,B
1,abc
2,def
3,ghi
4,jkl
# Table2
A,C
1,abc
1,def
2,ghi
3,ghit
这很好用,因为 Table1 中的 A 列包含唯一值并且可以用作主键。现在,您可以前往Report tab
,设置两个表格,并通过直接单击 Table1 中的 A 下方或引入切片器来按您的心愿进行切片和骰子:
但问题是你可以在没有建立表之间关系的情况下做到这一点。删除下的关系Relationships
并返回Report
并选择Home > Manage Relationships
以查看我的意思:
正如对话框所说,'There are no relationships defined yet.'
但是您仍然可以像以前一样通过在另一个表中进行选择来对一个表进行子集化(编辑:该语句已在 RADO 的答案中被证明是错误的)。我知道您可以突出显示切片器并选择Format > Edit Interactions
和取消选择与切片器关联的表。但我仍然对整个事情感到困惑。
那么这里是否发生了一些我不知道的事情?或者表之间的关系是否真的由表的内容定义 - 因为跨表的相关值的存在以及潜在主键的存在(无论是自然的还是合成的)使得使用 SQL 查询它们成为可能, dplyr 动词或任何其他形式的查询技术。你真的不需要明确定义的关系吗?
或者换一种说法,Power BI表关系的建立是否有SQL等价物?也许像下面这样:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (ID)
);
对不起,如果我在这里漫无边际,但我只是很困惑。到目前为止,谷歌搜索只会增加混乱。所以感谢您的任何见解!
解决方案
您的陈述“但是您仍然可以像以前一样通过在另一个表中进行选择来对一个表进行子集化”是不正确的。这是这里的一个关键问题。
关系支持在 Power BI 中传播筛选器上下文。这是一个非常重要的短语,如果您打算使用 Power BI,您将必须了解它的含义。这是要理解的最重要的概念。
要明白我的意思,您需要编写 DAX 度量并尝试使用您的表来操作它们。当您有或没有关系时,您会立即看到差异。
整个系统的工作原理(简化):PowerBI 包含一种称为“DAX”的语言。您将在 DAX 中创建度量,然后 PowerBI 会将它们翻译成称为 xmSQL 的内部语言,这是一种特殊的 SQL。在 xmSQL 中,常规连接被转换为 LEFT OUTER JOIN,如下所示:
SELECT SUM(Sales.Amount)
FROM Sales
LEFT OUTER JOIN Customer
ON Sales.Customer_Key = Customer.Customer_Key
双向关系稍微复杂一些,但在概念上相似。
总的来说,当您在表之间创建关系时,您是在告诉 PowerBI 引擎如何连接这些表。然后引擎还添加了一些优化以加快查询速度。每次执行 DAX 度量时,单击切片器或视觉对象,PowerBI 都会在后台生成多个 xmSQL 语句,执行它们,然后将其结果呈现为视觉对象。您可以使用 DAX Studio 等工具查看这些 SQL 查询。
请注意,在 PowerBI 中建立表之间的关系并不是绝对必要的。您可以使用 DAX(以编程方式)模仿相同的行为,但这种“虚拟”关系更复杂,而且速度可能会慢很多。
推荐阅读
- c++ - 如何在 C++ 中使用 lame (mp3->wav) 进行解码
- c - 了解 time_t 调用
- java - 如何在堆栈中找到一个值并使用递归将其放在顶部?
- selenium - 我可以使用 selenium 在网站上单击此元素吗?
- javascript - Greasemonkey - 使用来自其他用户脚本的一个用户脚本(作为 js 库)
- python - 计算我在列表python中删除元素的次数
- javascript - Playwright - 查找多个元素或类名
- python-3.x - 如何让我的 python 脚本根据其设置的模式确定数字是整数还是浮点数?
- powershell - PowerShell 可以替换使用 -clike 找到的区分大小写的文本部分吗?
- if-statement - 'type' object is not subscriptable - IF LOOP ERROR