您可以使用联接来关联不同的数据视图,以便同时探索多个数据视图中的数据,并查看数据的不同部分之间的关系。
例如,您的数据库可能包含表 order_items
、orders
和 users
。您可以使用联接同时探索所有表中的数据。本页介绍了 LookML 中的联接,包括特定联接参数和联接模式。
联接功能从“探索”开始
您可以在模型文件中定义联接,从而建立探索和视图之间的关系。合并操作会将一个或多个视图与单个“探索”关联,您可以直接或通过另一个合并的视图连接起来。
假设有两个数据库表:order_items
和 orders
。为两个表生成视图后,在模型文件的 explore
参数下声明一个或多个表:
explore: order_items { ... }
当您从 order_items
“探索”页面运行查询时,order_items
会显示在生成的 SQL 的 FROM
子句中:
SELECT ...
FROM order_items
您还可以加入有关order_items
探索的更多信息。例如,如需添加 order_item
所属的 orders
的相关数据,可执行如下操作:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
}
}
上述 LookML 完成了两项工作。首先,您可以在界面中查看 orders
和 order_items
中的字段:
其次,LookML 介绍了如何将 orders
和 order_items
联接在一起。LookML 可以转换为以下 SQL:
SELECT ...
FROM order_items
LEFT JOIN orders
ON order_items.order_id = orders.id
以下各部分更详细地介绍了这些 LookML 参数。请参阅 join
参数参考页面,详细了解此 LookML 如何转换为 SQL。
聊天团队提示:用户最常问验证错误“未知或无法访问的字段”,这可能是由于缺少联接而导致的。有关详情,请参阅关于此错误的最佳做法页面。
联接参数
用于联接的四个主要参数为:join
、type
、relationship
和 sql_on
。
第 1 步:开始探索
首先,创建 order_items
探索:
explore: order_items { ... }
第 2 步:join
如需联接某个表,必须先在视图中声明它。在此示例中,orders
是模型中的现有视图。
然后,使用 join
参数声明您要将 orders
视图加入 order_items
:
explore: order_items {
join: orders { ... }
}
第 3 步:type
考虑要执行哪个联接的 type
。Looker 支持 LEFT JOIN
、INNER JOIN
、FULL OUTER JOIN
和 CROSS JOIN
。它们对应于 left_outer
、inner
、full_outer
和 cross
的 type
参数值。
explore: order_items {
join: orders {
type: left_outer
}
}
type
的默认值为 left_outer
,通常是热门联接类型。
第 4 步:relationship
定义 order_items
和 orders
之间的联接 relationship
。正确声明联接的 relationship
对 Looker 计算准确的测量值非常重要。这种关系是从 order_items
“探索”到“orders
”视图定义的。可能的选项包括 one_to_one
、many_to_one
、one_to_many
和 many_to_many
。
在此示例中,单个 order
可以有多个 order_items
。order_items
与 orders
之间的关系为 many_to_one
:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
}
}
如果联接中未包含 relationship
,Looker 会默认为 many_to_one
。
如需获得有关如何正确定义联接的 relationship
参数的更多提示,请参阅正确获取 relationship
参数的“最佳实践”页面。
第 5 步:sql_on
声明如何使用 sql_on
或 foreign_key
参数将这两个表联接在一起。我们通常建议采用 sql_on
,因为它可以执行 foreign_key
的所有功能,但通常更易于理解。
sql_on
相当于为查询生成的 SQL 中的 ON
子句。借助此参数,我们可以声明哪些字段应该匹配以执行联接:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
}
}
您还可以编写更复杂的联接。例如,您可能只想联接 id
大于 1000 的订单:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} AND ${orders.id} > 1000 ;;
}
}
如需详细了解这些示例中的 ${ ... }
语法,请查看替换运算符。
第 6 步:测试
转到订单商品探索,测试此联接是否按预期运行。您应该会看到 order_items
和 orders
中的字段。
如需详细了解如何测试 LookML 变更,请参阅模型开发。
通过另一个视图加入
您可以通过另一个视图将某个视图加入“探索”中。在上面的示例中,您通过 order_id
字段将 orders
添加到了 order_items
。此外,即使某个视图没有共享通用字段,我们可能仍希望将名为 users
的视图中的数据联接到 order_items
Discover。为此,您可以通过 orders
视图联接。
使用 sql_on
或 foreign_key
(而非 order_items
)加入 users
。orders
为此,请将 orders
中的字段正确限定为 orders.user_id
。
下面是一个使用 sql_on
的示例:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
}
join: users {
type: left_outer
relationship: many_to_one
sql_on: ${orders.user_id} = ${users.id} ;;
}
}
多次加入视图
users
数据视图包含买方和卖方的数据。要将此视图中的数据合并到 order_items
中,但对于买方和卖方这样做,您可以使用 from
参数两次联接不同的名称(users
)。
借助 from
参数,您可以指定在联接中使用哪个视图,同时为联接指定唯一名称。例如:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
}
join: buyers {
from: users
type: left_outer
relationship: many_to_one
sql_on: ${orders.buyer_id} = ${buyers.id} ;;
}
join: sellers {
from: users
type: left_outer
relationship: many_to_one
sql_on: ${orders.seller_id} = ${sellers.id} ;;
}
}
在这种情况下,只有买方数据会加入 buyers
,而只有卖方数据会加入 sellers
。
注意:users
视图现在必须通过其在联接中的别名名称 buyers
和 sellers
来引用。
限制联接中的字段
借助 fields
参数,您可以指定将探索中的哪些字段联接到探索中。默认情况下,系统会合并视图中的所有字段。不过,您可能只想导入部分字段。
例如,在将 orders
加入 order_items
后,您可能只需要通过联接来添加 shipping
和 tax
字段:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
fields: [shipping, tax]
}
}
您还可以引用一组字段,例如 [set_a*]
。每个集都使用 set
参数在视图中定义。假设您在 orders
视图中定义了以下集合:
set: orders_set {
fields: [created_date, shipping, tax]
}
将 orders
加入 order_items
时,您可以选择仅添加以下三个字段:
explore: order_items {
join: orders {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.order_id} = ${orders.id} ;;
fields: [orders_set*]
}
}
对称聚合
即使联接导致扇出,Looker 也使用一种称为“对称聚合”的功能来正确计算聚合(例如总和和平均值)。了解对称聚合最佳实践页面<ph class="ph-0-0">介绍了对称聚合,SQL 扇出的问题社区帖子中详细介绍了这些扇出问题。
必须提供主键
要通过联接来测量(汇总)操作,您必须在联接所涉及的所有视图中定义主键。
为此,请将 primary_key
参数添加到每个视图中的主键字段定义:
dimension: id {
type: number
primary_key: yes
}
为了正确处理联接的测量,Looker 需要您指定一个值,其中的值是完全唯一的非 NULL 值。如果您的数据不包含主键,请考虑几个字段的串联是否会导致具有完全唯一的非 NULL 值的主键。如果主键不是唯一的或包含 NULL 值,并且查询包含会发现这些问题的数据,Looker 会返回错误:计算唯一值时的主键(或 sql_distinct_key)、值溢出或冲突中所述的错误。
支持的 SQL 语言
为了让 Looker 可以在 Looker 项目中支持对称聚合,您的数据库方言也必须支持它们。下表显示了最新版 Looker 中支持对称聚合的方言:
如果您的方言不支持对称汇总,请在 Looker 中执行联接时要小心谨慎,因为某些类型的联接可能会导致汇总(例如总和和平均值)不正确。SQL 扇出问题社区帖子对此问题及其解决方法进行了详细介绍。
详细了解联接
如需详细了解 LookML 中的联接参数,请参阅联接参考文档。