aloudata logo
产品解决方案客户案例资源中心合作伙伴关于我们立即咨询

Text-to-SQL 没有答错,但答案不一定是你要的那个

作者:Aloudata 团队2026-03-30|NoETL 博客

上一期我们让小龙虾接上了语义层,六轮对话追出了 GMV 下跌的根因,还生成了定时报告。收到反馈最集中的一个疑问是:「我直接让 AI 写 SQL 查数据库不就行了吗?为什么还需要语义层?」这个问题值得认真回答,所以我们做了一组对比实验。这篇文章是实验的完整记录。没时间看视频的话,读这篇就够了。

这篇文章我们会回答四个问题:

一、实验公平吗? —— 我们给了 text-to-SQL 最好的条件。

二、五轮下来到底差多少? —— 一张表说清楚,再逐轮拆解。

三、这些口径是不是你们故意挑的? —— 不是。每条都是真实零售企业里踩过坑之后沉淀下来的共识。

四、那把口径维护在 Skill 或字典里不就行了? —— 方向对了,但还差最后一公里。

一、实验公平吗?

我们用的是一个零售场景的 Demo 数据集:3 张事实表(订单、库存、上市)加 3 张维度表(门店、商品、会员),标准维度建模,总共才 6 张表。现实中的数仓动辄几百张表,字段名经常是一串拼音缩写——跟那种环境比,我们这个已经简单到不能再简单了。

为了让对比尽量公平,我们专门写了一个 text-to-sql-query Skill,把完整的数据库 schema 都编码了进去:字段名、数据类型、中文注释、表间 JOIN 关系,一个不落。我们甚至还告诉它有哪些常见的口径歧义陷阱,要仔细分析和展示查询口径,必要时询问用户。

而且我们问的五个问题都非常基础,全是「上月 XX 是多少」的形式,不涉及归因、预测或任何多步推理,也不用考虑性能优化。就这种难度,来看看两边的答案会不会分叉。

Skill(含完整 schema)都已公开,链接在文末。

二、五轮下来到底差多少?

先上汇总:

轮次 问题 Text-to-SQL 语义层 差距
第一轮 销售额 19,349,217 ✅ 19,349,217 ✅ 0%
第二轮 坪效 30.99 / 6.05(每次不同) 1,527.77(永远一致) 49 ~ 253 倍
第三轮 连带率 58.40 42.39 37.7%
第四轮 净销售额 14,008,435 13,470,801 4.0%
第五轮 复购率 10.56%(促频次) 21.40%(促回访) 一倍 · 运营方向不同

只有第一题的答案完全一致——最简单的 SUM 聚合,没有任何口径歧义。后四题,四种不同的翻车方式。逐轮说。

坪效:同一个问题,问两次答案不一样

坪效就是每平方米产出多少销售额,零售行业最基本的空间效率指标。

语义层坪效的定义是这样:分子是 fact_orders 的销售额求和,分母是 dim_shop 的营业面积求和——但挂了两层过滤。第一层,shop_status = '开店',排除掉已关闭的门店;第二层,分子分母的数据日期都被限制在了查询周期内,只有当月有记录的在营门店才会进入计算。两层过滤叠加之后,2 月份进入分母的只有 24 家门店,面积合计 12,665 平方米。

而 text-to-SQL 这边,我们前后跑了两次,拿到了两个完全不同的结果。第一次是测试,AI 写了个非常直觉的 SQL——销售额除以面积,没做任何过滤,关店的门店面积也算了进去,得到 30.99。第二次录制的时候,AI 主动加上了 shop_status = '开店'。我们一度以为这次会算对呢,结果出来是 6.05——反而偏得更远了。原因是它虽然过滤了门店状态,但没有对 dim_shop 做时间范围过滤,分母变成了全部 6,040 家开店门店的面积总和(320 万平方米),而分子只是上月一个月的销售额。分子和分母的口径完全没有对齐。

