2018 — 2026蒸汽教育 · 八周年

用AI做数据分析,面试怎样证明结论可靠:从生成SQL到复算业务指标

用订单与退款的完整原创案例,演示AI生成SQL后怎样核对口径、连接粒度、同额订单反例和独立手算,附可运行SQLite练习及面试追问,帮助证明分析结论的可靠性。

圆眼镜男主对照两组计数线,独立复算数据结果
📅 时效更新核对日期:2026-10-30。查询使用SQLite与合成订单资料;错误AI草稿为人工构造示例,不代表任何模型现场输出。

AI能写SQL,但你还不能证明结论可靠?

添加顾问微信,带目标分析岗位、查询和一个错误样本,讨论口径、SQL验证与面试表达。

文 / STEM Career 编辑部

AI可以很快写出SQL、解释表格并生成图表,但这些产物连在一起,并不自动成为可靠分析。一个错误连接会放大金额,一个不清楚的分母会改变比例,图表又可能把错误包装得更容易相信。面试官追问“你怎么知道这个结论对”,真正需要的是你自己的核验过程。

本文用一组原创订单与退款数据,完整演示从业务口径到错误查询、错误修补、独立复算和结论表达。文中的“AI草稿”是人工构造的教学示例,没有声称由某个模型现场生成;可运行程序也不调用模型。练习目标是让你能发现、修正并解释分析问题,而不是背一段正确SQL。

先把业务问题改写成可计算的口径

假设运营同事问“九月的订单净额是多少”。这句话至少有几个歧义:是九月创建、九月支付,还是九月发生的收入事件;扣除哪些退款;退款发生在十月是否仍要计入;金额是否包含税费、运费和不同币种。模型无法替业务方决定这些问题,直接写查询就会把未确认的假设藏进代码。

本题定义为:选出九月创建且当前状态为已支付的订单,汇总实付,减去退款表中这些订单的全部退款。所有金额是同一币种的整数分,没有税、运费与重复订单;资料为一次完整的教学快照。它是“订单月份分群净额”,不是九月退款事件口径,也不是财务报表里的收入确认。

将时间窗口明确为九月一日含当天,十月一日不含当天。这样十月一日创建的订单不会因为结束日期写得模糊而误入。真实资料若有时区,先约定业务时区与时间字段转换,再查询。不要在报告里写一句“按月统计”,让读者猜测你用的是哪个月份定义。

在生成查询前画清每张表的粒度

订单表每个订单一行,主键是订单标识;退款表每笔退款一行,一个订单可以对应多行。两张表连接以后,订单字段可能重复出现。这并不说明源订单表有重复,也不等于需要把所有记录去重,问题来自关系的粒度。

本例订单甲实付一万分,有两笔退款,分别两千与一千分;订单乙实付六千分,没有退款;订单戊实付一万分,没有退款。还有一笔九月待支付订单和一笔十月一日已支付订单,按口径都不计。正确的九月合格订单共有三笔,实付两万六千分,退款三千分,净额两万三千分。

SQLite的SELECT说明描述了连接输入、过滤与聚合等查询行为。这里最重要的实践问题,是连接后“一行代表什么”有没有改变。把甲与两笔退款连接,会出现两行甲;如果你还把每行的实付都当成新订单金额,聚合结果自然偏高。

第一份看起来合理的草稿为什么错

假设草稿把订单与退款直接左连接,筛选九月已支付,再计算每行的实付减退款后求和。它使用左连接保留没有退款的订单,也用空值替换处理无退款,表面上考虑得很周全,但仍然犯了重复计算实付的问题。

在连接结果中,甲先出现一万减两千,再出现一万减一千,两行合计一万七千;乙六千,戊一万,总共三万三千分。正确的甲只应计一万减三千,即七千分。差额恰好是被重复加入的一万分实付,不是退款金额本身算错。

这时不要只说“有重复数据”。准确描述应为:一对多连接把订单粒度扩展成订单与退款记录的组合,随后对订单金额求和导致放大。这个解释能指导修复,也能应对面试官把退款表换成商品明细、优惠记录或用户行为表的追问;根因仍是粒度不一致。

加上DISTINCT为什么可能修得更错

