合并 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} 无法使用与 datagroups 搭配使用的 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 文件必须与视图 A 包含在同一模型中,并使用 include 参数。
  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(&#42;) 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} ;;
}

在“探索”界面中,系统会生成一个名为“注册时间”的维度组,其中每个维度都包含“注册月数”和“注册年份”。

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 还创建了“时长已注册”维度组,但借助 ::date 引用,您无需使用 raw 时间范围,也无需使用 SQL 将其转换为字符串,便可使用 enrollment_monthgraduation_month 维度。

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

此语法不适用于 type: list 的衡量方法,从 Looker 6.8 开始,便无法引用后者。

LookML 常量

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

常量必须在项目清单文件中声明,常量的值必须是字符串。例如,您可以定义一个值为 "Okayama" 的常量 city,如下所示:

constant: city {
  value: "Okayama"
}

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


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

然后,Looker 会在探索菜单和“探索”标题中显示探索山用户,而非默认的用户

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