纳入 SQL 并引用 LookML 对象

如需编写功能强大的 LookML,您需要能够引用现有维度、测量、视图或派生表,即使它们不在当前范围内也是如此。您还需要引用底层表中的列,并使用数据库方言的函数调用来操纵这些值。

替换运算符 ($)

替换运算符“$”可让 LookML 代码更具可重用性和模块化,使您能够引用其他视图和派生表、SQL 表中的列或 LookML 维度和测量。这有两方面好处。首先,您可能已经设计出了一个非常棘手的维度或测量,因此无需再次编写所有复杂内容。其次,如果您更改了维度或测量的某些内容,该更改可以传播到依赖于它的所有其他内容。

您可以通过多种方式使用替换运算符:

${TABLE}.column_name 引用与您正在使用的视图关联的表中的列。例如:

dimension: customer_id {
  type: number
  sql: ${TABLE}.customer_id ;;
}

${field_name} 引用您正在使用的视图中的维度或测量。例如:

measure: total_population {
  type: sum
  sql: ${population} ;;
}

${view_name.field_name} 引用另一个视图中的维度或测量。例如:

dimension: lifetime_orders {
  type: number
  sql: ${user_order_facts.lifetime_orders} ;;
}

${view_name.SQL_TABLE_NAME} 引用另一个视图或 派生表。请注意,此引用中的 SQL_TABLE_NAME 是字面量字符串;您无需将其替换为任何内容。例如:

explore: trips {
  view_label: "Long Trips"
  # This will ensure that we only see trips that are longer than average!
  sql_always_where: ${trips.trip_duration}>=(SELECT tripduration FROM ${average_trip_duration.SQL_TABLE_NAME});;
}

${view_name.SQL_TABLE_NAME} 不适用于与 数据组 一起使用的 sql_trigger 参数。

范围和命名

您可以为探索、视图、字段和集命名。这些 Looker 标识符的编写不带引号。

LookML 字段和集具有 完整名称短名称

  • 完整名称的格式为 <view>.<field-name | set-name>。左侧表示范围,即包含字段或集的视图。右侧指定特定的字段或集名称。
  • 短名称的格式为 <field-name | set-name>,不带分隔 句点。Looker 会使用短名称的使用范围将其展开为完整名称。

以下示例展示了多种形式的名称和范围。这是一个不切实际的字段组,但展示了各种可能的范围表达式。

view: orders {                   # "orders" becomes the containing scope
  measure: count {               # short name, equivalent to orders.count
    type: count
  }
  dimension: customer_id {       # short name, equivalent to orders.customer_id
    type: number
    sql: ${TABLE}.customer_id ;;
  }
  dimension: customer_address {  # short name, equivalent to orders.customer_address
    sql: ${customer.address} ;;  # full name, references a field defined in the "customer" view
  }
  set: drill_fields {            # short name, equivalent to orders.drill_fields
    fields: [
      count,                     # short name, equivalent to orders.count
      customer.id                # full name, references a field defined in the "customer" view
    ]
  }
}

dimension: customer_address 声明中,请注意 SQL 块 (customer) 的底层视图与封闭视图范围 (orders) 不同。如果您需要在两个不同视图之间比较字段,这会很有用。

当视图(我们将其称为“视图 A”)引用在不同视图(我们将其称为“视图 B”)中定义的字段时,请注意以下几点:

  1. 视图 B 文件必须使用 include 参数包含在与视图 A 相同的模型中。
  2. 视图 B 必须在一个或多个探索中联接到视图 A。如需了解联接,请参阅LookML 中的联接使用入门页面。

SQL 方言

Looker 支持多种数据库类型,例如 MySQL、Postgres、Redshift 和 BigQuery。每个数据库都支持略有不同的特征集,并且具有不同的函数名称,我们将其称为 SQL 方言

LookML 旨在与所有 SQL 方言搭配使用,并且 LookML 不偏好任何一种方言。不过,您需要在某些 LookML 参数中添加 SQL 代码表达式(称为 SQL 块)。借助这些参数,Looker 会将 SQL 表达式直接传递给您的数据库,因此您必须使用与数据库匹配的 SQL 方言。例如,如果您使用 SQL 函数,则该函数必须是数据库支持的函数。

SQL 块

某些 LookML 参数要求您提供原始 SQL 表达式,以便 Looker 了解如何从数据库检索数据。

sql_ 开头的 LookML 参数需要某种形式的 SQL 表达式。例如:sql_always_wheresql_onsql_table_name。SQL 块最常见的 LookML 参数是 sql,它在维度和测量字段定义中使用,用于指定定义维度或测量的 SQL 表达式。

您在 SQL 块中指定的代码可以只是一个字段名称,也可以像相关子选择一样复杂。内容可能非常复杂,几乎可以满足您在原始 SQL 中表达自定义查询逻辑的任何需求。请注意,您在 SQL 块中使用的代码必须与数据库使用的 SQL 方言 匹配。

维度和测量的 SQL 块示例

以下是维度和测量的 SQL 块示例。LookML 替换运算符 ($) 可以使这些 sql 声明看起来与 SQL 非常不同。不过,在替换发生后,生成的字符串是纯 SQL,Looker 会将其注入到查询的 SELECT 子句中。

dimension: id {
  primary_key: yes
  sql: ${TABLE}.id ;;   # Specify the primary key, id
}
measure: average_cost {
  type: average
  value_format: "0.00"
  sql: ${order_items.cost} ;;   # Specify the field that you want to average
}
dimension: name {
  sql: CONCAT(${first_name}, ' ', ${last_name}) ;;
}
dimension: days_in_inventory {
  type: int
  sql: DATEDIFF(${sold_date}, ${created_date}) ;;
}

