自定义表达式
何时使用自定义表达式以及为什么您应该在Metabase的笔记本编辑器中充分利用它们。
在数学中,表达式是表达值的符号集合。如果您之前曾经使用过电子表格软件,那么表达式就是公式,例如 =SUM(A1, B1)
。
Metabase的 查询构建器 中的自定义表达式是强大的工具,可以在不离开工具箱的情况下覆盖大多数分析用例。事实上,使用查询构建器的好处是当使用SQL时得不到的。
- 可扩展性:使用 查询构建器 构建查询,使得人们可以在不了解任何SQL的情况下从您的问题中学习并建立自己的问题。
- 钻取 允许人们按类别拆分记录、放大、钻取到未聚合的记录或点击数据时进行X射线检查。使用Metabase查询构建器构建的问题将使用户获得完整的钻取功能,而使用SQL构建的问题只会显示有限选项,如按值过滤。
您可以在开发过程中随时通过 将现有问题转换为原生SQL问题 来切换到SQL。
在 查询构建器 中有三个地方我们可以使用自定义表达式
- 自定义列 使用函数来计算值(如使用
+
来加法)或操作文本(如使用lower
将文本转换为小写)。 - 自定义过滤器 使用像
contains
这样的函数,其结果为真或假。 - 自定义汇总 使用像
count
或sum
这样的函数来聚合记录。
自定义列
我们可以在数据中添加一个自定义列,使用表达式来计算新列。让我们看看表达式是如何工作的。这是Metabase附带示例数据库中的订单表。
假设我们想了解订单中应用的折扣百分比,基于税前小计。例如,如果我们对价值10美元的订单给出了1美元的折扣,我们希望看到一列显示我们已对该订单进行了10%的折扣。
不幸的是,快速查看预览中的列告诉我们,数据库没有存储这个计算(即没有“折扣百分比”列)。我们只有订单的小计和折扣总额。
然而,凭借数学,我们可以使用折扣总额和订单小计来计算百分比。这正是表达式发挥作用的地方:我们可以使用表达式来计算每一行的折扣百分比,并将计算出的值存储在新列中。
让我们看看如何创建一个自定义列。
在查询构建器中,我们在数据部分中选择自定义列。
为了计算折扣百分比,我们需要将折扣除以原始总额(即Subtotal
)以得到折扣百分比。
在表达式中,我们使用方括号引用列。例如,我们可以将订单表中的折扣列引用为[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
结尾的商品,因此我们可以使用带有 OR 操作符之间的 startsWith
和 endsWith
表达式。
= startsWith([Title], "Enormous") OR endsWith([Title], "Computer")
结果数据集将包含以 Enormous
开头或以 Computer
结尾的商品。
请注意,自定义筛选表达式必须始终解析为 true 或 false。但是,您可以在语句内嵌套不解析为 true 或 false 的表达式,如下所示:
= contains(concat([First Name], [Last Name]), "Wizard")
因为最外层的函数(contains
)解析为 true 或 false。而您不能使用 concat([First Name], [Last Name])
作为筛选,因为它将解析为一个字符串文本(尽管您可以使用 concat 创建一个自定义列,如 Full Name
)。
自定义汇总
自定义表达式解锁了许多不同的数据聚合方式。让我们以 Share
函数为例,它以十进制的形式返回匹配条件的数据行百分比。例如,如果我们想知道产品线中纸制品的总百分比,即我们的产品线中有多少比例是由纸制品组成的?
首先,我们从样本数据库中选择 产品 表。然后,我们点击查询构建器中的 汇总按钮 并选择 自定义表达式。然后,我们从下拉菜单中选择 Share
,这将提示我们输入一个条件。在这种情况下,我们想知道哪些产品的标题中包含“Paper”,因此我们将使用 contains
函数在 Title
中进行搜索。
= Share(contains([Title], "Paper"))
然后我们命名我们的表达式(例如,纸制品百分比
)并点击 完成。点击 可视化按钮,Metabase 将计算纸制品的份额。
要更改格式,请选择左下角的 设置按钮 以打开 设置侧边栏 并将 数字选项 → 样式 更改为 百分比。
整合一切
让我们使用表达式创建一个相当复杂(人为设计)的问题。比如说,我们被要求找出2019年羊毛和棉产品每月的平均净流入量,其中净流入量是指售价减去我们为产品支付的成本。换句话说:对于每个月销售的每个羊毛和棉产品单位,我们在2019年每个月平均赚了或损失了多少钱?
为了得到这些令人着迷的数字,我们需要使用表达式来
- 计算每单位的售价(自定义列)。
- 过滤结果,只包含羊毛或棉产品(自定义筛选),并将这些结果限制在2019年内。
- 计算平均净流入量(自定义汇总),并按月分组。
让我们开始吧
-
我们创建了一个名为
Unit price
的自定义列。为了计算Unit price
,我们将使用表达式将小计除以销售的单位数(Quantity
)= [Subtotal] / [Quantity]
-
接下来,我们将使用自定义筛选表达式来筛选羊毛和棉产品的订单(即产品名称中包含“羊毛”或“棉”的产品)。
= contains([Products → Title], "Wool") OR contains([Products → Title], "Cotton")
-
我们还将筛选2019年1月1日至12月31日期间的订单。
-
我们将使用自定义表达式来创建自定义汇总。让我们假设标准的零售加成率为50%(即基石加成率)。所以如果产品的价格是2美元,我们将假设每单位产品的成本为1美元。基于这个假设,我们可以简单地将每单位销售的净流入量定义为
Unit price
减去Product.Price
的一半。然后我们将对每个订单的这些数字进行平均汇总。= Average([Unit price] - [Products → Price] / 2)
-
最后,我们将这些订单按
Orders.Created_At
每月进行分组。
这是我们的笔记本
我们将选择将数据可视化为一个折线图,我们可以点击它来深入数据
进一步阅读
- 文档:查询构建器中的自定义表达式。在表达式中,我们可以使用很多我们没有介绍过的函数,所以请查看文档以获取完整的函数列表。
- 时间序列比较展示了如何使用自定义表达式来可视化和比较时间序列。
- 清理和格式化文本使用自定义表达式处理混乱和缺失的数据。
下一节:Metabase中的连接
如何使用笔记本编辑器在简单和自定义问题中连接表。