SQL问题字段过滤器
了解如何使用Metabase字段过滤器在SQL查询中构建更智能的过滤器小部件。
本文展示了如何使用一种称为字段过滤器的特殊类型变量,在Metabase中将智能SQL过滤器小部件添加到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
子句括在双括号中,以使输入可选,并使用 变量侧边栏 将变量类型设置为 文本
,并将过滤器小部件标签设置为 类别
。这种方法是可行的,但不是最佳方法
- 为了过滤数据,人们必须知道哪些类别存在(并且当他们输入时必须正确拼写)。
- 此外,他们不能同时选择多个类别,因为
{{category}}
变量只接受单个值。
相比之下,字段过滤器将变量映射到实际的列数据。然后连接到变量的过滤器小部件“知道”哪些类别可用,并可以显示这些类别的下拉菜单,如下所示
关于小部件的一些建议:下拉菜单只是可用的选项之一。在我们的示例中,对于类型为 类别
的字段,例如我们的 category
字段在 Products
表中,我们还可以将过滤器小部件设置为搜索框或纯输入框。管理员可以在 管理面板 的 数据模型选项卡 中配置字段设置。
请注意,如果列中不同值的数量超过300,即使您选择了下拉选项,Metabase也会自动使用搜索框。在我们的文档中了解有关编辑元数据的更多信息。
现在,让我们回到我们的问题。以下是Products.category
字段过滤器的语法。注意在WHERE
子句中变量之前省略了列和运算符——我们将在下面详细介绍字段过滤器语法。
SELECT *
FROM orders
LEFT JOIN products
ON orders.product_id = products.id
WHERE {{category}};
在WHERE
子句中放置我们的变量后,我们可以使用变量侧边栏将变量作为字段过滤器连接起来。我们将设置:
变量类型
为字段过滤器
。映射到的字段
为Products → Category
。此设置告诉Metabase将我们的SQL代码中的变量连接到Products
表的category
列。字段小部件类型
为category
。字段小部件标签
为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
子句中使用模式。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输入变量 - 文本、数字和日期的指南。
您还可以阅读我们的
下一节:SQL片段:重用和共享SQL代码
了解您在SQL代码中使用片段所需了解的一切。