有关联接的 SQL 概念

与 SQL 中一样,LookML 中的 join 用于根据两个或多个表之间的相关列来合并这些表中的行。

在 LookML 中,探索(由 explore LookML 参数定义)用于定义用户可以查询数据的方式。探索至少包含一个视图或一组联接在一起的视图。探索中的主视图始终包含在查询中。通常情况下,只有在需要满足查询时才会包含联接视图。

LookML 视图对应于数据库中的 SQL 表(或具有表结构的其他元素),或对应于派生表。视图定义了数据库中可用的字段或列,以及应如何访问这些字段或列。

以下示例是 orders 探索的定义。

explore: orders {
  join: users {
    type: left_outer
    sql_on: ${orders.user_id} = ${users.id} ;;
    relationship: many_to_one
  }
}

orders 视图(即“探索”中的主要视图)正通过 SQL LEFT OUTER JOINusers 视图联接,如 type: left_outer LookML 参数所示。由 sql_on LookML 参数定义的 SQL ON 子句不使用 table_alias.column,而是引用 to ${view_name.field_name}。这样一来,如果数据库中的表名称或列名称发生更改,只需在一个位置进行更改即可。

relationship 参数非常重要。联接可能会导致行重复的扇出问题。通过指定多笔订单将仅加入一位用户,Looker 可以识别出此联接不会发生扇出,因此无需特殊处理。不过,one_to_many 关系可能会触发扇出。

默认情况下,自动生成的视图和探索使用左外部联接。不过,在前面的示例中,每个订单很可能都只有一个用户,因此该示例中的联接可以是内部联接。

如需查看探索生成的 SQL,您可以在界面中运行探索,然后选择数据面板中的 SQL 标签页。

例如,如果您打开之前定义的订单探索,然后选择用户 ID数量字段,生成的 SQL 将如下所示:

SELECT
    `user_id` AS `orders.user_id`,
    COUNT(*) AS `orders.count`
FROM
    `thelook`.`orders` AS `orders`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

在此示例中,根本没有引用 users 表。只有在需要时才会引入。

如果您移除用户 ID 维度,并从用户视图中添加 ID 维度,则 SQL 将如下所示:

SELECT
    `users`.`id` AS `users.id`,
    COUNT(*) AS `orders.count`
FROM
    `thelook`.`orders` AS `orders`
    INNER JOIN `thelook`.`users` AS `users` ON `orders`.`user_id` = `users`.`id`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

在这种情况下,由于 Users 视图中存在选择,因此会包含联接。

以下示例展示了之前定义的 orders Explore 文件中的 LookML,并向 order_items 视图添加了联接:

explore: orders {
  join: users {
    type: inner
    sql_on: ${orders.user_id} = ${users.id} ;;
    relationship: many_to_one
  }
  join: order_items {
    type: inner
    sql_on: ${orders.id} = ${order_items.order_id} ;;
    relationship: one_to_many
  }
}

现在,如果您在界面中打开订单探索,就会看到订购商品数视图。如果您从订单项视图中选择总销售价格度量,同时从订单中选择数量,并从用户中选择 ID,Looker 会生成以下 SQL:

SELECT
    `users`.`id` AS `users.id`,
    COUNT(DISTINCT orders.id ) AS `orders.count`,
    COALESCE(SUM(`order_items`.`sale_price`), 0) AS `order_items.total_sale_price`
FROM
    `thelook`.`orders` AS `orders`
    INNER JOIN `thelook`.`users` AS `users` ON `orders`.`user_id` = `users`.`id`
    INNER JOIN `thelook`.`order_items` AS `order_items` ON `orders`.`id` = `order_items`.`order_id`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

在此示例中,COUNT(*) AS orders.count 变为 COUNT(DISTINCT orders.id ) AS orders.count。Looker 检测到可能存在扇出情况,并自动将 SQL DISTINCT 关键字添加到了 SQL COUNT 函数中。