SQL 问题的字段筛选器
了解如何在 SQL 查询中使用 Metabase 字段过滤器来构建更智能的过滤器小部件。
本文介绍如何使用一种特殊的变量类型——**字段过滤器**,将智能 SQL 过滤器小部件添加到 Metabase 中的 SQL 查询中。
字段过滤器简介
对于用 SQL 编写的 Metabase 问题,我们可以使用基本变量类型——文本、数字和日期——来创建简单的 SQL 过滤器小部件。为了创建可以显示筛选列中特定数据选项的“更智能”的过滤器小部件,例如创建值的下拉菜单,我们可以使用一种特殊的变量类型,称为字段过滤器。
字段过滤器最初可能会让一些人感到困惑,因为人们期望它们像基本输入变量一样工作(但它们不是)。然而,字段过滤器非常值得学习,因为您可以使用它们创建更复杂的过滤器小部件。本文将深入探讨字段过滤器,但首先让我们讨论字段过滤器变量和基本文本、数字和日期变量之间的主要区别。
区分字段过滤器与简单的文本、数字和日期变量
- 字段过滤器默认是可选的。如果未给定值,SQL 查询将像字段过滤器不存在一样运行。但是,您可以选择要求一个值。
- 字段过滤器不适用于表别名。由于字段过滤器依赖于表中列的元数据(以及这些表的特定名称),因此过滤器无法“知道”您已经为表起了别名。并且根据您使用的数据库,您可能需要在
FROM
子句中包含完整的模式路径。 - 字段过滤器使用特殊语法,以便它们可以在后台处理 SQL 代码。您只需将字段过滤器提供给
WHERE
子句(不带列或运算符),字段过滤器将为您管理 SQL 代码。这允许代码考虑人们在过滤器小部件中进行的多次选择。
第 3 点可能尤其令人困惑,所以让我们通过一个例子来阐述它。
使用下拉菜单创建 SQL 过滤器小部件
我们将使用 Metabase 随附的示例数据库,为用 SQL 编写的问题添加一个带下拉菜单的过滤器小部件。假设我们要创建一个 SQL 问题,它从 Orders
表中获取所有订单,但我们希望人们可以选择按 Products
表中的类别过滤结果。我们可以使用基本输入变量创建 Products.category
过滤器,如下所示
SELECT *
FROM Orders
LEFT JOIN Products
ON Orders.product_id = Products.id
[[WHERE Products.category = {{category}}]];
在这种情况下,我们将 WHERE
子句用双括号括起来以使输入可选,并使用**变量侧边栏**将变量类型设置为 Text
,将过滤器小部件标签设置为 Category
。这种方法有效,但并不理想
- 为了筛选数据,人们必须知道存在哪些类别(并在输入时正确拼写)。
- 此外,他们无法同时选择多个类别,因为
{{category}}
变量只接受单个值。
相比之下,字段过滤器会将变量映射到实际的列数据。连接到变量的过滤器小部件随后“知道”哪些类别可用,并可以显示这些类别的下拉菜单,如下所示
关于小部件的一点说明:下拉菜单只是可用选项之一。对于类型为 Category
的字段,例如 Products
表中的 category
字段,我们还可以将过滤器小部件设置为搜索框或纯输入框。管理员可以在**管理面板**的**数据模型选项卡**中配置字段设置。
请注意,如果列中不同值的数量大于 300,即使您选择了下拉选项,Metabase 也会自动使用搜索框。在我们的文档中了解更多关于编辑元数据的信息。
现在,让我们回到我们的问题。这是 Products.category
字段过滤器的语法。请注意 WHERE
子句中变量之前的列和运算符的省略——我们将在下面详细讨论字段过滤器语法
SELECT *
FROM orders
LEFT JOIN products
ON orders.product_id = products.id
WHERE {{category}};
有了 WHERE
子句中的变量,我们就可以使用**变量侧边栏**将变量作为字段过滤器连接起来。我们将设置
变量类型
为字段过滤器
。要映射到的字段
为产品 → 类别
。此设置告诉 Metabase 将 SQL 代码中的变量连接到Products
表的category
列。字段小部件类型
为类别
。字段小部件标签
为类别
。
我们不要求变量,所以不需要默认值。如果查询在过滤器小部件中没有指定值的情况下运行,查询将返回所有类别的记录。
请注意,WHERE
子句没有指定变量应该等于哪个列。这种隐式语法(隐藏的 SQL 代码)允许字段过滤器在后台处理 SQL 代码,以适应多种选择。
为日期字段创建复杂的 SQL 过滤器小部件
我们可以创建一个日期类型的基本输入变量,它将添加一个带有简单日期过滤器的 SQL 过滤器小部件。如果,我们改用字段过滤器变量,我们可以将该变量连接到包含日期的字段(列),这为配置我们的过滤器小部件解锁了更多选项。这是 SQL
SELECT *
FROM ORDERS
WHERE {{created_at}}
以下是映射到日期字段的字段过滤器的不同小部件类型
- 月和年
- 季度和年份
- 单个日期
- 日期范围
- 相对日期
- 日期过滤器
每种小部件类型都提供不同的方式让人们筛选结果。这里有三个 SQL 字段过滤器示例
日期过滤器小部件类型提供了最大的灵活性,允许人们按相对日期和范围进行过滤。
字段过滤器的注意事项
在尝试实现字段过滤器时,人们通常会在以下几个地方卡住。
字段过滤器与别名不兼容
如上所述,如果您在 SQL 查询中使用别名,字段过滤器将无法工作。例如,此代码(带别名)将不起作用
-- DON'T DO THIS
SELECT *
FROM orders AS o
LEFT JOIN products AS p
ON o.product_id = p.id
WHERE {{category}};
而这段没有别名的代码_将_工作
SELECT *
FROM orders
LEFT JOIN products
ON orders.product_id = products.id
WHERE {{category}};
原因是字段过滤器通过分析有关数据(例如,表的列名)的元数据来工作,而该元数据不包括您在 SQL 代码中创建的别名。请注意,某些数据库要求在 FROM
子句中包含 schema。Oracle 的一个示例是 FROM "schema"."table"
。在 BigQuery 中,需要使用反引号:FROM `dataset_name.table`
。
省略 WHERE 子句中的直接赋值
如上所述,围绕字段过滤器的 SQL 代码并不完全符合标准。您可能会试图这样写
-- DON'T DO THIS
WHERE category = {{ category }}
因为这是标准 SQL 中 WHERE
子句的正确语法。但该语法不适用于字段过滤器。字段过滤器的正确语法省略了 =
运算符
WHERE {{ category }}
这种简写的原因是,Metabase 可以在幕后插入 SQL 代码,以应对多种选择的情况,例如当用户从下拉菜单中选择多个类别时。
了解更多关于 SQL 过滤器和变量的信息
查看我们的基本 SQL 输入变量 - 文本、数字和日期指南。
您还可以阅读我们的文档,了解