在 LookML 中使用联接

“合并”功能可让您将不同的数据视图关联起来,以便同时探索多个数据视图中的数据,并了解数据的不同部分之间的关系。

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

以探索开始

联接在模型文件中定义,以建立探索视图之间的关系。“联接”将一个或多个视图与单个“探索”关联(直接或通过其他联接视图连接)。

让我们以两个数据库表为例:order_itemsorders。为两个表生成视图后,请在模型文件的 explore 参数下声明一个或多个视图:

explore: order_items { ... }

order_items 探索运行查询时,order_items 会显示在生成的 SQL 的 FROM 子句中:

SELECT ...
FROM order_items

欢迎加入我们的order_items“探索”专区,了解更多信息。例如,如需添加 order_item 所属的 order 的相关数据,您可以编写如下代码:

explore: order_items {
  join: orders {
    type: left_outer
    relationship: many_to_one
    sql_on: ${order_items.order_id} = ${orders.id} &#59;&#59;
  }
}

上面的 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。

Chat 团队提示:用户最常询问验证错误“未知或无法访问的字段”,这可能是由于缺少联接导致的。如需了解详情,请参阅关于此错误的帮助中心文章

联接参数

联接的四个主要参数为:joinsjointyperelationshipsql_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} &#59;&#59;
  }
}

您还可以编写更复杂的联接。例如,您可能只想联接 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 &#59;&#59;
  }
}

如需详细了解 ${ ... } 语法,请查看替换运算符

第 6 步:测试

转到 Order Items(探索项目)以测试此联接是否按预期运行。您应该会看到 order_itemsorders 中的字段。

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

通过其他视图加入会议

您可以通过其他视图将视图联接到“探索”中。在上面的示例中,您通过 order_id 字段将 orders 加入了 order_items。我们可能还需要将名为 users 的视图中的数据与 order_items 探索合并,即使它们不共用公共字段。为此,您可以通过 orders 视图进行联接。

使用 sql_onforeign_key 加入 usersorders 而非 order_items。为此,请将 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} &#59;&#59;
  }
  join: users {
    type: left_outer
    relationship: many_to_one
    sql_on: ${orders.user_id} = ${users.id} &#59;&#59;
  }
}

多次加入视图

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 使用一种名为“对称聚合”的功能来正确计算聚合(例如求和和平均值),即使联接会导致扇出。对称聚合的简单说明帮助中心文章详细介绍了对称聚合,请参阅SQL 扇出的问题一文,了解它们如何解决扇出问题。

必须提供主键

为了让衡量(汇总)通过联接,您必须在联接所涉及的所有视图中定义主键。

为此,请将 primary_key 参数添加到每个视图中的主键字段定义中:

dimension: id {
  type: number
  primary_key: yes
}

为了正确处理联接的测量,Looker 会要求您指定主键,这些键的值是完全唯一的非 NULL 值。如果您的数据不包含主键,请考虑几个字段的串联是否会导致产生完全唯一的非 NULL 值的主键。如果主键不是唯一的或包含 NULL 值,并且您的查询包含会揭示这些问题的数据,则 Looker 会返回错误(如这篇帮助中心文章中所述)。

支持的 SQL 语言

为了让 Looker 支持 Looker 项目中的对称聚合,您的数据库方言也必须支持它们。下表显示了最新版 Looker 中支持对称聚合的方言:

如果您的方言不支持对称聚合,请在 Looker 中执行联接时要小心,因为某些类型的联接可能会导致聚合(如求和和平均值)不准确。帮助中心的 SQL 扇出问题一文详细介绍了此问题及其解决方法。

详细了解联接

如需详细了解 LookML 中的联接参数,请参阅联接参考文档。