分析如何适用于使用关系的多表数据源
使用具有多个相关表的数据源会影响分析在 Tableau 中的工作方式。由于多个关联的表具有独立的域并保留其本机详细级别,因此当您将字段拖到视图中时:
- 系统将在数据的自然详细级别对数据进行查询。
- 仅查询与可视化项相关的数据。
- 表之间的关系会影响查询的结果。生成可视化项的流程可能因字段表在数据模型中彼此相关的方式或它们是否没有直接相关而异。
有关数据源增强功能的概述以及使用关系的简介,请观看这个时长 5 分钟的视频。
注意:本视频和本主题中显示的用于编辑关系的界面与当前版本略有不同,但具有相同的功能。
在不要害怕关系和以下 Tableau 博客文章中详细了解关系的工作方式:
另请参见 Action Analytics(链接在新窗口中打开) 中有关关系的视频播客,例如为什么 Tableau 发明了关系?(链接在新窗口中打开)单击 Library(库)(链接在新窗口中打开)中的“Video Podcast”(视频播客)以查看更多信息。
在 Tableau 版本 2024.2 及更高版本中,Tableau 数据模型支持多事实分析和通过多事实关系共享维度。有关详细信息,请参见关于多事实关系数据模型(链接在新窗口中打开)、何时使用多事实关系模型(链接在新窗口中打开)和构建多事实关系数据模型(链接在新窗口中打开)。
注意:您仍然可以在 Tableau 中创建单表数据源。您可以使用联接、并集、自定义 SQL 等的组合来构建逻辑表。Tableau 中单表分析的行为未改变。对包含维度和度量混合的单个逻辑表进行分析的工作方式与 Tableau 2020.2 之前的版本一样。
分析注意事项
验证关系
有几个选项可用于验证数据模型以进行分析。为数据源创建模型时,我们建议转到工作表,选择该数据源,然后构建可视化项以浏览记录计数、预期数据、不匹配值、null 或重复的度量值。尝试跨不同的表处理字段,以确保所有内容都符合您的预期。
要查找的内容:
- 数据模型中的关系是否为它们的表使用正确的匹配字段?
- 添加多个匹配字段对是否会使关系更准确?
- 将不同的维度和度量拖到视图中会产生什么结果?
- 您是否看到预期的行数?
- 如果从默认设置更改了任何性能选项设置,则您在可视化项中看到的值是否符合预期?如果不符合,您可能需要检查设置,或重置为默认值。
用于验证关系和数据模型的选项:
- 每个表以名为 TableName(Count)的字段的形式在该表的详细级别包括其记录的计数。若要查看表的计数,请将其“计数”字段拖到视图中。若要查看所有表的计数,请在“数据”窗格中选择每个表的“计数”字段,然后在“智能显示”中单击“文本表”。
- 在“数据”窗格中单击“查看数据”以查看每个表的行数和数据。此外,在开始创建关系之前,在分析之前或期间查看数据源中数据对于让您了解每个表的范围非常有用。有关详细信息,请参见查看基础数据。
- 将维度拖到行上以在状态栏中查看行数。若要查看不匹配的值,请单击“分析”菜单,然后选择“表布局”>“显示空行”或“显示空列”。您还可以将不同的度量从可视化项中呈现的其中一个表拖到视图,例如 <YourTable>(Count) 。这可确保从该表中看到维度的所有值。
提示:如果要查看为关系生成的查询,可以使用 Tableau Desktop 中的性能记录器。
- 单击“帮助”菜单,然后选择“设置和性能”>“启动性能记录”。
- 将字段拖到视图中以构建可视化项。
- 单击“帮助”菜单,然后选择“设置和性能”>“停止性能记录”。“性能记录”工作簿将自动打开。
- 在“性能摘要”仪表板中的“按时间排序的事件”下,单击“正在执行的查询”栏并查看下面的查询。
另一个更高级的选项是使用 GitHub 上的 Tableau 日志查看器(链接在新窗口中打开)。您可以使用 end-protocol.query
筛选特定关键字。有关详细信息,请从 GitHub 中的 Tableau 日志查看器 wiki 页面(链接在新窗口中打开)开始。
仅维度可视化项
将多表数据源与相关表一起使用时:如果构建仅维度可视化项,Tableau 将使用内部联接,并且您将看不到完整的不匹配域。
若要查看维度值的部分组合,您可以:
- 使用“显示空行/显示空列”来查看所有可能的行。单击“分析”菜单,然后选择“表布局”>“显示空行”或“显示空列”。请注意,此设置还会触发日期和数字数据桶字段的密实化,这可能是不需要的。
- 将度量从可视化项中呈现的一个表添加到视图,例如 <YourTable>(Count) 。这可确保从该表中看到维度的所有值。
有关详细信息,另请参见可能让您惊讶的维度的不匹配值行为和多表分析疑难解答。
何时使用 LOD 计算和表达式
由于 Tableau 可理解输入表的详细级别 (LOD),因此应该无需使用 LOD 计算来消除由于联接而导致的不需要的重复。
您可能仍然希望使用 LOD 计算来:
- 处理源表中不需要的重复。
- 计算多级聚合(例如,总和的平均值)
- 进行群组分析(例如计算每个客户的第一个订单日期)
如果 LOD 计算的维度包含单个表中的字段,则该 LOD 计算将显示在“数据”窗格中其所属的表中。
多表分析的示例
以下一组示例演示如何跨多个相关表查询数据。此多表数据源包含演员在不同电影角色中的外观的简短列表。
“Appearances”(扮演的角色)表中的行表示演员在特定影片中扮演特定角色。在此数据集中,参与者可以具有零个或多个外观。
在以下 Tableau 博客文章中详细了解关系的工作方式:
示例 1:对联接数据与相关数据中单个问题的分析
在 2020.2 之前连接到 Tableau 中的数据时,数据源可以由单个表或多个表组成,这些表已联接或合并到单个非规范化表中。从 Tableau 2020.2 开始,Tableau 可识别并保留多表数据源的规范化数据,其中的表数据保持独立,并且每个表都保持本机详细级别。下面的示例显示了单表和多表数据源之间的分析差异。
此示例显示三个电影数据表:“Appearances”(扮演的角色)、“Actors”(演员)和“Movies”(电影)。
这些表可以联接在一起:按“Actor = Actor”将“Appearances”(扮演的角色)表与“Actors”(演员)表联接,并按“Movie = Movie”将“Appearances”(扮演的角色)表与“Movies”(电影)表联接。如果联接是完全外部联接,因此不会丢失任何行,则最终输出如下所示。请注意,联接子句中使用的字段会显示两次。
以这种方式合并到单个表中的数据称为非规范化数据或拼合数据。
这种联接的数据是拼合数据。每行都由一个演员在电影中扮演的角色组成(因此 John Rhys-Davies 在《Return of the King》(国王归来)中有两行,因为他扮演了两个角色);因此,数据的粒度位于影片中角色的级别。在多行中相关的信息会重复。《Return of the King》(国王归来)首映日期出现了两次,因为数据集中的该电影有两个角色。John Rhys-Davies 的身高列出了五次,因为对于他的演员身份,共有 5 个独特的角色/电影组合。
因此,此拼合数据具有一些需要注意的特征。举例来说,如果您希望按演员电影的平均总收入来绘制演员的身高,您可能会假设我们可以将“Height”(身高)引入“列”,并将“Gross”(总收入)引入“行”,然后对“Gross”(总收入)取平均值。但是,如果您这样做,默认视图看起来将不正确。在这里,John Rhys-Davies 应该会有 925 厘米高,超过了 30 英尺!
这是因为默认聚合为 SUM。对于 John Rhys-Davies 共有 5 个数据行,所以我们获取了他的真实高度 185 厘米五次。您可以通过更改对“Height”(高度)的聚合(例如更改为平均值或最小值)来解决此问题。这实际上只返回一行的值(因为它们都相同)。
更改聚合时,身高将会要更加确切。但现在您需要注意平均总收入。请记住,Tableau 会考虑表示 John Rhys-Davies 身高的全部五行。当您考虑他所拍的电影的平均总收入时,它不应该是五个行的平均值,而应该是三部电影的平均值。您不想仅仅因为他在《Return of the King》(国王归来)中扮演两个角色就计算两次总收入。但事实果真如此吗?
通过进行一些快速的数学计算,我们可以知道:《Lord of the Rings》(指环王)电影应具有的平均值为 (869 + 923 + 1119)/3,即 $970.3。但是,散点图中的值为 $990.6。当前平均值来自五个行: (869 + 923 + 923 + 1119 + 1119)/5。
这与通过更改聚合修复身高问题一样容易修复。您需要使用详细级别 (LOD) 表达式来更改 Tableau 查看的详细级别,从默认的“Appearance”(扮演的角色)更改为“Movie”(电影)级别。您可以为“LOD Gross”(LOD 总收入)创建一个 FIXED [Movie] : MIN([Gross (USD millions)])} 形式的计算,然后针对我们的视图获取这个新“LOD Gross”(LOD 总收入)字段的平均值。
LOD 表达式可以解读为“对于每部电影,返回其最低总收入”。这消除了重复问题,因为即使构建的视图包含电影和演员,也始终会按电影返回总收入。
现在数字是正确的。John Rhys-Davies 身高 185 厘米,他所出演电影在这个数据集中的平均总收入为 970.3。您需要了解数据的重复方式,以及 Tableau 如何聚合数据以显示数据,然后才能确保返回正确的值。
多个表中的规范化数据
在逻辑表之间创建关系可能看起来类似于创建联接,但是 Tableau 并没有将数据拼合为单个表(包含可能必需的所有重复项),而是保留了表之间的关系。系统会以适当的详细级别从每个表中提取信息,并与其他数据相关。
在“数据源”页面上,您不会看到拼合表的“完整”网格视图。它并不存在。Tableau 会按原样保留所有三个表,并且仅建立关系,同时根据视图需求将所需的数据汇集在一起。
若要创建相同的散点图,请将“Height”(身高)和“Gross”(总收入)拖到视图中,并将“Gross”(总收入)设置为平均值。就是这样!Tableau 查看每个表的数据与来自其他相关表的数据的关联方式,并推断应如何显示身高(通过演员)和如何计算平均总收入(通过电影)。
示例 2:单个表中的维度
如果可视化项中的维度来自单个表,Tableau 仅会查询一个表并显示整个域的结果。您可以添加度量值,并仍可看到整个域。
例如,使用上面介绍的“Movie Appearances”(扮演的电影角色)数据源,将“Actor”(演员)字段添加到可视化项会生成以下可视化项:
由于可视化项中的唯一维度来自“Actors”(演员)表,因此 Tableau 将仅针对“Actors”(演员)表运行查询。出现在“Actors”(演员)表中的所有演员都显示在可视化项中,无论他们是否有任何“Appearances”(扮演的角色)。
将“Appearance Actor”(演员扮演的角色)字段作为度量值引入视图中,然后应用 COUNT 聚合将创建显示演员扮演的角色的数量。请注意,Sigourney Weaver 没有任何扮演的角色,但她的名字仍然在视图中。
示例 3:多个表中的维度
如果视图中的维度来自多个表,Tableau 将查找与所有维度相关的表,并显示该表中的域。因此,您在示例 1 中看到的某些维度值会发生变化。
例如,将“Movies ”(电影)表中的字段拖动到可视化项中会更改查询。由于“Movies”(电影)和“Actors”(演员)表通过“Appearances”(扮演的角色)表相关,因此查询仅返回“Appearances”(扮演的角色)表中存在的“Actor/Movie”(演员/电影)对。
由于 Sigourney Weaver 在此数据集中没有任何“Appearances”(扮演的角色)(并因此未与数据集中的任何影片相关),则“Actor/Movie”(演员/电影)对不会显示她:
示例 4:无法由维度拆分的度量
如果某个度量无法由维度拆分,Tableau 会跨该维度复制该度量。
下一个可视化项显示电影的总收入金额。由于这两个字段都来自“Movies”(电影)表,因此 Tableau 将仅查询“Movies”(电影)表。
“Movies”(电影)表包括每部电影的已聚合总收入,如以下可视化项所示(创建此数据集时,《Infinity War》(无限战争)的总收入不可用,显示为零)。
如果您将“Actor”(演员)添加到此可视化项时,Tableau 知道它不能按“Actor”(演员)细分电影总收入,因为数据模型中没有这种更精细的信息。相反,Tableau 会显示每部电影的电影总收入,这些收入在演员之间重复。
示例 5:未与度量分层相关的维度
从上一个可视化项中移除“Movie”(电影)维度会查询每名演员的“Movie Gross”(电影总收入)度量的总和。结果是该演员出演的每部电影的聚合电影总收入。
在这种情况下,维度“Actor”(演员)和度量“Movie Gross”(电影总收入)之间不存在分层关系,多名演员可能出现在同一部电影中。例如,Benedict Cumberbatch 和 Chris Hemsworth 都出现在《Dr. Strange》(奇异博士)中。在这种情况下,Tableau 会将《Dr. Strange》(奇异博士)的电影总收入包括在这两名演员的总计中。
由于相同的电影总收入值包含在多名演员的总计中,因此 Tableau 将不会直接对这些值进行求和。
但是,当显示此可视化项的总计时,请注意,Tableau 会正确运算电影总收入,而不包括重复的电影。
多表分析疑难解答
对于多表相关表,可以会出现以下情况。下表描述了有关如何对分析进行故障排除的已知方案和高级说明。
分析情况 | 描述 | |
---|---|---|
针对仅维度可视化项的内部联接 | 当您向同一视图添加多个维度时,您可能不会立即看到预期的所有值。或者,您可能会注意到,从其他表向可视化项中添加新维度会导致某些值从可视化项中消失。 Tableau 将使用保留数据中实际存在的值组合的查询。这意味着,您将看到由向可视化项提供维度的表的内部联接生成的行。 如果要查看维度值的部分组合,您可以启用“显示空行/列”以查看所有可能的行,也可以从视图中呈现的表之一添加度量(例如 <MyTable>(Count)),以确保从该表中看到维度的所有值。 | |
计算中的常量 | 在多表数据源中,常量值的行为就像来自具有单个行的自己的表一样。如果聚合常量值,则其行为将像聚合位于单个行上一样。Sum(10) 将始终等于 10。Avg(10) 也将始终等于 10。Count(10) 将始终等于 1。 为了确保向后兼容性,单逻辑表数据源上的常量值的行为将像为表中的每个值复制常量值一样。 行级别计算中的常量不会更改计算的行详细级别。计算“[Sales] + 10”的行为就像它与“[Sales]”(销售额)字段来自同一个表一样。 | |
强制外部联接 | Tableau 确保所有度量值都(连同数据中实际出现的所有维度组合)呈现在可视化项中,因此,如果要确保看到数据中的所有可能值(包括“不匹配的 null”),则可以通过将度量从工作表中的每个表引入视图来达到此目的。 | |
我没有看到预期将从交叉表计算得出的度量值 | 计算的域是其输入的内部联接。如果度量计算的所有输入中没有匹配值,则它们将不会包含在度量计算中。 在创建行级别计算之前,请考虑使用 LOD 计算将度量值移到同一对象。 | |
在不同逻辑表的字段之间切换的计算会产生意外的结果 | 如果计算在行级别字段之间切换(使用 case 语句、if 语句或类似“IFNULL”的函数),则可能会看到意外的结果,因为计算结果是为每一行计算的,其中行是计算输入之间的内部联接。 更好的方法是在聚合值之间切换,而不是尝试在行级别计算内切换。这还将在单个表方案中产生更好的性能。 或者,这只是跨表计算的一个问题,因此使用 LOD 计算将所有字段同一个表也是可行的。 不要这样做: SUM(
IF [Parameter] == "Foo" THEN [Field 1] ELSE [Field 2] END
)
这样做: IF [Parameter] == "Foo" THEN SUM([Field 1]) ELSE SUM([Field 2]) END | |
意外的不匹配 null | 您可能会看到与非预期 null 维度值关联的度量值。这可能表示数据源中的关系配置不正确。它还可能表示包含度量的表中存在实际不匹配的值,这些值在维度表中没有对应的行。 过去,如果选择了错误的联接类型,此数据可能会丢失。使用关系时,将保留这些不匹配的值。如果不想看到不匹配的值,可以使用筛选器将其排除。 | |
聚合值不正确 | 是使用关系还是联接?对于关系,默认情况下可正确计算聚合。使用联接时,可能需要编写 LOD 计算来以对值进行去重处理。 您是否错误地在关系上设置了性能选项?请尝试将性能选项重置为默认值,并查看这样是否会生成正确的聚合。 | |
维度会复制度量值,而不是将它们分区。 维度筛选器不包含度量。 | 检查用于定义关系的字段是否正确。 | |
Tableau 生成的查询太多,或生成的查询具有多个左联接 | 检查日志或性能记录,了解生成了多少查询以及使用了多少左联接。借助新的数据建模功能,Tableau 会生成具有左联接的查询和/或其他查询,以确保可视化项中始终包含不匹配的度量值。如果不需要查看不匹配的值,请使用筛选器从可视化项中移除不匹配的 (NULL) 值。这应该会减少生成的查询数。 如果您知道数据没有任何不匹配的值,则可以在性能选项中将每个关系的引用完整性设置设为“所有值匹配”。这也会减少生成的查询数。 您还可以降低可视化项的复杂性,以减少生成的查询数。移除度量和隐藏筛选器控件是简化查询多表相关数据的关键方法。 | |
查询有多个子查询 | 检查日志或性能记录,查看 Tableau 生成的查询的复杂性。 Tableau 会自动生成子查询以在必要时以对数据进行去重处理,从而生成正确的聚合。这与 LOD 计算生成的查询类似。 如果您知道数据中的逻辑表之间的关系具有多对一或一对一关联基数,则可以在关系性能选项中设置此关联基数信息。这将允许 Tableau 消除不必要的子查询,因为它知道不会发生重复。 | |
我过去使用联接来筛选数据 | 在 2020.2 中,Tableau 将努力恢复不匹配的值。有时,这意味着,在您可能指定了内部联接来以有意筛选出数据的情况下,它将使用左联接 如果筛选出通过此联接引入的不匹配的值,Tableau 将能够优化查询,使其恢复为使用内部联接。 根据您的特定方案,将这种内部联接建模为逻辑表中的物理联接可能是有意义的。如果使用包含度量的表来筛选维度表,则此功能尤其强大,因为它不会引入额外的度量复制。 |