一种常见补丁是对实付金额使用 SUM(DISTINCT paid_cents),再扣退款。它会把相同金额只加一次,却不知道这些金额属于不同订单。甲和戊恰好都付了一万分,因此其中一笔合法订单的金额被丢掉,结果变成一万三千分。

SQLite聚合函数文档说明聚合参数中的DISTINCT会先排除相同值。相同金额与相同订单不是同一件事;金额重复完全可以是正常业务。该文档也区分统计全部行和统计非空值,提醒我们在面试中说清楚计数到底针对哪种对象。

如果测试资料里所有订单金额刚好不同,这个补丁可能碰巧通过。刻意安排甲和戊同额,就是一个能够推翻错误修法的反例。好的核验集不需要一开始就很大,但每个样本应针对一条可能被误解的规则。增加更多没有退款且金额各异的订单,反而可能让错误更难被看见。

让退款先回到订单粒度再连接

修复思路是先按订单标识汇总退款,让退款子查询也变成每个订单一行,再与订单连接。这样合格订单仍是三行,每个实付只出现一次。最后分别汇总实付、退款与净额,并把行数和不同订单数一起输出,作为粒度检查。

WITH refund_totals AS (
  SELECT order_id, SUM(amount_cents) AS refunded_cents
  FROM refunds
  GROUP BY order_id
)
SELECT COUNT(*) AS order_rows,
       COUNT(DISTINCT o.id) AS distinct_orders,
       SUM(o.paid_cents) AS paid_cents,
       SUM(COALESCE(r.refunded_cents, 0)) AS refunded_cents,
       SUM(o.paid_cents - COALESCE(r.refunded_cents, 0)) AS net_cents
FROM orders o
LEFT JOIN refund_totals r ON r.order_id = o.id
WHERE o.status = 'paid'
  AND o.created_at >= '2026-09-01'
  AND o.created_at < '2026-10-01';

这段查询只表达本题口径。若退款表含多个币种、撤销退款、重复导入或部分失败状态,需要先处理相应规则;如果问题改为“九月实际发生的资金流”,就不能沿用当前订单月份筛选。面试官改变条件时,应先说明需要调整哪一层,而不是机械保护自己已经写好的SQL。

用独立手算打破查询自证的循环

下载SQL核验练习包,使用Python三点十或更高版本运行 practice.py,它会建立内存SQLite数据库。程序已经执行,直接连接得到三万三千分,错误DISTINCT补丁得到一万三千分,先聚合退款的查询得到两万三千分。

请先在纸上写出甲、乙、戊各自净额,再求和。核验代码另外用这三个手算值求和,与查询结果比较,而非调用同一条SQL生成“标准答案”。若预期和实现来自同一段错误逻辑,两个结果一致也无法发现问题,这正是分析项目容易出现的自证循环。

程序还增加九月一日创建的零金额已支付订单,确认订单数增加而净额不变。它同时考验开始边界与零金额,不把净额为零误解为没有订单。执行通过只支持当前有限数据和口径,没有验证真实财务系统、不同数据库或大规模查询性能。

让AI参与 却把检查点留在自己手里

向AI提供的内容应包括字段解释、主键、一对多关系、业务时间与预期输出,而非只给一句“帮我算净额”。可以请它先列出不确定条件与可能的连接风险,再生成查询。这会改善讨论起点,但不能替代你检查源资料和业务约定。

得到草稿以后,先要求解释连接后每行的含义,再用小样本运行。接着构造同额订单、无退款、多退款、边界日期和待支付状态,检查每项规则。模型给出解释时也可能误判;你需要用数据推翻或支持,而不是因为解释听起来流畅就接受。

还可以把错误查询交回AI,请它提出两个修法并说明各自条件。比较“先聚合”与“对金额去重”,观察它是否理解粒度。项目记录保留你否决某条建议的理由,比把全部对话粘进作品集更有用。真正的贡献是你怎样选择和验证,不是提示词写了多长。

从数字走到业务结论仍要再走一步

正确净额只回答本题的一个统计问题,尚不能解释业务为什么变化。若九月净额比八月低,需要对齐月份口径,检查支付完成程度、退款观察窗口和资料更新日,再考虑用户、商品或渠道结构。仅凭两个月总额就声称某渠道导致下降,会把观察当成原因。

