Claude Haiku 5 5 在「PostgreSQL JSONB字段解析与聚合统计」的评测结果

这是该 AI 模型在此测试用例上的详细评测结果。

基本信息

  • 模型名称:Claude Haiku 5 5
  • 用例名称:PostgreSQL JSONB字段解析与聚合统计
  • 测试类型:文本生成
  • 评测维度:SQL 数据库能力

系统提示词(System Prompt)

这是给 AI 模型的背景设定和角色指令:

你是一名资深的 PostgreSQL 数据库工程师。 回答要求: 1. 给出完整、可直接执行的 SQL 语句 2. 对关键语法和操作符进行简要注释 3. 说明 JSONB 操作符的含义 4. 最终 SQL 要格式整洁、易于阅读

用户提示词(User Prompt)

这是用户给 AI 模型的具体任务要求:

有一张 PostgreSQL 表,结构如下: ```sql CREATE TABLE app_logs ( id SERIAL PRIMARY KEY, created_at TIMESTAMPTZ NOT NULL, payload JSONB NOT NULL ); ``` 其中 `payload` 字段的示例数据如下: ```json { "level": "error", "error_code": "E1001", "message": "Connection timeout" } ``` 请写一条 SQL 查询,从 `payload` 字段中提取 `error_code` 的值,并只返回 `level` 为 `"error"` 的记录。 要求返回列:`id`、`created_at`、`error_code`(从 JSONB 中提取的文本值)。

任务要求

AI 模型需要满足以下要求:

  1. 正确使用 JSONB 操作符(如 `->>` 或 `->>`)提取 `error_code` 字段为文本类型
  2. 正确使用 WHERE 条件过滤 `payload->>'level' = 'error'` 的记录
  3. 返回列包含 `id`、`created_at` 以及提取后的 `error_code`
  4. SQL 语法正确,可在标准 PostgreSQL 环境下执行
  5. 对 JSONB 操作符的用途有简要说明

评测结果

综合得分

该模型在此用例的得分为:98.1 分(满分 100 分),已通过

基础难度评测结果

  • 得分:98.1 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

这是一个典型的 JSONB 查询场景。下面给出 SQL,并说明关键操作符。 ```sql SELECT id, -- 主键 created_at, -- 创建时间 payload ->> 'error_code' AS error_code -- 提取 error_code 的文本值 FROM app_logs WHERE payload ->> 'level' = 'error' -- 过滤 level 为 'error' 的记录 ORDER BY created_at; -- 可选:按时间排序,便于阅读 ``` **JSONB 操作符说明** | 操作符 | 返回类型 | 含义 | 示例 | |--------|----------|------|------| | `->` | `jsonb` | 按键获取字段,返回 JSON 类型值(保留 JSON 格式,如字符串带引号) | `payload -> 'level'` 得到 `"error"` | | `->>` | `text` | 按键获取字段,返回纯文本值(去掉外层引号) | `payload ->> 'level'` 得到 `error` | | `#>` | `jsonb` | 按路径(文本数组)获取嵌套字段 | `payload #> '{a,b}'` 取 `payload->'a'->'b'` | | `#>>` | `text` | 按路径获取嵌套字段并返回文本 | `payload #>> '{a,b}'` | **要点说明** - 使用 `->>` 而不是 `->`,是因为题目要求返回的是文本值;若用 `->`,比较和返回结果都会带 JSON 格式(如 `"error"` 带引号),与字符串 `'error'` 比较会失败。 - `WHERE payload ->> 'level' = 'error'` 直接使用文本比较,语义清晰。若数据量大,可以考虑为该表达式建立索引以加速查询: ```sql CREATE INDEX idx_app_logs_level ON app_logs ((payload ->> 'level')); ``` - 若希望过滤更高效并利用 GIN 索引,可改写为包含查询(使用 `@>`): ```sql SELECT id, created_at, payload ->> 'error_code' AS error_code FROM app_logs WHERE payload @> '{"level": "error"}' -- 包含操作符:payload 是否包含该键值对 ORDER BY created_at; -- 配合 GIN 索引使用 CREATE INDEX idx_app_logs_payload ON app_logs USING GIN (payload); ``` 两种写法结果相同:第一种适合配合表达式索引,第二种适合配合整体 GIN 索引。

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【CLAUDE】候选输出在所有维度上均达到高水准,核心 SQL 完全正确,操作符说明详尽且有实用深度,代码格式整洁规范。额外提供的 `@>` 写法与 GIN 索引建议体现了工程实践意识,超出题目基本要求,是一份高质量的回答。 【GEMINI】候选输出完美满足题目所有要求。SQL 语句准确无误,行内注释到位,操作符说明详实丰富,还额外拓展了 GIN 索引与包含操作符的使用技巧,表现优秀。 【KIMI】该候选输出表现优秀,完全满足基础难度的功能要求,SQL 正确无误,解释详尽清晰,代码格式规范。额外提供的性能优化方案和替代写法体现了资深工程师的专业水准,虽对基础题而言略有超额,但不影响整体质量。