如最后两个维度所示,SQL 块可以使用底层数据库支持的函数(例如,本示例中的 MySQL 函数 CONCATDATEDIFF)。

包含相关子选择的 SQL 块示例

您可以将任何 SQL 语句放在字段的 SQL 块中,包括相关子选择。下面给出了一个示例:

view: customers {
  dimension: id {
    primary_key: yes
    sql: ${TABLE}.id ;;
  }
  dimension: first_order_id {
    sql: (SELECT MIN(id) FROM orders o WHERE o.customer_id=customers.id) ;;
         # correlated subselect to derive the value for "first_order_id"
  }
}

派生表的 SQL 块示例

派生表使用 SQL 块来指定派生表的查询。下面给出了一个示例:

view: user_order_facts {
  derived_table: {
    sql:            # Get the number of orders for each user
      SELECT
        user_id
        , COUNT(*) as lifetime_orders
      FROM orders
      GROUP BY 1 ;;
  }
  # later, dimension declarations reference the derived column(s)

  dimension: lifetime_orders {
    type: number
  }
}

LookML 字段类型引用

当您在另一个字段中引用现有 LookML 字段时,可以使用双冒号 (::) 后跟所选类型,指示 Looker 将引用的字段视为特定数据类型。例如,如果您在另一个字段中引用 orders.created_date 维度,则可以使用语法 ${orders.created_date::date} 来确保 created_date 字段在 Looker 生成的 SQL 中被视为日期字段,而不是转换为字符串。

您可以在引用中使用的数据类型取决于您引用的原始字段的数据类型。例如,如果您引用的是字符串字段,则只能指定 ::string 数据类型。以下是您可以为每种类型的字段使用的允许字段类型引用的完整列表:

  • 在对字符串字段的引用中,您可以使用 ::string
  • 在对数字字段的引用中,您可以使用 ::string::number
  • 在对日期或时间字段的引用中,您可以使用 ::string::date::datetime

    使用 ::string::date 的引用以查询时区返回数据,而使用 ::datetime 的引用以数据库时区返回数据。
  • 在对 yesno 字段的引用中,您可以使用 ::string::number::boolean

    对于不支持布尔数据类型的数据库方言,无法使用 ::boolean 类型的字段引用。
  • 在对位置字段的引用中,您可以使用 ::latitude::longitude

将 LookML 字段类型引用与日期字段搭配使用

例如,假设您有一个 enrollment_month 维度和一个 graduation_month 维度,这两个维度都是在 维度组中创建的 type: time。在本示例中,enrollment_month 维度由以下 type: time 的维度组生成:


dimension_group: enrollment {
  type: time
  timeframes: [time, date, week, month, year, raw]
  sql: ${TABLE}.enrollment_date ;;
}

同样,graduation_month 维度由以下 type: time 的维度组创建:


dimension_group: graduation {
  type: time
  timeframes: [time, date, week, month, year, raw]
  sql: ${TABLE}.graduation_date ;;
}

使用 enrollment_monthgraduation_month 维度,您可以通过创建 维度组type: duration来计算学生入学和毕业之间经过的月数或年数。不过,由于某些日期字段在 Looker 生成的 SQL 中被转换为字符串,因此将 enrollment_monthgraduation_month 维度设置为 sql_startsql_end 的值可能会导致错误。

为避免因这些时间字段被转换为字符串而导致错误,一种方法是创建 type: duration 的维度组,并在 sql_startsql_end 参数中引用 enrollmentgraduation 维度组中的 raw 时间范围:


dimension_group: enrolled {
  type: duration
  intervals: [month, year]
  sql_start: ${enrollment_raw} ;;
  sql_end: ${graduation_raw} ;;
}

在“探索”界面中,这会生成一个名为 Duration Enrolled 的维度组,其中包含各个维度 Months EnrolledYears Enrolled

type: duration 的维度组中使用 raw 时段的更简单替代方案是,为 sql_startsql_end 参数中引用的字段指定 ::date::datetime 引用类型。


dimension_group: enrolled {
  type: duration
  intervals: [month, year]
  sql_start: ${enrollment_month::date} ;;
  sql_end: ${graduation_month::date} ;;
}

本示例中的 LookML 还会创建一个 Duration Enrolled 维度组,但使用 ::date 引用允许使用 enrollment_monthgraduation_month 维度,而无需使用 raw 时间范围或使用 SQL 将其转换为字符串。

如需查看有关如何使用 LookML 字段类型引用创建自定义维度组的type: duration其他示例,请参阅 dimension_group 参数文档页面。

此语法不适用于 type: list 的测量,自 Looker 6.8 起无法引用此类测量。

LookML 常量

借助 constant 参数,您可以指定可在整个 LookML 项目中使用的常量。借助 LookML 常量,您可以定义一次值,并在项目中接受字符串的任何部分引用该值,从而减少 LookML 代码中的重复。

常量必须在项目清单文件中声明,并且常量的值必须是字符串。例如,您可以按如下方式定义值为 "Okayama" 的常量 city

constant: city {
  value: "Okayama"
}

然后,您可以使用语法 @{city} 在整个项目中引用 city 常量。例如,您可以在 users 探索中使用 city 常量和 label 参数:


explore: users {
  label: "@{city} Users"
}

然后,Looker 会在探索 菜单和探索的标题中显示 Okayama Users ,而不是默认的 Users

如需了解详情以及如何使用 LookML 常量编写可重用代码的示例,请参阅 constant 参数文档页面。