教程:自定义表达式

在 Metabase 的笔记本编辑器中,您应该何时使用自定义表达式以及为什么应该利用它们。

正在寻找自定义表达式的文档?请参阅 文档:字段过滤器

在数学中,表达式是符号的集合,它们一起表达一个值。如果您以前使用过电子表格软件,表达式就是公式,例如 =SUM(A1, B1)

Metabase 的**查询构建器**中的自定义表达式是非常强大的工具,它们可以满足绝大多数分析用例的需求,而无需将 SQL 从工具箱中移除。事实上,使用查询构建器比使用 SQL 有很多优势。

  • 可扩展性:通过使用**查询构建器**构建查询,人们可以在无需了解任何 SQL 的情况下,从您的查询中学习并在此基础上进行构建。
  • 钻取允许用户按类别分解记录、放大、深入到未聚合的记录,或在单击时进行数据钻取。使用 Metabase 查询构建器构建的查询将赋予用户完整的钻取功能,但使用 SQL 构建的查询只提供按值过滤等有限选项。

您始终可以在开发过程中的任何时候通过将现有查询转换为原生 SQL 查询来切换到 SQL。

在**查询构建器**中,我们可以在三个地方使用自定义表达式:

  • 自定义列使用函数来计算值(例如,使用 + 来相加数字)或处理文本(例如,使用 lower 将文本转换为小写)。
  • 自定义过滤器使用像 contains 这样的函数,这些函数会求值为 true 或 false。
  • 自定义汇总使用像 countsum 这样的函数来聚合记录。

自定义列

我们可以使用表达式来计算新列,从而向我们的数据添加自定义列。让我们来看一个表达式的实际应用。这是 Metabase 随附的 示例数据库中的 **Orders** 表。

The Orders table in the Sample Database included with Metabase.

假设我们想知道订单的折扣百分比,该折扣是基于税前小计计算的。例如,如果我们在 10 美元的订单上给予 1 美元的折扣,我们希望看到一列显示我们将该订单折扣了 10%。

不幸的是,快速浏览预览中的列后,我们发现数据库并未存储该计算(即,没有“折扣百分比”列)。我们只有订单的小计和折扣总额。

然而,得益于数学,我们可以使用折扣总额和订单小计来计算百分比。这就是表达式发挥作用的地方:我们可以使用表达式为每一行计算折扣百分比,并将计算出的值存储在一个新列中。

让我们一步步了解如何创建自定义列。

在**查询构建器**中,我们在**数据部分**选择**自定义列**。

要计算折扣百分比,我们需要将折扣除以原始总价(即 Subtotal),以获得折扣百分比。

