自定义表达式
何时以及为何您应该在 Metabase 的 Notebook 编辑器中使用自定义表达式。
在数学中,表达式是符号的集合,它们共同表示一个值。如果您以前使用过电子表格软件,表达式就是公式,例如=SUM(A1, B1)
。
Metabase 的查询构建器中的自定义表达式是强大的工具,无需从工具箱中取出 SQL 即可涵盖绝大多数分析用例。事实上,使用查询构建器有很多您在使用 SQL 时无法获得的优势
- 可扩展性:使用查询构建器来构建查询,使人们无需了解任何 SQL 即可学习和基于您的问题进行构建。
- 钻取允许人们按类别分解记录、放大、钻取到未聚合的记录,或点击查看数据细节。使用 Metabase 查询构建器构建的问题将赋予用户完整的钻取能力,而使用 SQL 构建的问题则只显示有限的选项,例如按值筛选。
您可以在开发过程中的任何时候通过将现有问题转换为原生 SQL 问题切换到 SQL。
在查询构建器中有三个地方可以使用自定义表达式
- 自定义列使用函数计算值(例如
+
用于添加数字)或操作文本(例如lower
将文本转换为小写)。 - 自定义过滤器使用诸如
contains
的函数,它们的值为真或假。 - 自定义汇总使用诸如
count
或sum
的函数来聚合记录。
自定义列
我们可以使用表达式向数据添加自定义列来计算新列。让我们看看一个表达式的实际应用。这里是 Metabase 附带的示例数据库中的订单表。
假设我们想知道基于税前小计应用于订单的折扣百分比。例如,如果我们对 10 美元的订单提供了 1 美元的折扣,我们希望看到一个列显示该订单已折扣 10%。
不幸的是,快速查看预览中的列会告诉我们数据库没有存储该计算结果(即没有“折扣百分比”列)。我们只有订单小计和折扣总额。
然而,多亏了数学,我们可以使用折扣总额和订单小计来计算百分比。这就是表达式发挥作用的地方:我们可以使用表达式计算每一行的折扣百分比,并将该计算值存储在新列中。
让我们逐步了解如何创建自定义列。
在查询构建器中,我们在数据部分中选择自定义列。
要计算折扣百分比,我们需要用折扣金额除以原始总金额(Subtotal
)以获得折扣百分比。
在表达式中,我们使用方括号引用列。例如,我们可以将订单表中的 Discount 列称为[Discount]
。如果我们需要引用通过外键链接的另一个表中的列,我们可以在表和列之间使用.
(点),例如[Table.Column]
(或者,您可以从键入左方括号([
)时出现的下拉菜单中选择[Table → Column]
)。例如,我们可以输入[Products.Category]
,它将解析为:[Products → Category]
。
目前,我们只关注订单表中的列,因此无需引用其他表。以下是我们将用于计算自定义折扣百分比列的表达式(或公式)
[Discount] / [Subtotal]
在表达式字段中输入该表达式,然后给新列命名为:Discount percentage
。
点击“完成”,然后点击可视化按钮查看新列。
由于新Discount percentage
列中的值与折扣有关,我们将该列移到Discount
列旁边。您可以通过点击列标题并将列拖动到目标位置来在表格中移动列,如下所示
由于我们正在计算百分比,让我们修正格式以便于阅读。点击Discount percentage
标题以调出该列的操作菜单,然后点击齿轮图标格式化列。
Metabase 将滑出格式化侧边栏,其中包含选项。让我们将样式更改为百分比,并将小数位数增加到2。而且由于标题Discount percentage
占用了大量空间,我们将其重命名为Discount %
。
还有一个选项可以添加迷你条形图。这个条形图不会显示相对于 100% 的百分比;相反,迷你条形图将显示折扣百分比相对于其他订单折扣百分比的情况。暂时关闭迷你条形图。
这是添加了Discount %
列的最终问题
自定义过滤器
Metabase 开箱即用地提供了许多筛选选项,但您可以使用自定义筛选表达式设计更复杂的过滤器。这些对于创建使用OR
语句的过滤器特别有用,这也是我们在此处将要介绍的内容。
通常在查询构建器中,当我们向问题添加多个过滤器时,Metabase 会隐式地使用AND
运算符组合这些过滤器。例如,如果添加一个以Enormous
开头的产品过滤器,以及一个以Computer
结尾的产品过滤器,我们的问题将只返回既以Enormous
开头**并且**以Computer
结尾的产品,而这些产品在 Metabase 的示例数据库中是不存在的。
要筛选以Enormous
开头**或**以Computer
结尾的产品,我们将从过滤器下拉菜单中选择自定义表达式,并使用startsWith
和endsWith
函数
startsWith(string1, string2)
endsWith(string1, string2)
函数startsWith
和endsWith
检查string1
是否以/结尾string2
开头/结尾。所以string1
是要检查的字符串(大海捞针),而string2
是要查找的文本(针)。由于我们希望查找以Enormous
开头**或**以Computer
结尾的产品,我们可以使用startsWith
和endsWith
表达式,并在两者之间使用 OR 运算符
startsWith([Title], "Enormous") OR endsWith([Title], "Computer")
结果数据集将包含以Enormous
开头或以Computer
结尾的产品
请注意,自定义过滤器表达式必须始终解析为真或假。但是,您可以在语句中嵌套不解析为真或假的表达式,例如
contains(concat([First Name], [Last Name]), "Wizard")
因为最外层的函数(contains
)解析为真或假。而您不能将concat([First Name], [Last Name])
作为过滤器,因为它会解析为文本字符串(尽管可以使用 concat 创建像Full Name
这样的自定义列)。
自定义汇总
自定义表达式解锁了多种聚合数据的方式。让我们考虑Share
函数,它以小数形式返回数据中符合条件的行所占的百分比。例如,假设我们想知道我们产品线中纸制品总百分比,即我们的产品线中有多少比例由纸制品组成?
首先,我们将从示例数据库中选择产品表。接下来,我们将点击查询构建器中的汇总按钮并选择自定义表达式。然后,我们将从下拉菜单中选择Share
,这将提示我们输入一个条件。在这种情况下,我们想知道哪些产品的标题中包含“纸”,因此我们将使用contains
函数来搜索Title
。
Share(contains([Title], "Paper"))
然后我们命名表达式(例如Percentage of paper products
),然后点击完成。点击可视化按钮,Metabase 将计算纸制品的份额。
要更改格式,请选择左下角的设置按钮以调出设置侧边栏,并将数字选项 → 样式更改为百分比。
综合运用
让我们使用表达式创建一个相当复杂(人为构造)的问题。假设我们的任务是找出 2019 年羊毛和棉制品每月的平均净流入,其中净流入是销售价格减去我们为产品支付的成本。换句话说:对于每售出的一单位羊毛和棉制品,我们在 2019 年每个月平均赚取(或损失)了多少钱?
要获得这些引人入胜的数字,我们需要使用表达式来
- 计算每单位销售价格(自定义列)。
- 筛选结果,使其仅包含羊毛或棉制品(自定义过滤器),并将这些结果限制在 2019 年。
- 计算平均净流入(自定义汇总),并按月份分组。
开始吧
-
我们创建一个名为
Unit price
的自定义列。为了计算Unit price
,我们将使用表达式将小计除以售出单位数(Quantity
)[Subtotal] / [Quantity]
-
接下来,我们将使用自定义过滤器表达式来筛选
Wool
和Cotton
产品的订单(即产品标题中包含“Wool”或“Cotton”的Product.Title
)。contains([Products → Title], "Wool") OR contains([Products → Title], "Cotton")
-
我们还将筛选介于
01/01/2019
和12/31/2019
之间的订单。 -
我们将使用自定义表达式来创建自定义汇总。假设标准零售加价率为 50%(基石加价)。所以如果
Product.Price
是 2 美元,我们假设每单位产品的采购成本是 1 美元。基于此假设,我们可以简单地将每单位净流入定义为Unit price
减去Product.Price
的一半。然后我们将通过计算每个订单的这些数字的平均值来汇总数据。Average([Unit price] - [Products → Price] / 2)
-
最后,我们将按月将这些订单按
Orders.Created_At
分组。
这是我们的 Notebook
我们将选择将数据可视化为折线图,可以点击它来钻取数据
延伸阅读
- 文档:查询构建器中的自定义表达式。表达式中还有很多我们没有介绍的函数,请查看文档以获取完整的函数列表。
- 时间序列比较展示了如何使用自定义表达式来可视化和比较时间序列。
- 清理和格式化文本使用自定义表达式处理混乱和缺失的数据。
下一篇:Metabase 中的连接
如何在 Metabase 中使用 Notebook 编辑器在简单和自定义问题中连接表。