「哪些门店该进入分母」以及「分母要不要跟分子对齐时间范围」,这两条规则在 schema 的字段注释里完全找不到。它们是被编码在语义层指标定义里的业务规则,AI 靠读表结构很难准确推断出来。

连带率:毛件数还是净件数

连带率(UPT),指的是每笔交易平均卖出几件商品。text-to-SQL 用的是 retail_quantity,也就是毛销售件数,包含了后来被退掉的部分;语义层用的是 net_quantity,扣除退货之后的净件数。这个月退了将近两万件,所以两个口径差出了 16 件,接近 38%。

哪种更「对」?取决于你是谁。比如销售培训部门关心的是导购当时推了多少件,退货是售后的事,毛件数合理;而商品企划部门关心的是最终留在顾客手里多少件,净件数合理。企业完全可以同时保留毛连带率和净连带率两个指标——但「连带率」这三个字不加限定地出现在月报里的时候,它到底指的是哪一个?这就需要有人来管了。

净销售额:最安静的 4%

数据库里有一个字段就叫 net_amount,字面意思就是「净金额」。AI 看到用户问"净销售额",选了这个字段,完全合情合理。但语义层定义的「净销售额」不是这个字段——它是 retail_amount - return_amount,也就是毛销售额减去退货金额。两者差了 54 万,因为 net_amount 里还包含了一些其他调整项,跟业务团队理解的「净销售额」不是同一个概念。

4% 的偏差是五轮里最小的,但反而最危险。前面坪效差了几十上百倍,连带率差了将近四成——差距大到你一眼就能发现不对。但 4% 放进一张月报表格里,大多数人根本注意不到。54 万就这样安安静静地混了进去,汇报了一整年,年底盘账的时候才发现全年累计差了六百多万。

复购率:同一个词,两种运营方向

text-to-SQL 把「复购」理解成了月内重复购买——当月下过两笔以上订单的客户占比,10.56%。语义层的定义是跨月回访——上个月买过、这个月又来了的客户占比,21.40%。差了整整一倍。

两边给出的建议方向乍看是一致的:都觉得偏低,都建议加大投入。但仔细看就会发现它们指向的运营动作完全不同。10% 对应的策略是「促频次」——怎么让顾客一次多买几单,手段是满减券、凑单优惠;21% 对应的是「促回访」——怎么让上个月的顾客这个月再来,手段是会员召回、到店激励。同样叫「复购率」,如果你带着做好留存的目的来问数,看到 10% 和 20% 你要投入的预算相差的恐怕不止 1 倍了。

三、这些口径是不是你们故意挑的

一定会有人这样想:坪效要过滤门店状态还要对齐时间、连带率要用净件数、复购率用跨月口径——这些看起来那么「讲究」的定义,是不是你们为了衬托语义层刻意设计的?

不是。这些就是真实零售企业在经营过程中,被各种数据事故教训出来的规则。坪效的分母不过滤关店门店,管理层看到的空间效率指标就是失真的,据此做出的门店调整方案会全部偏离;连带率混用毛净口径,退货率高的月份里销售团队可能反而以为自己干得不错;复购率的定义运营和会员两个团队各用一套,季度复盘的时候如果两个口径都上了总经理办公会,信任就崩了。

每一条规则背后都是踩过的坑。如果你觉得这些口径「刁钻」,恰恰说明这类业务常识在你的组织里可能还是隐性的、靠口头传递的——而口头传递到不了 AI 那里。

四、那把口径维护在 Skill 或字典里不就行了

这个思路的方向是对的——你已经看到了核心问题不在 AI 的能力,而在口径的管理。

具体做法无非两种。一种是把指标定义直接写进 Skill 的 prompt 里,告诉 AI「遇到坪效要怎么过滤、复购率用跨月口径」。另一种更优雅一点,维护一份口径字典,AI 每次查数之前先去字典里检索对应定义,再据此生成 SQL。

两种都试得通,但都绕不开同一个问题:AI 拿到了正确的定义之后,还是要自己把它翻译成 SQL。翻译这一步,就可能漏。

