在 LookML 中使用联接

您可以使用联接来关联不同的数据视图,以便同时探索多个数据视图中的数据,并查看数据的不同部分之间的关系。

例如,您的数据库可能包含表 order_itemsordersusers。您可以使用联接同时探索所有表中的数据。本页介绍了 LookML 中的联接,包括特定联接参数和联接模式。

联接功能从“探索”开始

您可以在模型文件中定义联接,从而建立探索视图之间的关系。合并操作会将一个或多个视图与单个“探索”关联,您可以直接或通过另一个合并的视图连接起来。

假设有两个数据库表:order_itemsorders。为两个表生成视图后,在模型文件的 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 完成了两项工作。首先,您可以在界面中查看 ordersorder_items 中的字段:

其次,LookML 介绍了如何将 ordersorder_items 联接在一起。LookML 可以转换为以下 SQL:

SELECT ...
FROM order_items
LEFT JOIN orders
ON order_items.order_id = orders.id

以下各部分更详细地介绍了这些 LookML 参数。请参阅 join 参数参考页面,详细了解此 LookML 如何转换为 SQL。

聊天团队提示:用户最常问验证错误“未知或无法访问的字段”,这可能是由于缺少联接而导致的。有关详情,请参阅关于此错误的最佳做法页面

联接参数

用于联接的四个主要参数为:jointyperelationshipsql_on

第 1 步:开始探索

首先,创建 order_items 探索:

explore: order_items { ... }

第 2 步:join

如需联接某个表,必须先在视图中声明它。在此示例中,orders 是模型中的现有视图。

然后,使用 join 参数声明您要将 orders 视图加入 order_items

explore: order_items {
  join: orders { ... }
}

第 3 步:type

考虑要执行哪个联接的 type。Looker 支持 LEFT JOININNER JOINFULL OUTER JOINCROSS JOIN。它们对应于 left_outerinnerfull_outercrosstype 参数值。

explore: order_items {
  join: orders {
    type: left_outer
  }
}

type 的默认值为 left_outer,通常是热门联接类型。

第 4 步:relationship

定义 order_itemsorders 之间的联接 relationship。正确声明联接的 relationship 对 Looker 计算准确的测量值非常重要。这种关系是从 order_items“探索”到“orders”视图定义的。可能的选项包括 one_to_onemany_to_oneone_to_manymany_to_many

在此示例中,单个 order 可以有多个 order_itemsorder_itemsorders 之间的关系为 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_onforeign_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_itemsorders 中的字段。

如需详细了解如何测试 LookML 变更,请参阅模型开发

通过另一个视图加入

您可以通过另一个视图将某个视图加入“探索”中。在上面的示例中,您通过 order_id 字段将 orders 添加到了 order_items。此外,即使某个视图没有共享通用字段,我们可能仍希望将名为 users 的视图中的数据联接到 order_items Discover。为此,您可以通过 orders 视图联接。

使用 sql_onforeign_key(而非 order_items)加入 usersorders为此,请将 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 视图现在必须通过其在联接中的别名名称 buyerssellers 来引用。

限制联接中的字段

借助 fields 参数,您可以指定将探索中的哪些字段联接到探索中。默认情况下,系统会合并视图中的所有字段。不过,您可能只想导入部分字段。

例如,在将 orders 加入 order_items 后,您可能只需要通过联接来添加 shippingtax 字段:

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 中的联接参数,请参阅联接参考文档。