昨天的文章:有老铁留言,直接SQL不就行了吗,为什么要用宏.
这是一个非常好的问题。你是对的,从功能上讲,所有宏(Macro)能做的事情,直接写 SQL 确实都能做。
但是,在工程化和复杂数据分析中,“能做”不代表“好维护”或“高效率”。

DuckDB 引入宏(Macro),本质上是为了解决 SQL 语言长久以来的一个痛点:缺乏轻量级的逻辑复用机制。
你可以把“直接写 SQL”比作“复制粘贴代码”,而“宏”就是编程语言中的“函数(Function)”。
以下是为什么要用 DuckDB 宏的 4 个核心理由:
1. 消除重复代码(DRY 原则)
如果你有一段复杂的逻辑(比如复杂的税费计算、特殊的时间戳转换),在标准 SQL 中,你必须在每个查询里重复写这段公式。
- 直接写 SQL(痛点):
- 如果公式变了(比如税率变了),你需要去 10 个不同的 SQL 文件里修改。
-- 查询 A SELECT item, price * 0.85 + (price * 0.1) - 5 as final_price FROM sales; -- 查询 B SELECT item, price * 0.85 + (price * 0.1) - 5 as final_price FROM inventory;- 使用宏(解法):
- 定义一次,到处调用。修改时只需改宏定义。
-- 定义宏 CREATE MACRO calc_price(p) AS p * 0.85 + (p * 0.1) - 5; -- 调用SELECT item, calc_price(price) FROM sales; SELECT item, calc_price(price) FROM inventory;2. 参数化的“视图”(比 View 更强)
标准 SQL 的 VIEW(视图)是静态的。你不能给视图传参数。如果你想查“过去 7 天的数据”和“过去 30 天的数据”,你通常需要写两个查询或者在 WHERE 子句里手动改。
DuckDB 的表宏(Table Macro) 允许你创建“带参数的视图”。
- 直接写 SQL:
- SQL
- -- 必须手动写 WHERE 条件
- SELECT * FROM web_logs WHERE date > current_date - INTERVAL '7 days';
- 使用宏:
- 你可以封装逻辑,让使用者只关心参数。
CREATE MACRO get_recent_logs(days_count) AS TABLE SELECT * FROM web_logs WHERE date > current_date - INTERVAL (days_count || ' days'); -- 调用时非常清爽 FROM get_recent_logs(7); FROM get_recent_logs(30);3. 提高可读性(业务语义化)
复杂的 SQL 往往充满了晦涩的 CASE WHEN、CAST 或正则表达式。宏可以把这些“技术细节”隐藏起来,暴露“业务含义”。
- 直接写 SQL(晦涩):
SELECT regexp_extract(user_agent, 'Chrome/([0-9]+)', 1) as chrome_version FROM logs;- 使用宏(清晰):
CREATE MACRO extract_ver(ua) AS regexp_extract(ua, 'Chrome/([0-9]+)', 1); SELECT extract_ver(user_agent) FROM logs;- 对于阅读代码的人来说,extract_ver 比一长串正则更容易理解。
4. 这里的“宏”比 Python UDF 更快
很多数据库为了复用逻辑,会让你写 Python 或 Java 的 UDF(用户自定义函数)。但在数据量大时,Python UDF 会有性能损耗(数据要在数据库引擎和 Python 解释器之间传输)。
DuckDB 的宏是 SQL 级别的替换。
- 当你运行带宏的查询时,DuckDB 引擎会在执行前把宏“展开”成原始 SQL 表达式。
- 性能损耗为 0。它享受和原生 SQL 完全一样的优化器加速。
总结
维度 | 直接写 SQL | DuckDB 宏 (Macro) |
复用性 | 靠复制粘贴 | 定义一次,处处调用 |
维护成本 | 高(改一处需改全身) | 低(只改定义) |
灵活性 | 只能写死逻辑 | 支持传参数 (Scalar/Table) |
可读性 | 代码冗长,业务意图不明显 | 语义清晰,隐藏技术细节 |
性能 | 原生速度 | 原生速度 (优于 Python UDF) |
一句话总结:
如果你只是写一次性的查询,直接 SQL 没问题;但如果你在构建一个需要长期维护的数据分析项目,或者需要给团队其他人提供好用的工具,宏是 DuckDB 给你的一把“封装神梯”。