有关联接的 SQL 概念

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

在 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

在此示例中,未引用用户表。只有在需要时才会引入。

如果您移除“用户 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

在本例中,由于从“用户”视图中进行了选择,因此系统会包含联接。

以下示例显示了先前定义的 orders“探索”文件中的 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 COUNT 函数添加了 SQL DISTINCT 关键字。