在表达式中,我们使用方括号引用列。例如,我们可以将 **Orders** 表中的 Discount 列引用为 [Discount]。如果需要引用由外键链接的另一个表中的列,我们可以使用 . 在表和列之间分隔,例如 [Table.Column](或者,当您键入一个开放括号 ([) 时,可以从出现的下拉菜单中选择 [Table → Column])。例如,我们可以输入 [Products.Category],它将解析为:[Products → Category]

目前,我们只对 Orders 表中的列感兴趣,因此无需引用其他表。这是我们将用于计算我们的自定义折扣百分比列的表达式(或公式):

[Discount] / [Subtotal]

在**表达式**字段中输入该表达式,然后为新列命名:Discount percentage

Entering a field formula to create a custom column.

点击“完成”,然后点击**可视化按钮**以查看您的新列。

由于我们新 Discount percentage 列中的值与折扣相关,让我们将该列移到 Discount 列旁边。您可以通过单击列标题并将其拖动到目标位置来移动表中的列,如下所示:

Dragging a column to change its position in the table visualization.

由于我们正在计算百分比,让我们调整格式以便更容易阅读。单击 Discount percentage 标题以打开该列的**操作菜单**,然后单击**齿轮图标**以格式化该列。

Metabase 将滑出**格式化侧边栏**,其中包含选项。让我们将样式更改为**百分比**,并将小数位数增加到**2**。由于 Discount percentage 标题占用了大量空间,让我们将列重命名为 Discount %

还有一个添加**迷你条形图**的选项。此条形图不会显示相对于 100% 的百分比;相反,迷你条形图将显示折扣百分比相对于其他订单的折扣百分比。我们暂时将迷你条形图关闭。

这是添加了 Discount % 列的最终查询:

Our finished Discount % column.

自定义过滤器

Metabase 开箱即用地提供了许多过滤选项,但您可以使用自定义过滤器表达式设计更复杂的过滤器。这些对于创建使用 OR 语句的过滤器特别有用,这也是我们将在这里介绍的内容。

在查询构建器中,当我们向查询添加多个过滤器时,Metabase 通常会隐式地使用 AND 运算符组合这些过滤器。例如,如果我们添加一个产品以 Enormous 开头的过滤器,以及一个产品以 Computer 结尾的过滤器,我们的查询只会返回同时以 Enormous 开头 **且** 以 Computer 结尾的产品,而这些产品在 Metabase 的示例数据库中不存在。

要过滤以 Enormous 开头 **或** 以 Computer 结尾的产品,我们将从**过滤器**下拉菜单中选择**自定义表达式**,并使用 startsWithendsWith 函数。

startsWith(string1, string2)
endsWith(string1, string2)

函数 startsWithendsWith 检查 string1 是否以 string2 开头/结尾。因此,string1 是要检查的字符串(容器),而 string2 是要查找的文本(针)。由于我们想查找以 Enormous 开头 **或** 以 Computer 结尾的产品,我们可以使用 startsWithendsWith 表达式,并在它们之间使用 OR 运算符。

startsWith([Title], "Enormous") OR endsWith([Title], "Computer")

结果数据集将包含以 Enormous 开头 **或** 以 Computer 结尾的产品。

Products that are either enormous or aerodynamic.

请注意,自定义过滤器表达式必须始终求值为 true 或 false。但是,您可以在语句中嵌套不求值为 true 或 false 的表达式,例如:

contains(concat([First Name], [Last Name]), "Wizard")

因为最外层函数(contains)会求值为 true 或 false。而您不能使用 concat([First Name], [Last Name]) 作为过滤器,因为它会解析为一串文本(尽管您可以使用 concat 来创建自定义列,例如 Full Name)。

自定义汇总

自定义表达式为我们聚合数据提供了许多不同的方法。让我们考虑 Share 函数,它以小数形式返回数据中与条件匹配的行所占的百分比。例如,假设我们想知道我们产品线中纸制品所占的总百分比,即我们产品线中有多少比例由纸制品组成?

首先,我们将从示例数据库中选择 **Products** 表。接下来,点击查询构建器中的**汇总按钮**,然后选择**自定义表达式**。然后,我们将从下拉菜单中选择 Share,这将提示我们输入一个条件。在这种情况下,我们想知道哪些产品在其标题中包含“Paper”,因此我们将使用 contains 函数来搜索 Title

Share(contains([Title], "Paper"))

Calculating the share of paper products.

然后我们为表达式命名(例如,Percentage of paper products),然后点击**完成**。点击**可视化按钮**,Metabase 将计算纸制品所占的份额。

要更改格式,请选择左下角的**设置按钮**以打开**设置侧边栏**,并将**数字选项 → 样式**更改为**百分比**。

The share of paper products, formatted as a percentage.

综合运用

让我们创建一个相当复杂(人为构造)的查询,其中使用表达式。假设我们的任务是按月查找 2019 年羊毛和棉花产品的平均净流入,净流入是销售价格减去我们为产品支付的成本。换句话说:对于售出的每件羊毛和棉花产品,我们在 2019 年每月平均赚取(或亏损)多少钱?

为了获得这些有趣的数据,我们需要使用表达式来:

  • 计算每件商品的售价(自定义列)。
  • 将结果过滤为仅包含羊毛或棉花产品(自定义过滤器),并将这些结果限制在 2019 年。
  • 计算平均净流入(自定义汇总),并按月分组。

我们开始吧。

  1. 我们创建一个名为 Unit price 的自定义列。要计算 Unit price,我们将使用表达式将小计除以售出的单位数量(Quantity)。

    [Subtotal] / [Quantity]
    
  2. 接下来,我们将使用自定义过滤器表达式来过滤 WoolCotton 产品的订单(即,过滤包含“Wool”或“Cotton”的产品,这些产品出现在 Product.Title 中)。

    contains([Products → Title], "Wool") OR contains([Products → Title], "Cotton")
    
  3. 我们还将过滤日期在 2019/01/012019/12/31 之间的订单。

  4. 我们将使用自定义表达式来创建自定义汇总。假设标准的零售加价为 50%(即加倍加价)。因此,如果 Product.Price 为 2 美元,我们将假定该产品的单位成本为 1 美元。基于此假设,我们可以简单地将每单位售出的净流入定义为 Unit price 减去 Product.Price 的一半。然后,我们将通过计算每个订单的平均值来汇总这些数据。

    Average([Unit price] - [Products → Price] / 2)
    
  5. 最后,我们将这些订单按月按 Orders.Created_At 分组。

这是我们的笔记本:

Our wool and cotton notebook.

我们将选择将数据可视化为折线图,我们可以点击它进行钻取数据。

Drilling through fabrics to view individual orders.

延伸阅读

这有帮助吗?

感谢您的反馈!
订阅新闻通讯
Metabase 的更新和新闻
© . This site is unofficial and not affiliated with Metabase, Inc.