AI 入门与核查AI 应用

AI写的“本月SQL”多算一条?用5行数据检查月份边界与NULL

“帮我统计十月的记录”听起来很明确,生成的SQL却可能把11月1日零点也算进去。正常日期样本往往发现不了这个问题:10月中旬的记录无论怎样写都会通过。要检查AI有没有理解月份,需要把样本放在边界上,并先规定“十月”按哪个时区计算。

墙上的2020年10月黑白日历资料照片,用于说明月份边界
配图:Waldemar Brandt · Unsplash License

先明确任务与结果

本例明确只统计UTC的2026年10月,时间列为PostgreSQL的带时区时间戳。采用“大于等于10月1日零点、严格小于11月1日零点”的区间,再逐行核对预期ID。以下是自编参考案例,不是某个模型的实测输出,也没有声称在读者数据库中运行。

先写出任务合同,别让AI自行补时区

这次合同只有三项:字段occurred_at使用带时区时间戳;月份按UTC;缺失时间单独报告,不塞进任何月份。如果实际业务按纽约、伦敦或上海的本地月历结算,必须重新确定边界,不能直接拿本例UTC值去替换。

PostgreSQL时间类型文档区分带时区与不带时区时间戳。不要只看字符串里出现了+00就假定类型正确。数据导入阶段存在模糊时间时,先按AI日期规范化核查保留原值与偏移证据,再验证筛选条件。

五行数据把隐藏的假设变成可见差异

下面的数据全部为编辑自编,用来制造必要的边界情况;不是用户数据。先在不看SQL的情况下写出预期结果,之后才能判断查询是否符合任务,而不是用查询结果倒推答案。

UTC十月的人工参考答案
IDoccurred_at本例预期
A2026-09-30 23:59:59+00排除:尚未进入十月
B2026-10-01 00:00:00+00包含:恰好在起点
C2026-10-31 23:59:59.999+00包含:仍在十月
D2026-11-01 00:00:00+00排除:已进入十一月
ENULL单独报告:时间缺失

使用两个可解释的边界

PostgreSQL参考查询

SELECT id
FROM events
WHERE occurred_at >= TIMESTAMPTZ '2026-10-01 00:00:00+00'
  AND occurred_at <  TIMESTAMPTZ '2026-11-01 00:00:00+00'
ORDER BY id;
假设events已经包含上述测试行且occurred_at为timestamptz。预期只返回B、C,共两条;应先在隔离测试数据上检查,不能直接改写生产查询。

这段查询只解决本例的月份过滤,不同时验证原始数据完整性、去重、连接关系或业务指标定义。

两种看似合理的写法会失败

PostgreSQL比较运算说明规定BETWEEN包含两个端点;普通NULL比较的结果也不能当成真实时间。若把上界写成11月1日,再使用BETWEEN,D会多进入结果。若把上界写成10月31日零点,则会漏掉C这类月末当日稍后的记录。

同一份五行数据的三个结果

失败候选的参考结果

起点与11月1日之间使用BETWEEN:B、C、D,共三条。上界设为10月31日零点:本例只剩B。

符合合同的参考结果

使用起点包含、下月起点排除的区间:B、C,共两条;E继续留在缺失时间记录中。

先比较ID集合,再比较数量。数量偶然相同也可能包含错误ID;不要把三种不同写法只用一条月中记录测试。

把验证要求写进给AI的提示词

可复制的SQL核查提示词

请审查月份筛选,不执行任何数据库操作。
数据库:PostgreSQL。列occurred_at类型timestamptz。业务月份:UTC的2026年10月。
要求起点包含、下月起点排除。NULL单独报告,不补成零点。
先逐行判断A至E,再列出预期ID和数量;指出BETWEEN端点及类型假设。
只给可在隔离测试数据上验证的查询,不假称已经运行或通过。
在此粘贴本文五行样本与待审查SQL。
提示词是编辑示例。AI即使给出预期的两个ID,也不能替代对真实列类型和业务时区的核对。

验收不止是“返回两条”

先比较B、C这两个具体ID,再查看A、D为什么被排除,最后单独统计E。若只看总数,某条错误记录替换一条正确记录仍可能得到二。和AI表格公式的样本验算一样,参考答案必须独立于被检查的生成结果。

不要靠把上界写成23:59:59来“覆盖整天”:不同数据可能有小数秒精度。采用下一个月份起点作为排除边界更容易说明,但依然必须先定义时区。真实数据的重复ID、夏令时或业务截止规则应另设样本,本篇并未一并验证。

这个案例的通过条件

  • 已写明数据库、列类型和业务月份时区。
  • B与C包含,A与D排除,E保持缺失状态。
  • 检查实际ID集合,未只核对行数。
  • 边界案例在隔离环境验证后,再由有权限的人审查真实查询。

常见问题

BETWEEN不能用于任何日期查询吗?

不是。它包含两端,如果任务本来要求两端都包含就可能适用。月度分区通常更容易用起点包含、下月起点排除来表达,关键是匹配任务。

为什么不把结束时间写成23:59:59?

因为真实时间可能带有小数秒。需要完整月份时,以次月起点作为排除边界可以避免猜测最后一秒的精度。

纽约业务月份也照抄UTC就行吗?

不行。先依据实际业务时区计算该月起止时刻,再核对列类型与转换方式;本例只定义了UTC月份。

参考资料与延伸阅读

继续阅读