例如九月刚结束时仍可能有退款尚未进入快照,八月却已经有更长的观察时间。若你比较订单最终净额,两组成熟程度不一致;若比较截至各月末已知净额,则需分别重建当时快照。没有历史快照时要承认信息限制,不用当前表假装恢复过去每一天的真实状态。

图表也应保留分母和口径。可以同时画实付、退款与净额,并注明单位为分或转换后的币种金额。坐标截断、取整和只有百分比没有基数,都可能夸大变化。先保证数字能被解释,再选择图形,不要让自动生成的漂亮图表成为分析完成的唯一证据。

面试官追问时可以沿四层回答

第一层讲问题与口径,说明当前分析真正统计什么;第二层讲数据关系,说明为何不能直接连接后求和;第三层讲验证,展示反例、手算和边界;第四层讲结论范围,说明数字支持什么、还不支持什么。四层之间的连接,比背一个工具清单更容易被评估。

若被问“用AI后你还做了什么”,可以指出你补全业务定义、构造同额订单反例、否决DISTINCT补丁并安排独立复算。若被问“为什么不用全量数据直接看结果”,解释全量可用于后续确认,但小样本更容易定位错误关系;两者目的不同,不能用规模掩盖逻辑不清。

不要把“查询可以执行”当成正确性,也不要把“核验样本通过”当成覆盖所有业务。可以明确本题尚未处理跨币种、退款撤销和按事件月份统计。接下来由新增需求决定增加哪些规则。承认准确边界,通常比声称“我已经保证数据完全准确”更便于继续技术讨论。

作品集保留哪些文件才方便复查

建议提交字段与口径说明、合成数据、错误草稿、修复查询、独立预期、运行命令和一页结论。文件命名可以直白,让阅读者先看问题,再看修复与结果。没有必要把全部聊天历史作为主交付,但应简要说明AI参与了哪些步骤,你亲自核验了哪些内容。

如果源数据不能公开,就使用不含真实标识的原创小例子演示方法,并明确这是重建练习。不要把真实客户截图打码后就默认可以公开,也不要将合成数据的订单量写成实际业务规模。项目中能公开的范围,先与拥有资料的一方确认;简历可以描述职责和可核对产物,不需要暴露客户数据。

技能准备可以继续连接数据与商业分析面试和Excel业务分析练习。前者帮助串起SQL和业务判断,后者练从杂乱表格追到可靠汇总,最终都要能说明结论如何从资料中得到。

把复盘变成下一次真正会做的动作

做完练习后,请同伴改变一项条件:同一个订单出现两笔同额退款,金额允许为空,或者问题改为十月发生的退款。先说旧查询哪些部分仍适用,哪些必须重写,再动手修改。不要只记住本题正确金额,那会在条件变化后失效;要记住的是口径、粒度、反例和独立预期之间的关系。

对每项新条件,再写一个会让旧方案失败的最小输入。例如加入同额退款,不应因为两笔金额一样就只计一次;加入空金额,则先决定它代表未知、未发生还是资料错误。没有约定之前,不要为了让求和返回数字就一律替换成零。缺失含义属于分析契约,不能交给函数默认行为决定。

下一轮可以不使用AI先完成小样本推演,再让工具生成一份不同写法,对照结果与执行逻辑。若两条查询相同,也仍需用规则核验;若不相同,就判断差异来自语义、方言还是性能。最终保留你能够独立解释的版本,让作品与能力证据一致。

如果你已有分析项目,却在追问中说不清“怎么证明对”,可以带目标岗位、一份查询和一个错误案例咨询。蒸汽数据项目与面试准备服务可以围绕真实卡点讨论口径澄清、SQL验证与结果表达,帮助你把工具产物变成自己能够负责的分析过程。

常见问题(FAQ)

SUM DISTINCT能解决连接重复吗?

它按金额值排重,可能丢掉不同订单的相同金额,不能代替粒度设计。

示例中的净额是财务收入吗?

不是,口径是九月创建且paid订单减去表中其全部退款。

程序运行成功就算分析正确吗?

还要核对业务口径、数据关系、反例、独立预期和结论范围。

参考资料与官方说明
AI能写SQL,但你还不能证明结论可靠?

添加顾问微信,带目标分析岗位、查询和一个错误样本,讨论口径、SQL验证与面试表达。