坪效那一轮已经说明了问题。就算你把定义写得清清楚楚——分母只取在营门店、时间范围要跟分子对齐——AI 第二次确实做到了过滤门店状态,但维度表的时间过滤还是漏掉了。两层规则只落地了一层,结果偏得比不过滤的时候还远。

还有一个更现实的问题:规模。5 个指标的定义塞进 prompt 或字典没有任何压力,但真实企业动辄几百上千个指标。全塞进 prompt,模型的注意力会断崖式下降;放在字典里检索好一些,但指标口径不是定好了就一成不变的——下个季度「坪效」的分母可能从「在营门店」改成「在营满 30 天的门店」,你得在字典里持续维护,对它负责,AI 则要找到它、改对它,然后祈祷没有遗漏。

语义层的做法则是定义即执行。你在语义层里定义好坪效的口径,查询时这个定义直接生成查询结果,中间没有「AI 读懂定义→AI 自己再写一遍 SQL」这个翻译环节。没有翻译,就没有遗漏的机会。

打个比方:把口径写进 Skill 是用记事本管配置,维护口径字典是用 Excel 管配置,语义层是用配置中心管配置。思路一脉相承,但能承载的复杂度完全不在一个量级。

最后说几句

这次实验最打动我们的发现,其实不是「text-to-SQL 容易出错」——它给出的每一个数字都是数据库里真真切切算出来的,没有一个是「错」的。真正的问题在于:同一个业务概念,每次问都可能得到不同的答案。

在 BI 时代,口径不一致的问题当然也存在,但它有一个天然的纠偏机制:数据是人生产的,也是人消费的。分析师出了一版报表,业务负责人看完觉得不对,开个会对一下口径,下次就改过来了。口径的对齐发生在人与人的沟通中——虽然低效,但总归有人兜底。

到了 AI 时代,这个纠偏环节消失了。AI 写完 SQL 直接返回结果,没有人在中间「看一眼觉得不对劲」,甚至未来的消费者都不再是人类。如果口径本身没有被显性地定义和管理,AI 每次都是在临场发挥——后果会非常严重。

与此同时,业务本身是流动的。口径不能只沉淀不变更,管理和生产必须是动态一致的。这两点加在一起——AI 时代需要显性的语义治理,而语义本身又在持续演化——决定了你需要的不是一份静态的文档或字典,而是一个活的系统。

Aloudata CAN 就是这样一个系统。它不只是管定义的:定义指标时强制进行口径判重和名称去重,让同一个概念不可能同时存在两套互相矛盾的口径;强制注册属性信息,每个指标的计算逻辑、负责人、适用范围都有据可查。更关键的是,它同时也是一个动态数据服务引擎——内置智能加速引擎,代持了传统 DWS/ADS 层的人工 ETL 工程。你不需要手工建宽表,定义好指标,Aloudata CAN 自动完成从管理到查询的全链路。

一句话总结:语义层不是 AI 的替代品,是 AI 的前置依赖。

资源

https://clawhub.ai/jackyujun/metric-query

https://clawhub.ai/jackyujun/metric-attribution

  • 申请 Aloudata CAN Demo 环境 API Key:

申请 Aloudata CAN Demo 环境 API Key

Topic Hub

数据架构与建模

相关产品推荐
Recommended

Aloudata Agent

基于 NoETL 明细级语义编织的企业级可信数据分析智能体,以指标为中心进行语义一致的对话式数据分析。

联系我们
contact us code
扫码关注 Aloudata 微信公众号
获取更多 NoETL 技术干货
contact us code
扫码加入 Aloudata 技术交流群
获取更多最新案例资讯

即刻开启可信智能之旅

我们的行业专家会第一时间联系您,帮助您了解更多
aloudata logo

电话0571-85106688

邮箱marketing@aloudata.com

简历hr@aloudata.com

wechat service qr code扫码关注 Aloudata

© 2021-2026 大应科技有限公司 浙 ICP 备 2021026047 号 -1

浙公网安备 33010602011980 号