进阶难度评测结果

  • 得分:95.4 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

## 查询 SQL ```sql SELECT -- 1. 时间截断:将 created_at 截断到整点(秒、分归零) -- date_trunc('hour', ts) 返回 timestamptz 类型的整点时间 date_trunc('hour', created_at) AS hour, -- 2. JSONB 提取:->> 取出 error_code 的文本值(返回 text 类型) -- 若需要 JSON 类型则使用 ->,这里分组和展示用文本更合适 COALESCE(payload ->> 'error_code', 'UNKNOWN') AS error_code, -- 3. 聚合统计:统计每个(小时, 错误码)组合的记录数 COUNT(*) AS error_count FROM app_logs -- 4. 过滤条件:仅保留 level 为 "error" 的记录 -- ->> 提取 level 字段为 text,再与字符串 'error' 比较 WHERE payload ->> 'level' = 'error' -- 5. 分组:按整点时间和错误码分组 GROUP BY date_trunc('hour', created_at), COALESCE(payload ->> 'error_code', 'UNKNOWN') -- 6. 排序:小时升序,同一小时内出现次数降序 ORDER BY hour ASC, error_count DESC; ``` ## 关键函数与操作符说明 | 名称 | 类型 | 作用 | |---|---|---| | `->>` | JSONB 操作符 | 按键提取值,并以 `text` 返回。`payload ->> 'level'` 得到 `'error'` 字符串 | | `->` | JSONB 操作符 | 按键提取值,以 `jsonb` 返回,保留 JSON 类型,适合继续嵌套访问 | | `date_trunc(field, ts)` | 时间函数 | 将时间戳截断到指定精度,`'hour'` 会把分、秒、微秒置零 | | `COALESCE(a, b)` | 条件函数 | 返回第一个非 NULL 参数。这里避免 `error_code` 缺失时出现 NULL 分组 | | `COUNT(*)` | 聚合函数 | 统计每组的行数,返回 `bigint` | ## 补充说明 1. **时区**:`created_at` 是 `TIMESTAMPTZ`,`date_trunc('hour', ...)` 按当前会话的 `TimeZone` 截断。如果需要按特定时区(如北京时间)的整点统计,可改为: ```sql date_trunc('hour', created_at AT TIME ZONE 'Asia/Shanghai') ``` 注意此时结果为 `timestamp`(无时区)。 2. **性能建议**:如果数据量较大,可以为过滤条件建立表达式索引,加速 `level` 过滤: ```sql CREATE INDEX idx_app_logs_level ON app_logs ((payload ->> 'level')); ``` 若主要用 `payload @> '{"level":"error"}'` 这种包含查询写法,则可使用 GIN 索引: ```sql CREATE INDEX idx_app_logs_payload ON app_logs USING GIN (payload); ``` 两者的写法需与查询保持一致,索引才会被使用。 3. **不带 `COALESCE` 的情况**:若确定 `error_code` 一定存在,可直接使用 `payload ->> 'error_code'`,结果相同;若缺失,则该组会以 `NULL` 形式出现在结果中。

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【CLAUDE】候选答案质量优秀,完整覆盖了所有功能要求,SQL 逻辑正确、格式规范、注释详尽。额外引入 `COALESCE` 处理 NULL 值体现了工程实践意识,时区补充说明和性能索引建议均超出题目要求,展示了较强的 PostgreSQL 工程经验。整体表现明显优于及格线,属于高质量回答。 【GEMINI】候选输出表现优异,完全符合资深 PostgreSQL 工程师的设定。不仅精准无误地完成了所有查询与聚合需求,还在代码健壮性(COALESCE 容错)、性能优化建议(B-Tree 与 GIN 索引)及时区转换方面给出了专业见解,是一份高质量的回答。 【KIMI】该候选输出是一份高质量的PostgreSQL JSONB查询解答,核心功能完全满足题目要求,解释详尽专业,代码可直接执行。COALESCE处理NULL值的做法在实际生产环境中是良好的防御性编程实践,但从严格符合题目要求的角度,属于额外增强而非题目必需。

困难难度评测结果

  • 得分:86.7 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

