首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我不再信 AI 生成的 SQL ,我现在信这套做法

我不再信 AI 生成的 SQL ,我现在信这套做法

原创
作者头像
析言
修改2026-09-14 17:11:54
修改2026-09-14 17:11:54
330
举报
文章被收录于专栏:SQLazySQLazy

为什么我不信任 AI 生成的 SQL 了,不是因为它不通,而是因为它太通——能过语法检查、能执行,却可能在不注意的地方漏洞百出。

你有没有遇到过 AI 给的 SQL 通过了语法检查、执行不报错,数据却悄悄错了一行?

能跑,不等于可信

一个看起来很简单的需求:状态流水表用字段 "NewStatus" 记录每个 ID 的状态,每个 ID 都有 "ConfirmationStarted" 和多条 "Closed",要取 "ConfirmationStarted" 之前最近的那条 "Closed"。

期望结果:

以 ID=147 为例,在 ConfirmationStarted 之前共有三条 Closed,最后一条 06-25 才是“最近的一条”;08-25 虽也是 Closed 但已在 ConfirmationStarted 之后,不算。

期望结果只有两行:"147→2022-06-25"、"1645→2023-04-29"。其他 Closed 要么太早,要么在 ConfirmationStarted 之后,都不算。

把需求丢给 AI,几秒拿到一段漂亮的 SQL,CTE 套窗口函数,review 时挑不出毛病。上线两周后对账才发现 147 取成了 05-28,数据错了一行,但 SQL 能跑。

乍一看 bug 很难发现:分段逻辑写对了,却把最后的聚合从 MAX 写成了 MIN,把“离 ConfirmationStarted 最近的一条”变成了“最早的一条”,结果在边界数据上悄悄偏了一行。

AI 给的有漏洞的 SQL 长这样:

代码语言:txt
复制
WITH t2 AS (
        SELECT CreatedAt, ID, NewStatus
            , 1 + SUM(CASE WHEN NewStatus='ConfirmationStarted' THEN 1 ELSE 0 END)
                OVER (PARTITION BY ID ORDER BY ID ASC, CreatedAt ASC ROWS UNBOUNDED PRECEDING) AS seg
        FROM mytable
    )
SELECT ID, MIN(CreatedAt) AS CreatedAt --这是几处错误之一,应为MAX,取最近的
FROM (
    SELECT CreatedAt, ID, NewStatus, seg
    FROM t2
    WHERE NewStatus='Closed' AND seg=1
) t_3
GROUP BY ID
ORDER BY ID

这就是 AI 直接产终态 SQL 最危险的地方:你能让 AI 重写一段话,却很难让它自己发现逻辑里那一行看不见的偏差。

我们让AI做了最不该做的事

AI 很擅长把口语需求拆成步骤,却不擅长为最终 SQL 的每一个边界条件都给出 100% 保证。它是概率模型,不是编译器。

公开评测显示,即使让最先进的大模型直接把自然语言翻译成可执行 SQL,在复杂查询上的执行准确率也常在六成左右徘徊,远未达到可直接签核的程度,平均三、四次就可能错一次。

旧范式是 "提示词→AI→不确定的终态 SQL",黑盒交付,只能让它整段重猜。

我们需要的新范式应该是 "提示词→AI→规范步骤→编译器→确定性 SQL",每一步可验证。

“跑得通”不算数,“敢签字”才算。

SQLazy,就是这个敢签字的底气,就是规范步骤的编译器,就是新范式的落地工具。

在SQLazy里,这件事只要4步

同样的 "最近一条 Closed",在 SQLazy 里是 4 步,关键是:每一步都能点开看中间结果。

第 1 步 "sort ID, CreatedAt asc" 先把时序排正。

第 2 步 "segment condition (NewStatus ="ConfirmationStarted") partition ID as seg" 按 "ConfirmationStarted" 分段,"partition ID" 保证每个 ID 独立。分段列的名字是 seg,其中 seg=1 就是目标区间,不用手写 "SUM(CASE WHEN ...) OVER"。

第 3 步 "filter (NewStatus ="Closed"and seg = 1)" 只留目标区间里的 Closed。

第 4 步 "summarize CreatedAt max as CreatedAt; group ID" 每 ID 取最大时间,就是最近一条。

分段对不对,点开 t2 看 "seg" 列就知道;哪步错了就改哪步——错在第 2 步就只改第 2 步,不用推倒重来。编译时选 MySQL 还是 Snowflake,永远同一输入同一输出,不会编造字段。

代码语言:txt
复制
WITH t2 AS (
        SELECT CreatedAt, ID, NewStatus
            , 1 + SUM(CASE
                WHEN (NewStatus = 'ConfirmationStarted') THEN 1
                ELSE 0
            END) OVER (PARTITION BY ID ORDER BY ID ASC, CreatedAt ASC ROWS UNBOUNDED PRECEDING) AS seg
        FROM mytable
    )
SELECT ID, MAX(CreatedAt) AS CreatedAt
FROM (
    SELECT CreatedAt, ID, NewStatus, seg
    FROM t2
    WHERE (NewStatus = 'Closed'
        AND seg = 1)
) t_3
GROUP BY ID
ORDER BY ID

这段 SQL 不是 AI 猜的,是编译器按固定规则把 4 步翻译出来的,肯定对,不用审。

当然,简单 CRUD 真没必要用 SQLazy,SQLazy 就是为那种 30 行以上的复杂逻辑准备的,比如带时序、分段、相对位置的逻辑。

把你最可疑的那段AI SQL贴进来

最典型的幻觉是什么?凭空编造不存在的字段或表、把筛选条件安到错的列上、把关联键或聚合口径搞错——SQL 照样能跑,结果早已跑偏,类似的场景人人都曾遇到。

别再陷入“重写提示词→重跑→碰运气”的循环了。把那段最不放心的业务逻辑丢给 SQLazy,拆成一步步可验的流程,并在评论区晒出你的幻觉案例。

AI给逻辑,编译器保落地——零幻觉

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 能跑,不等于可信
  • 我们让AI做了最不该做的事
  • 在SQLazy里,这件事只要4步
  • 把你最可疑的那段AI SQL贴进来
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档