Metabase Concat 表达式完全指南:列拼接、类型转换与 SQL/Spreadsheet/Python 等价实现
发布时间:2026/9/12 14:41:40 作者:尧图编辑部 阅读量:1,286

Metabase Concat 表达式完全指南列拼接、类型转换与 SQL/Spreadsheet/Python 等价实现【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase导读concat是 Metabase 自定义表达式Custom Expressions中最常用的字符串函数之一用于将两个及以上列或值拼接为一个字符串典型场景包括合并城市 国家生成完整地址、拼接订单号前缀、组合姓名与称谓等。本文以官方文档docs/questions/query-builder/expressions/concat.md为核心骨架结合 Metabase 开源仓库中 MBQLMetabase BI Query Language的 schema 定义、查询转换器与 SQL 驱动实现完整讲解concat的语法、参数规则、非字符串列的自动类型转换行为、可接受数据类型以及它与 SQLCONCAT、ExcelCONCATENATE、Python 字符串相加的等价写法。读完本文你将能在 Metabase 查询构建器中熟练使用concat生成自定义列并理解其底层执行机制。什么是 concatconcat拼接将两个或多个列字段或值按顺序连接在一起并返回一个字符串。它是查询构建器表达式编辑器中字符串函数一族的代表成员与substring、regexextract、replace等函数一起在metabase.lib.schema.expression.string中被统一定义。从 MBQL 的 schema 定义看concat是一个catnconcat-and类型的子句其返回类型被固定为:type/Text参数由[:args [:repeat {:min 2} [:schema [:ref ::expression/expression]]]]约束——即至少需要两个参数每个参数可以是任意表达式列引用、字面量或嵌套函数(mbql-clause/define-catn-mbql-clause :concat :- :type/Text [:args [:repeat {:min 2} [:schema [:ref ::expression/expression]]]])该定义位于 src/metabase/lib/schema/expression/string.cljc是前端表达式校验与后端 MBQL 解析共享的唯一事实来源.cljc双平台文件。这意味着无论你在查询构建器中书写还是通过 API 提交 MBQLconcat的参数数量与类型都会先经过这层 schema 校验。语法concat(value1, value2, ...)value1、value2… 可以是列引用或字面值Metabase 会在拼接前将非字符串类型的列自动转换为字符串表达式的结果始终是字符串无论传入值的类型如何参数之间按书写顺序依次连接不自动插入任何分隔符——需要分隔符如逗号、空格时必须作为独立的字符串参数显式写出。列引用使用方括号语法例如[City]、[Country]字符串字面量使用双引号例如 is in 。关于列引用、连接表列[ConnectedTableName.Column]以及引用已保存的指标/分段的通用规则可参阅 自定义表达式总览。示例表达式结果concat(Vienna, Austria)ViennaAustriaconcat(Vienna, is in ,Austria)Vienna is in Austriaconcat([City], is in ,[Country])Vienna is in Austria第一行演示了纯字面量拼接注意没有自动加空格第二行演示了用字面量插入分隔文本第三行演示了实战中最常见的形态——拼接两个列并在中间插入分隔符。非字符串列Metabase 使用未格式化raw值这是使用concat时最容易踩的坑当你在concat中使用非字符串列时Metabase会忽略你在列上配置的任何格式化Formatting设置直接使用底层数据库返回的原始值进行转换拼接。例如你在表格结果中把一个数字列格式化为只显示两位小数concat的结果仍会包含原始数据里如果有的话更多的小数位。格式化后的显示原始值concat(Result:, , [Value])KittenKittenResult: Kitten1717Result: 1731.2531.24823945Result: 31.2482394542%0.42Result: 0.42January 1, 20242025-02-11 21:40:27.892Result: 31.24823945要点数字31.25的格式化显示与concat结果不一致因为拼接使用的是31.24823945这个原始值百分比42%在拼接结果中变成0.42原始的比值小数日期列也是如此——即使显示为January 1, 2024拼接输出的是完整时间戳2025-02-11 21:40:27.892。因此若你需要格式化后的文本效果如保留两位小数、百分比符号、特定日期格式应在拼接前先用format相关的字符串函数或对原始值做预处理而不是依赖列的展示格式化。列格式化本身的管理方式见 数据建模 - 格式化。可接受的数据类型数据类型是否可用于concatString✅Number✅Timestamp✅Boolean✅JSON✅所有非字符串类型都会被转换为字符串无论传给concat的值是什么类型结果始终是字符串。这一点与 schema 定义中返回类型固定为:type/Text完全一致类型系统在 MBQL 层面就保证了concat的输出一定是文本。从查询转换链路看这一结果必为字符串的约束还体现在 src/metabase/lib/convert.cljc——该文件将:concat与:substring、:replace、:regex-match-first、:split-part、:collate等字符串算子归为一类进行统一转换处理确保这些表达式在进入 SQL 编译阶段前保持一致的语义。在查询构建器中使用 concatconcat最常见的用途是在**自定义列Custom Column**中创建新的文本字段在查询构建器中点击自定义列Custom Column在表达式编辑器中输入例如concat([City], , , [Country])为新列命名如Location点击Done完成。concat也可以作为**过滤器Filter或汇总Summarize**表达式的一部分虽然过滤器场景通常配合contains等谓词使用。关于表达式编辑器的完整操作方式函数浏览器、自动格式化、聚合与函数的区别等参见 自定义表达式文档。快捷操作合并列Combine Columns值得一提的是Metabase 还为字符串列提供了Combine Columns合并列的快捷操作点击列头时如果当前列是字符串列会触发:drill-thru/combine-columns动作底层自动生成一个concat表达式把点击的列与一个或多个分隔符 列对拼接起来。该功能在 src/metabase/lib/drill_thru/combine_columns.cljc 中实现触发条件列存在、value为空非聚合场景、当前 stage 是 MBQL stage、且该列的语义类型为字符串效果等价于手动写出concat([Column], [separator], [nextColumn], ...)的自定义表达式。这意味着大多数合并两列的需求你甚至不需要手写表达式直接点击列头选择 Combine Columns 即可生成的结果就是一个concat表达式。底层执行从 MBQL 到 SQL当你在查询构建器中写完concat([City], , , [Country])并运行后Metabase 会把它编译成针对底层数据库的 SQL。以关系型数据库为例最终执行的语句形如SELECT CONCAT(City, , , Country) AS Location FROM richard_linklater_films;在 SQL 驱动的查询处理器 src/metabase/driver/sql/query_processor.clj 中MBQL 的:concat子句会被编译为 HoneySQL 形式的[:concat ...]表达式再交由具体驱动生成各数据库方言的拼接语法如 MySQL/PostgreSQL 的CONCAT、SQLite 的||等。同一个concat表达式在 generate-pattern 等内部逻辑中也被复用——例如实现contains/starts-with/ends-with这类LIKE匹配时非字面量模式会通过[:concat pre arg post]构造匹配串可见concat是 SQL 后端的基础算子。因此可以推断concat的拼接工作在数据库端完成Metabase 的自动类型转换最终表现为 SQL 中的隐式/显式字符串转换这也是为什么展示格式化不会生效——格式化是前端展示层的行为而拼接发生在 SQL 层。与其他工具函数的等价实现SQL如果你的数据存在关系型数据库中notebook 编辑器生成的查询最终都会转成 SQL。以下 SQLSELECT CONCAT(City, , , Country) AS Location FROM richard_linklater_films;等价于 Metabase 表达式concat([City], , , [Country])注意不同数据库的拼接语法略有差异MySQL/PostgreSQL/SQL Server 使用CONCATSQLite/PostgreSQL 也支持||运算符Metabase 驱动层会屏蔽这些差异让你始终用统一的concat书写。Spreadsheets电子表格如果样本数据在电子表格中City 在 A 列、Country 在 B 列可以用公式在 C 列生成 LocationCONCATENATE(A2, , , B2)等价于 Metabase 表达式concat([City], , , [Country])Excel/Google Sheets 中的运算符、CONCAT函数同样可达到类似效果Metabase 的concat语义与它们一致按参数顺序拼接、不自动加分隔符。Python假设样本数据在名为df的 DataFrame 中df[Location] df[City] , df[Country]等价于 Metabase 表达式concat([City], , , [Country])Metabase 表达式与编程语言写法的共同点是所有操作都是按行进行的向量化操作——对每一行独立计算拼接结果这正是表达式Functions与聚合Aggregations的本质区别详见 自定义表达式文档。常见问题与最佳实践不要依赖自动分隔符concat不会自动插入空格或逗号。concat(Vienna, Austria)的结果是ViennaAustria。始终把分隔符写成独立的字符串参数。分隔符用字面量分隔符属于固定文本应写成双引号字符串字面量如, 、 - 、 。注意类型转换语义数字、布尔、时间戳、JSON 都会转换为原始字符串。若需要格式化后的文本两位小数、百分比符号、YYYY-MM-DD日期先格式化再拼接。参数至少两个MBQL schema 强制要求concat至少 2 个参数单参数拼接没有意义可考虑直接引用列或使用其他函数。空值与拼接当参与拼接的列含NULL时不同数据库的行为可能不同有的数据库CONCAT(NULL, ...)直接返回NULL。若需要将空值视为空字符串可结合coalesce使用例如concat(coalesce([City], ), , , coalesce([Country], ))。优先使用 Combine Columns 快捷操作仅拼接现有字符串列时点击列头选择 Combine Columns 即可自动生成concat表达式减少手写出错的可能。延伸阅读自定义表达式文档总览 —— 表达式编辑器、函数浏览器、聚合与函数的区别Substring子串截取 —— 与concat搭配的字符串处理函数Coalesce空值兜底 —— 处理拼接中的 NULL 值数据建模 - 格式化 —— 了解列格式化与concat原始值行为的关系表达式 schema 定义 ——concat在 MBQL 层的最小参数与返回类型约束合并列 drill-thru 实现 —— Combine Columns 快捷操作的底层原理【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考