教程:使用 SQL 变量创建过滤器
如何使用文本、数字和日期的基本输入变量,在原生 SQL 查询中创建过滤器控件。
查找关于 SQL 参数的文档?请参阅 文档:SQL 参数。
本文将介绍如何在 Metabase 中使用原生 SQL 查询创建问题,以便问题查看者可以输入值并过滤结果。虽然 Metabase 可以轻松地在不使用 SQL 的情况下汇总和可视化数据,但数据分析师有时需要深入研究复杂的查询,他们可以使用 Metabase 的 SQL 编辑器来编写这些查询。
SQL 变量和过滤器控件简介
例如,使用 Metabase 附带的 示例数据库,我们可以在 SQL 中编写一个提取订单产品信息的问题,但我们希望该问题的使用者能够指定他们想要查看的产品类别。为了让人们可以选择在已保存的 SQL 问题中输入值,我们可以编写带有变量的 SQL 查询,Metabase 将自动创建过滤器控件供人们使用。

目前,我们只关注应用于 SQL 编写的问题的过滤器。有关仪表板上的过滤器,请参阅 使用 SQL 问题为仪表板添加过滤器。
但首先:您想使用 SQL 编写问题,还是查询构建器更适合您的用例?
SQL 问题与查询构建器问题
在深入介绍添加过滤器控件之前,值得考虑一下人们将如何使用我们的问题。如果我们只是想让人们有机会在仪表板上输入值到简单的过滤器控件中,那么使用 **查询构建器** 编写问题并在 SQL 代码中添加变量是有意义的。
如果我们改为使用 **查询构建器** 来组合问题,则无需过滤器控件,因为问题的使用者将拥有完整的查询构建原语套件,可以通过 连接、过滤和汇总数据来以任何他们喜欢的方式切片和分析数据。对于更复杂的问题,他们还可以使用 自定义表达式,以及 钻取数据 来放大订单,或点击值以查看单个记录——这些功能不适用于以 SQL 编写的问题。

如果可以使用查询构建器中的功能来回答您的问题,我们建议您使用它们。但是,如果您需要自定义 SQL 命令或函数,并且希望您的用户能够过滤这些问题的结果,请继续阅读。
原生 SQL 查询可用的不同类型的变量

对于使用 Metabase 的 原生 SQL 查询编辑器组合的问题,有四种类型的变量可供选择
- 文本
- 数字
- 日期
- 字段筛选器
其中一种类型,**字段过滤器**,与其他类型不同。实际上,最好将变量类型分为两大类:基本输入变量和字段过滤器。
-
基本输入变量 会创建简单的过滤器控件,人们可以在其中输入值来过滤问题的结果。基本输入变量包括
-
字段过滤器变量 是特殊的输入变量。它们比基本输入变量更复杂,并且行为不同。字段过滤器“连接”到列,并可以提供下拉菜单供人们选择一个或多个值。
我们将在下文中介绍三种基本输入变量——文本、数字和日期——并在另一篇文章中介绍字段过滤器。但首先,让我们了解何时应该选择一种变量类型而不是另一种。
字段过滤器还是基本输入变量?
何时使用基本输入变量
- 用于简单的文本、数字和日期过滤。对于更灵活的日期过滤,请使用字段过滤器。
- 总的来说,对于那些不适合放入下拉菜单的无数值(这需要字段过滤器)。
- 在 SQL 中需要对输入变量进行一些数据处理/整理的情况下。
何时使用字段过滤器
- 提供一个下拉菜单供人们选择预定义的值。
- 提供多种按日期过滤的方式。
- 将变量连接到仪表板上的过滤器控件。
基本输入变量
基本输入变量接受文本、数字或日期等输入。基本输入变量适用于值不是预定义的,或者范围很广的情况,例如订单小计。日期是一个特殊情况:Metabase 提供控件,允许人们选择日期和时间,而不是键入值。
基本输入变量:数字
我们来使用一个数字类型的基本输入变量。假设我们要创建一个问题,该问题返回 Orders 表中的所有记录,但我们希望让人们可以选择按订单 subtotal 过滤掉订单。
让我们保持简单,只让人们输入一个数字,这样问题就会返回该数字大于的订单记录。
要在查询中包含变量,只需将变量名用双大括号括起来,如下所示: {{ variable }}。在此示例中,我们将变量命名为 {{subtotal_var}} 。这是 SQL
SELECT *
FROM orders
WHERE subtotal > {{subtotal_var}}
当我们向 SQL 查询添加变量时,Metabase 会在问题顶部添加一个过滤器控件,并滑出一个侧边栏以显示变量的选项。

这是**变量侧边栏**中的选项
- 变量类型:类型可以是
Text、Number、Date或Field filter。变量类型决定了变量控件的输入界面(例如,对于Date,控件将显示一个日期选择器)。 - 过滤器控件标签:变量在控件中显示的名称,默认为 SQL 查询中的变量名称。
- 必需? 当您将变量设置为必需时,Metabase 会提示您在问题首次加载时为变量提供一个默认过滤器控件值。如果您不提供默认值,Metabase 将在提供值之前不会执行查询。
在 subtotal_var 的情况下,我们想要
- 将
Variable type设置为Number(因为我们处理的是小计)。 - 将
Filter widget label从subtotal_var更改为Subtotal(以便更易于阅读)。 - 将
Required?切换为true。 - 将
Default filter widget value设置为0。这样,当问题运行时,它将自动返回所有结果;人们可以输入更高的总计以过滤结果。
现在我们可以将值填入“小计”控件,并过滤出小计大于该值的所有订单

使基本输入变量可选
如果我们想让过滤器控件成为可选的,我们可以将 WHERE 子句括在双括号中
SELECT *
FROM orders
[[WHERE subtotal > {{subtotal_var}}]]
当 WHERE 子句位于括号中时,如果查看者不输入总计,并且未设置默认值,则查询将简单地返回 Orders 表中的所有记录(即,Metabase 只会运行 SELECT * FROM orders)。
添加多个过滤器
我们也可以使用多个过滤器。例如,如果我们希望人们通过输入总计值的范围来过滤结果,我们可以为上限和下限添加两个变量
SELECT *
FROM orders
WHERE subtotal BETWEEN {{subtotal_min}} AND {{subtotal_max}}
在这种情况下,将出现两个控件,每个控件对应一个变量。

基本输入变量:文本
让我们尝试一个使用简单文本输入变量的示例。在这种情况下,我们要创建一个问题,其中包含一个过滤器控件,允许人们搜索包含他们在控件中输入的文本的产品标题。
这是代码
SELECT *
FROM products
[[WHERE UPPER(title) LIKE UPPER(CONCAT('%', {{search_term}},'%'))]]
我们将 WHERE 子句括在括号中以使控件输入成为可选。我们在变量前后加上通配符 %,以表示术语可以在变量的左侧或右侧具有零个或多个字符。此外,我们通过在 title 列和 {{search_term}} 上使用 UPPER 函数来防止区分大小写。
这是我们的过滤器

基本输入变量:日期
当您选择“日期”变量类型时,过滤器控件将显示一个简单的日期选择器。这是一个包含两个基本日期变量的问题,以便用户可以输入开始日期和结束日期,以返回这两个日期之间的订单。
SELECT *
FROM orders
[[WHERE created_at BETWEEN {{start_date}} AND {{end_date}}]]

请注意,用户需要同时为两个控件选择日期才能激活过滤器,这可能会导致意外行为。例如,有人可能将结束日期留空,并期望订单从开始日期一直过滤到今天,而实际上没有任何过滤器会被应用。
对于日期,请考虑改用字段过滤器,它提供了更多的灵活性。