SQL参数
您可以在原生/SQL编辑器中通过向SQL查询添加变量来创建SQL模板。这些变量将创建过滤器小部件,您可以使用它来更改查询中变量的值。您还可以将参数添加到问题的URL中,以设置过滤器的值,以便当问题加载时,这些值将插入到变量中。
定义变量
在您的本地查询中键入{{variable_name}}
将创建一个名为variable_name
的变量。
字段过滤器,一种特殊的过滤器,其语法略有不同。
此示例定义了一个名为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将为问题添加多个过滤器小部件。当您有多个过滤器小部件时,您可以单击过滤器小部件并拖动它来重新排列顺序。
字段过滤器变量类型
将变量设置为Field Filter
类型允许您将变量映射到当前数据库中任何表中的字段。字段过滤器允许您创建适合该字段的“智能”过滤器小部件。
字段过滤器变量应在SQL中的WHERE
子句或MongoDB中的$match
子句内部使用。
字段过滤器兼容类型
字段过滤器仅与以下字段类型兼容
- 分类
- 实体名称
- 实体键
- 外键
- 城市
- 州
- ZIP或邮政编码
字段也可以是日期或时间戳,可以在表元数据中将其保留为“无语义类型”。
当您将变量类型设置为“字段过滤器”时,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
)很有用。以下是一个使用CURRENT_DATE
设置日期过滤器默认值为当前日期的PostgreSQL示例。
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的其他版本的文档。