## 完整 SQL ```sql WITH filtered_logs AS ( -- 1. 筛选满足条件的原始记录,并计算小时粒度 SELECT date_trunc('hour', created_at) AS hour, -- 截断到整点小时(按会话时区) payload -> 'error' ->> 'code' AS error_code -- 取嵌套路径的文本值 FROM app_logs WHERE payload ->> 'level' = 'error' -- ->> 返回 text,适合与字符串比较 AND payload -> 'error' ->> 'code' IS NOT NULL -- 排除 error 或 code 缺失的记录 AND jsonb_typeof(payload -> 'tags') = 'array' -- 确保 tags 是数组,避免 ? 对标量误判 AND payload -> 'tags' ? 'critical' -- ? 判断数组顶层是否含字符串元素 "critical" ), hourly_counts AS ( -- 2. 按小时 + error_code 聚合(保留全部 error_code,不做 Top3 截断) SELECT hour, error_code, COUNT(*) AS error_count -- COUNT(*) 返回 bigint FROM filtered_logs GROUP BY hour, error_code ), ranked_and_diffed AS ( -- 3. 在每个小时内排名,并在同一 error_code 的时间序列上计算环比 SELECT hour, error_code, error_count, -- ROW_NUMBER:同小时内按 error_count 降序;并列时按 error_code 升序保证结果确定 ROW_NUMBER() OVER ( PARTITION BY hour ORDER BY error_count DESC, error_code ASC ) AS rank_in_hour, -- LAG:取同一 error_code 上一条记录(按 hour 排序)的 error_count -- 仅当上一条记录恰好是「上一个整点小时」时才计算差值,否则为 NULL CASE WHEN LAG(hour) OVER w = hour - INTERVAL '1 hour' THEN error_count - LAG(error_count) OVER w END AS count_diff FROM hourly_counts WINDOW w AS (PARTITION BY error_code ORDER BY hour) -- 命名窗口,复用于 LAG ) -- 4. 最终输出:仅保留每小时排名前 3 的记录 SELECT hour, error_code, error_count, rank_in_hour, count_diff FROM ranked_and_diffed WHERE rank_in_hour 'error' ->> 'code'`:`->` 返回 `jsonb`,保留层级结构;`->>` 返回 `text`,便于比较和分组。 - `jsonb_typeof(...) = 'array'`:校验 `tags` 的类型。若 `tags` 是标量字符串,`?` 也会匹配,加上此判断可避免误匹配。 - `?`:判断 jsonb 数组顶层是否包含字符串元素。另一种等价写法是 `payload -> 'tags' @> '"critical"'::jsonb`。 - `date_trunc('hour', created_at)`:返回 `timestamptz` 的整点时间。截断结果依赖会话时区(`TimeZone` 参数)。 - `ROW_NUMBER() OVER (PARTITION BY hour ORDER BY ...)`:在每个小时分区内编号,且编号严格唯一。 - `LAG(...) OVER w`:取同一 `error_code` 时间序列中的上一条记录。 - `WINDOW w AS (...)`:定义命名窗口,避免重复书写相同的 `OVER` 子句。 ## 设计思路 ### 1. 为什么环比必须基于全量数据计算 若先筛出 Top 3 再算 `LAG`,会出现错误:某 error_code 在上一小时排名第 4,它不在最终结果中,于是当前小时的 `count_diff` 被错误地算成 NULL。因此 `LAG` 必须在...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【CLAUDE】候选答案整体质量较高,在设计思路(环比必须基于全量数据、相邻小时校验)和边界处理方面甚至超出参考答案的深度。主要不足在于:tags 过滤使用 `?` 操作符而非更标准的 `@>` 包含操作符,以及排名函数选用 `ROW_NUMBER` 而非 `RANK`(两者在并列场景下行为不同,候选答案有说明但默认选择与题目「排名前 3」的通常语义存在偏差)。代码规范和解释说明均属上乘,是一份有实际工程价值的答案。 【GEMINI】这是一份质量极高、专业度极强的解答。模型不仅完美实现了全部功能要求,而且在环比计算的严谨性(严格判断相邻小时)和统计逻辑顺序(先全量 LAG 后截断 Top 3)上展现了资深工程师级别的业务洞察与技术深度,边界情况讨论详尽全面。 【KIMI】候选输出整体完成了题目要求的核心功能,CTE结构清晰,注释较为完整。但存在两个关键偏离:一是使用 `ROW_NUMBER()` 替代了题目明确要求的 `RANK()`,导致排名语义变化;二是 `count_diff` 的'相邻小时'判断逻辑过度复杂且不符合题目本意,题目仅要求基于排序后的上一行计算差值即可。此外,候选输出在'环比基于全量计算'的设计思路上有一定合理性,但实际实现方式增加了不必要的复杂度。建议修正为使用 `RANK()` 并简化 `LAG` 计算逻辑,以严格符合题目要求。

相关链接

您可以通过以下链接查看更多相关内容:

加载中...