视图的 SQL 概念

LookML 项目中的每个视图文件都会在 Looker 中定义一个视图,用于指定要查询的表以及该表中哪些字段(维度和测量)将显示在 Looker 界面中。视图对应于数据库中的单个表或单个派生表

在本指南中,您将了解以下主题:

如需详细了解如何使用 SQL 在 LookML 中定义和自定义派生表,请参阅派生表的 SQL 概念

视图

以下是一个名为 users.view 的视图文件示例,其中包含要查询的数据库表的定义以及几个维度和测量:

view: users {
  sql_table_name: thelook.users ;;

  dimension: id {
    primary_key: yes
    type: number
    sql: ${TABLE}.id ;;
  }

  dimension: age {
    type: number
    sql: ${TABLE}.age ;;
  }
   measure: average_age {
    type: average
    sql: ${age} ;;  }

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

  measure: count {
    type: count
  }
}

视图定义的第一个元素是 sql_table_name 参数,用于指定视图将查询的数据库中的表。此值是整个模型中定义表名称的唯一位置,因为对视图的所有其他引用都将使用表别名 ${TABLE}。如果您想更改数据库表名称,只需在 sql_table_name 参数中更改即可。在引用数据库表时,需要注意以下事项

Looker 使用 sql_table_name 值编写其 SQL FROM 子句,后跟视图名称(该名称将成为表别名)。等效的 SQL 代码如下所示:

FROM `thelook`.`users` AS `users`

Looker 使用视图定义的维度和测量来生成其 SQL SELECT 子句。每个维度都定义了维度的类型(例如字符串、数字或布尔值),以及一个 sql LookML 参数,该参数使用表别名引用视图中的维度。对于名为 age 的维度,请参阅以下示例:

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

当 Looker 创建要发送到数据库的 SQL 时,会将视图的别名替换为 ${TABLE}。对于上例中的 age 维度,Looker 会生成如下 SELECT 子句:

SELECT `users`.`age` AS `users.age`

指标通常是对维度执行的汇总。您可以在衡量标准的 sql 表达式中指定维度别名。例如,用于计算 age 维度平均值的测量可能包含包含别名 ${age}sql 表达式,如以下示例所示:

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

  measure: average_age {
    type: average
    sql: ${age} ;;
  }

如果您重命名 age 维度,其新别名会传播到其任何维度别名引用。

自定义视图文件

您可以自定义视图文件的 SQL 表达式,也可以使用 Looker 的内置 LookML 逻辑来模拟 SQL 表达式的逻辑。

使用 SQL 表达式

假设您想将年龄数据划分为四个同类群组,将未满 18 周岁的用户定义为“青少年”,将 18-35 周岁的用户定义为“年轻成人”,将 36-65 周岁的用户定义为“中年成人”,将 65 周岁及以上的用户定义为“老年人”。如需执行此划分,您必须使用捕获这些同类群组的 sql 表达式定义一个新维度(例如 dimension: age_cohort)。以下 LookML 维度定义使用适用于 MySQL 数据库连接的 CASE 语句:

dimension: age_cohort {
  type: string
  sql:
    CASE
      WHEN ${age} < 18 THEN 'Youth'
      WHEN ${age} < 35 THEN 'Young Adult'
      WHEN ${age} < 65 THEN 'Older Adult'
      ELSE 'Senior'
    END ;;
}

现在,您已将年龄段细分作为维度进行定义,因此您可以通过在“探索”查询中添加年龄段细分维度来重复使用 CASE 逻辑。

使用年龄同类群组维度创建探索查询时,您可以使用“探索”的“SQL”标签页查看 Looker 生成的 SQL 代码。使用年龄同类群组维度时,SQL 将如下所示:

SELECT
CASE
  WHEN users.age < 18 THEN 'Youth'
  WHEN users.age < 35 THEN 'Young Adult'
  WHEN users.age < 65 THEN 'Older Adult'
  ELSE 'Senior'
END  AS `users.age_cohort`,
AVG(`age`) AS `users.average_age`,
COUNT(*) AS `users.count`
FROM
  `thelook`.`users` AS `users`
GROUP BY
  1
ORDER BY
  2 DESC
LIMIT 500

使用 Looker 的内置支持请求逻辑

您可以使用与数据库无关的表达式来实现与 SQL CASE 语句相同的效果。借助 LookML case 参数,您可以定义同类群组分桶,这些分桶由 when 语句组成,这些语句使用 sql 表达式来捕获用于为结果添加标签的特定条件和字符串。

以下示例展示了使用 case LookML 参数写入的相同新 age_cohort 维度:

  dimension: age_cohort {
    case: {
      when: {
        sql: ${age} < 18 ;;
        label: "Youth"
      }
      when: {
        sql: ${age} < 35 ;;
        label: "Young Adult"
      }
      when: {
        sql: ${age} < 65 ;;
        label: "Middle-aged Adult"
      }
      else: "Older Adult"
    }
  }

在运行时,Looker 会为您的数据库构建正确的 SQL CASE 语法。此外,Looker 会构建另一个表达式来处理对组进行排序,因此生成的标签不会仅按字母数字排序(除非您将排序顺序定义为字母数字排序)。Looker 会构建类似于以下内容的最终 SQL 查询:

SELECT
CASE
  WHEN users.age < 18  THEN '0'
  WHEN users.age < 35  THEN '1'
  WHEN users.age < 65  THEN '2'
  ELSE '3'
END AS `users.age_cohort__sort_`,
CASE
  WHEN users.age < 18  THEN 'Youth'
  WHEN users.age < 35  THEN 'Young Adult'
  WHEN users.age < 65  THEN 'Older Adult'
  ELSE 'Senior'
END AS `users.age_cohort`,
AVG(`age`) AS `users.average_age`,
COUNT(*) AS `users.count`
FROM
  `thelook`.`users` AS `users`
GROUP BY
  1,
  2
ORDER BY
  1
LIMIT 500

使用 Looker 的内置分桶或层级逻辑

指定应如何对数值进行分组的另一种方法是使用 Looker 的内置 bintier 参数类型。type:binbins 参数搭配使用,type: tiertiers 参数搭配使用,以将数值维度拆分为一组数值范围。但缺点是,您无法为每个分箱定义标签。

以下 LookML 示例在维度中使用 bins 参数来定义每个集合的最小值:

  dimension: age_cohort {
    type: bin
    bins: [18,36,65]
    style: integer
    sql: ${age} ;;
  }

您可以在维度中使用 tiers 参数,方法完全相同。例如:

  dimension: age_cohort {
    type: tier
    tiers: [18,36,65]
    style: integer
    sql: ${age} ;;
  }

然后,Looker 会生成类似以下内容的 SQL 语句:

SELECT
CASE
  WHEN users.age  < 18 THEN '0'
  WHEN users.age  >= 18 AND users.age  < 36 THEN '1'
  WHEN users.age  >= 36 AND users.age  < 65 THEN '2'
  WHEN users.age  >= 65 THEN '3'
  ELSE '4'
END AS `users.age_cohort__sort_`,
CASE
  WHEN users.age  < 18 THEN 'Below 18'
  WHEN users.age  >= 18 AND users.age  < 36 THEN '18 to 35'
  WHEN users.age  >= 36 AND users.age  < 65 THEN '36 to 64'
  WHEN users.age  >= 65 THEN '65 or Above'
  ELSE 'Undefined'
END AS `users.age_cohort`,
AVG(`age`) AS `users.average_age`,
COUNT(*) AS `users.count`
FROM
  `thelook`.`users` AS `users`
GROUP BY
  1,
  2
ORDER BY
  1
LIMIT 500