SQL 参数
您可以通过在原生/SQL 编辑器中向 SQL 查询添加变量来创建 SQL 模板。这些变量将创建筛选器小部件,您可以使用它们更改查询中的变量值。您还可以将参数添加到问题的 URL 中以设置筛选器的值,这样当问题加载时,这些值就会插入到变量中。
定义变量
在原生查询中键入 {{variable_name}}
会创建一个名为 variable_name
的变量。
字段筛选器 (Field Filters) 是一种特殊类型的筛选器,具有略有不同的语法。
此示例定义了一个名为 category
的文本变量。
SELECT
count(*)
FROM
products
WHERE
category = {{category}}
Metabase 将读取该变量并向查询附加一个筛选器小部件,人们可以使用该小部件更改插入到带引号的 cat
变量中的值。因此,如果有人在筛选器小部件中输入“Gizmo”,Metabase 将运行的查询将是
SELECT
count(*)
FROM
products
WHERE
category = 'Gizmo'
如果您正在编写原生 MongoDB 查询,您的查询可能更像这样,cat
变量在 match
子句中定义。
[{ $match: { category: {{cat}} } }]
设置 SQL 变量
要将 SQL 变量设置为某个值,您可以:
- 在筛选器小部件中输入值,然后重新运行问题,或者
- 在 URL 中添加参数并加载页面。
要向 URL 添加值,请遵循以下语法:
?variable_name=value
例如,要将问题上的 {{cat}}
变量设置为值“Gizmo”,您的 URL 将如下所示:
https://metabase.example.com/question/42-eg-question?cat=Gizmo
要设置多个变量,请使用与号 (&
) 分隔参数。
https://metabase.example.com/question/42-eg-question?cat=Gizmo&maxprice=50
SQL 变量类型
当您定义变量时,变量侧面板将出现。您可以为变量设置类型,这会更改 Metabase 显示的筛选器小部件的类型。
有四种变量类型:
- 文本:一个纯文本输入框。
- 数字:一个纯文本输入框。
- 日期:一个简单的日期选择器。如果您需要更具表达力的日期选择器,例如指定范围,您将需要使用字段筛选器。
- 字段筛选器:根据映射字段的不同筛选器小部件。
最后一种变量类型,字段筛选器,是特殊的;它允许您创建“智能”筛选器小部件,例如搜索框、值下拉菜单或允许您指定日期范围的动态日期选择器。
您可以在查询中包含多个变量,Metabase 将向问题添加多个筛选器小部件。当您有多个筛选器小部件时,可以单击筛选器小部件并拖动它以重新排列顺序。
字段筛选器变量类型
将变量设置为字段筛选器类型允许您将变量映射到当前数据库中任何表中的字段。字段筛选器允许您为该字段创建“智能”筛选器小部件。
字段筛选器变量应在 SQL 的 WHERE
子句中或 MongoDB 的 $match
子句中使用。
字段筛选器兼容类型
字段筛选器仅适用于以下字段类型:
- 类别
- 实体名称
- 实体键
- 外键
- 城市
- 州/省
- 邮政编码
该字段也可以是日期或时间戳,在表格元数据中可以将其保留为“无语义类型”。
当您将变量类型设置为“字段筛选器”时,Metabase 将提供设置要映射到的字段以及筛选器小部件类型的选项。筛选器小部件类型的可用选项取决于字段的类型。例如,如果您映射到类别类型的字段,您将看到“类别”或“无”的选项。如果您映射到日期字段,您将看到“无”、“月和年”、“季度和年”、“单个日期”、“日期范围”或“日期筛选器”的选项。
如果您没有看到显示筛选器小部件的选项,请确保映射的字段设置为上述类型之一,然后尝试从管理面板的“数据库”部分手动同步您的数据库,以强制 Metabase 扫描和缓存字段的值。
如果您想将字段筛选器映射到不是上述兼容类型之一的字段,您将需要管理员更改该列的字段类型。请参阅元数据编辑。
字段筛选器语法
假设您想创建一个字段筛选器,按州/省筛选 People
表,并希望人们能够一次选择多个州/省。查询如下:
字段筛选器的语法与文本、数字或日期变量不同。
SELECT
*
FROM
PEOPLE
WHERE
{{state}}
然后,在侧面板中,选择“字段筛选器”变量类型,并选择要将变量映射到哪个字段(在本例中为 State
)。
请注意缺少列和运算符(如 =
)。您需要这样构造字段筛选器的原因是,为了处理 Metabase 为您生成代码的情况。例如,处理有人在筛选器小部件中选择多个值或日期范围的情况。使用字段筛选器,您无法控制生成的 SQL,因此如果您需要更强的控制,您应该使用一个(或多个)文本、数字或日期变量。
一个 MongoDB 原生查询示例可能如下所示:
[ {$match: {{date_var}} } ]
有关更深入的指南,请查看字段筛选器:为 SQL 问题创建智能筛选器小部件。
BigQuery 和 Oracle 中的字段筛选器
确保您的 SQL 方言与您选择的数据库匹配。与查询中表的引用方式相关的常见问题:
数据库 | 方言特性 | 示例 |
---|---|---|
BigQuery | 模式和表必须用反引号引用。 | FROM `dataset.table` |
Oracle | 模式和表必须用双引号引用。 | FROM schema.table |
如需更多帮助,请参阅SQL 错误消息故障排除。
如何创建不同类型的筛选器小部件
当您创建字段筛选器小部件时,Metabase 显示的筛选器小部件类型取决于 Metabase 中该字段的一个设置,即此字段的筛选。管理员可以将此字段选项设置为:
- 纯输入框
- 搜索框
- 所有值的列表(也称为下拉菜单)
日期字段将具有简单的日期筛选器(用于日期变量)或动态日期选择器(用于映射到日期字段的字段筛选器)。
如果您想更改特定字段的筛选器小部件,您需要请管理员在表格元数据中更新该字段,并设置所需的“此字段的筛选”选项。
带纯输入框的筛选器小部件
创建一个简单的文本或数字变量。此外,您可以使用字段筛选器,其字段的此字段的筛选值设置为“纯输入框”。
注意:为了防止 SQL 注入攻击,Metabase 会将搜索框中的任何内容转换为字符串。如果您想使用通配符,请查看我们的学习文章。
带搜索框的筛选器小部件
- 在查询中包含一个 SQL 变量。
- 将变量类型设置为字段筛选器。
- 将要映射到的字段设置为类别类型的字段,其此字段的筛选选项设置为“搜索框”
带下拉菜单和搜索的筛选器小部件
要创建带搜索和所有值列表的下拉菜单,您需要:
- 在查询中包含一个 SQL 变量。
- 将变量类型设置为字段筛选器。
- 将要映射到的字段设置为类别类型的字段,其此字段的筛选选项设置为“所有值的列表”。
- 将筛选器小部件类型设置为“类别”。
如果想要创建下拉列表的字段未设置为“类别”类型且“此字段的筛选”未设置为“所有值的列表”,则管理员需要更新该字段的设置。例如,如果您想为不兼容的字段类型(如电子邮件字段)创建下拉菜单,管理员需要将该字段类型更改为“类别”,将“此字段的筛选”选项设置为“所有值的列表”,然后重新扫描该字段的值。
然而,如果该列中有太多不同的值无法在下拉菜单中显示,Metabase 将直接显示一个搜索框。因此,如果您有许多电子邮件地址,您可能无论如何都会得到一个搜索框。下拉菜单小部件在值集较小(例如美国五十个州)时效果更好。
字段筛选器限制
设置字段筛选器变量时可能遇到的一些问题。
字段筛选器不适用于表别名
您将无法在对联接或 CTE 使用表别名的查询中从字段筛选器中选择值。
原因在于字段筛选器根据映射的字段生成 SQL;Metabase 不解析 SQL,因此它无法识别别名引用的是什么。根据查询的复杂程度,您有三种变通方法:
- 使用完整的表名。
- 用子查询替换 CTE。
- 在数据库中创建视图,并使用该视图作为查询的基础。
字段筛选器必须连接到查询中包含的字段
您的主查询应了解您的字段筛选器变量指向的所有表,否则您将收到 SQL 语法错误。例如,假设您的主查询包含如下字段筛选器:
SELECT
*
FROM
ORDERS
WHERE
{{ product_category }}
假设 {{ product_category }}
变量指的是另一个使用 Products
表的问题。为了使字段筛选器工作,您需要在主查询中包含一个到 Products
的联接。
SELECT
*
FROM
ORDERS
JOIN PRODUCTS ON ORDERS.product_id = PRODUCTS.id
WHERE
{{ product_category }}
自定义下拉列表和搜索框值
使用文本和字段筛选变量,您可以告诉 Metabase 用户在使用带下拉列表或搜索框的筛选器时可以选择哪些值。
- 在原生编辑器中,在双大括号中添加一个 {{variable}}。
- 如果侧边栏未打开,您可以点击右侧的 {x} 图标打开变量侧边栏。
- 在设置选项卡中,将变量类型设置为“文本”或“字段筛选器”。
- 在侧边栏中,转到用户应如何筛选此变量? 选择下拉列表或搜索框。
- 在您选择的选项旁边,点击编辑。
- Metabase 会弹出一个模态框,您可以在其中选择值的来源。
您可以选择:
- 从已连接的字段中获取 如果您选择了字段筛选变量类型,您还将可以选择使用已连接的字段。
- 从另一个模型或问题中获取。如果您选择此选项,您需要选择一个模型或问题,然后从该模型或问题中选择一个字段,Metabase 将使用该字段为下拉列表或搜索框提供值。例如,如果您希望下拉列表列出帐户可能拥有的不同计划,您可以选择您创建的“帐户”模型,并选择字段“计划”来为该下拉列表提供数据。然后,下拉列表将列出“帐户”模型中“计划”列中出现的所有不同计划选项。
- 自定义列表。每行输入一项。您可以输入任何您喜欢的字符串值。
您还可以更改仪表盘筛选器的可选值。
在筛选器小部件中设置默认值
在变量侧边栏中,您可以为变量设置默认值。此值将默认插入到相应的筛选器小部件中(即使筛选器小部件为空)。您需要向筛选器小部件插入一个新值来覆盖默认值。
在查询中设置复杂的默认值
您还可以通过在可选参数的结束括号内包含注释语法,直接在查询中定义默认值。
WHERE column = [[ {{ your_parameter }} --]] your_default_value
当您将值传递给 your_parameter
时,该注释将“激活”。
这在定义复杂默认值时非常有用(例如,如果您的默认值是一个函数,如 CURRENT_DATE
)。这是一个 PostgreSQL 示例,它使用 CURRENT_DATE
将日期筛选器的默认值设置为当前日期:
SELECT
*
FROM
orders
WHERE
DATE(created_at) = [[ {{dateOfCreation}} --]] CURRENT_DATE
如果您向变量传递一个值,则 WHERE
子句将运行,包括注释语法,该语法注释掉了默认的 CURRENT_DATE
函数。
请注意,用于注释文本的哈希符号 (--
) 可能需要替换为您所使用的数据库特有的注释语法。
要求筛选器小部件的值
在变量设置侧边栏中,您可以切换始终需要值选项。如果您打开此选项,则:
- 您必须输入默认值。
- 默认值将覆盖代码中的任何可选语法(例如可选的
WHERE
子句)。如果没有值传递给筛选器,Metabase 将使用默认值运行查询。点击编辑器中的眼睛图标可以预览 Metabase 将运行的 SQL。
使变量可选
您可以在查询中使子句可选。例如,您可以创建一个包含 SQL 变量的可选 WHERE
子句,这样如果未向变量提供任何值(无论是通过筛选器还是通过 URL),查询仍将运行,就像没有 WHERE
子句一样。
要在原生查询中使变量可选,请将包含 {{variable}}
的整个子句用 [[ .. ]]
括号括起来。如果有人在 variable
的筛选器小部件中输入值,Metabase 会将该子句放入模板中;否则 Metabase 会忽略该子句并运行查询,就像该子句不存在一样。
在此示例中,如果未向 cat
赋值,则查询将只选择 products
表中的所有行。但如果 cat
有值,例如“Widget”,则查询将只获取类别类型为 Widget 的产品:
SELECT
count(*)
FROM
products
[[WHERE category = {{cat}}]]
您的 SQL 也必须能够在不带 [[ ]]
中可选子句的情况下运行。
您需要确保当括号中的子句中的变量未传递任何值时,您的 SQL 仍然有效。
例如,如果从括号中的子句中排除 WHERE
关键字,当 cat
没有值时,将导致错误:
-- this will cause an error:
SELECT
count(*)
FROM
products
WHERE
[[category = {{cat}}]]
这是因为当 cat
没有值时,Metabase 将尝试执行 SQL,就像 [[ ]]
中的子句不存在一样:
SELECT
count(*)
FROM
products
WHERE
这并非有效的 SQL 查询。
相反,将整个 WHERE
子句放在 [[ ]]
中:
SELECT
count(*)
FROM
products
[[WHERE
category = {{cat}}]]
当 cat
没有值时,Metabase 将只执行:
SELECT
count(*)
FROM
products
这仍然是有效的查询。
使用多个可选子句时,您至少需要一个 WHERE
要使用多个可选子句,您必须至少包含一个常规的 WHERE
子句,后跟可选子句,每个子句都以 AND
开头:
SELECT
count(*)
FROM
products
WHERE
TRUE
[[AND id = {{id}}]
[[AND {{category}}]]
最后一个子句使用字段筛选器(请注意 AND
子句中缺少列)。使用字段筛选器时,必须从查询中排除该列;您需要在侧面板中映射变量。
MongoDB 中的可选变量
如果您使用 MongoDB,可以这样使子句可选:
[
[[{
$match: {category: {{cat}}}
},]]
{
$count: "Total"
}
]
或使用多个可选筛选器:
[
[[{ $match: {{cat}} },]]
[[{ $match: { price: { "$gt": {{minprice}} } } },]]
{
$count: "Total"
}
]
将 SQL 问题连接到仪表盘筛选器
为了使已保存的 SQL/原生问题可用于仪表盘筛选器,该问题必须至少包含一个变量。
可以与 SQL 问题一起使用的仪表盘筛选器类型取决于字段。例如,如果您有一个名为 {{var}}
的字段筛选器,并将其映射到状态字段,则可以将位置仪表盘筛选器映射到您的 SQL 问题。在此示例中,您将创建一个新的仪表盘(或转到现有仪表盘),单击铅笔图标进入仪表盘编辑模式,添加包含状态字段筛选器变量的 SQL 问题,添加一个新的仪表盘筛选器(或编辑现有位置筛选器),然后单击 SQL 问题卡片上的下拉菜单以查看状态字段筛选器。
如果您向问题添加日期变量,则只能使用仪表盘筛选器选项单个日期。因此,如果您尝试在仪表盘上使用其他时间选项之一,您需要将变量更改为字段筛选器变量并将其映射到日期列。
更多关于仪表盘筛选器。
进一步阅读
阅读其他Metabase 版本的文档。