# 代码审查报告 **文件:** `data\demo-sqlfluff\src\04_convention.sql` **语言:** sql **耗时:** 202.1s **分析工具:** sqlfluff --- 总计: 15 | 错误: 14 | 警告: 1 | 建议: 0 静态分析 · 13 个问题 - 🔴 `sqlfluff:CV01` L7 L7:`!=` 与 `<>` 混用,“不等于”运算符应保持一致。 建议: 将第 7 行中的 `<>` 改为 `!=`,使同一语句统一使用一种“不等于”写法。 - 🔴 `sqlfluff:CV02` L11 L11:应使用 `COALESCE` 而不是 `IFNULL`。 建议: 将 `IFNULL(amount, 0)` 替换为 `COALESCE(amount, 0)`,以保持 SQL 标准兼容。 - 🔴 `sqlfluff:CV03` L18 L18:SELECT 列表中不允许出现尾随逗号。 建议: 删除 `name` 后面的逗号,使其直接换行到 `FROM`。 - 🔴 `sqlfluff:CV04` L24 L24:统计行数应使用统一的 `COUNT(*)` 语法。 建议: 将 `COUNT(1)` 改为 `COUNT(*)`。 - 🔴 `sqlfluff:CV05` L34 L34:与 NULL 比较应使用 `IS NULL` / `IS NOT NULL`,不能使用 `= NULL`。 建议: 将 `end_date = NULL` 改为 `end_date IS NULL`;若想查非空则改为 `end_date IS NOT NULL`。 - 🔴 `sqlfluff:CV08` L41 L41:应使用 `LEFT JOIN` 而不是 `RIGHT JOIN`。 建议: 将 `RIGHT JOIN` 改写为 `LEFT JOIN`;若需保持原语义,应调换表顺序并改写为 `other_table AS b LEFT JOIN my_table AS a ON a.id = b.ref_id`。 - 🔴 `sqlfluff:ST11` L42 L42:连接表 `other_table AS b` 在查询的其他位置未被引用。 建议: 如果 `other_table AS b` 只是用于过滤,建议改为 `WHERE EXISTS (SELECT 1 FROM other_table AS b WHERE b.ref_id = a.id)`;若确实需要 b 的数据,应把 b 的字段加入 SELECT,否则移除该 JOIN。 - 🔴 `sqlfluff:LT02` L42 L42:`ON` 前应有换行,且 `ON` 不应缩进。 建议: 在 `ON` 前插入换行,并让 `ON` 从行首开始,不要缩进。 - 🔴 `sqlfluff:AM05` L50 L50:JOIN 子句应使用完整的连接条件(ON),不能只依赖 WHERE。 建议: 改为 `JOIN other_table AS b ON a.id = b.ref_id`,并从 WHERE 中移除该条件,避免产生隐式交叉连接。 - 🔴 `sqlfluff:CV12` L50 L50:连接条件应使用 `JOIN ... ON ...`,不要使用 `WHERE`。 建议: 在 `JOIN` 后直接写 `ON a.id = b.ref_id`。 - 🔴 `sqlfluff:CV12` L52 L52:连接条件已写在 WHERE 中,应移入 JOIN 的 ON 子句。 建议: 删除 WHERE,并把 `a.id = b.ref_id` 作为 JOIN 的 ON 条件。 - 🔴 `sqlfluff:CV06` L61 L61:语句必须以分号结束;分号应紧跟在语句最后,而不是单独成行。 建议: 删除第 62 行单独的分号,并将第 61 行末尾补上分号:`status_code = 'active';`。 - 🔴 `sqlfluff:LT12` L63 L63:文件必须以一个单独的尾随换行符结尾。 建议: 在文件末尾添加一个换行符,并确保不要出现多个空行。 AI 审查 · 2 条建议 - 🔴 [AI] [bug] `boolean-or-instead-of-and` L7 **OR 条件导致状态过滤几乎恒真** `status_code != 'active' OR status_code != 'pending'` 对所有非 NULL 的 status_code 都为真:当 status_code='active' 时第二个条件为真,当 status_code='pending' 时第一个条件为真。因此实际会返回除 NULL 外的所有行,与预期的“排除 active/pending”很可能相反。 建议: 改为 `status_code != 'active' AND status_code != 'pending'` 或 `status_code NOT IN ('active', 'pending')`。若需把 NULL 也包含,请使用 `COALESCE(status_code, '') NOT IN ('active', 'pending')`。 - 🟡 [AI] [design] `right-join-unused-left-columns` L41 **RIGHT JOIN 仅选择左表字段会产生 NULL 并可能产生重复行** `my_table AS a RIGHT JOIN other_table AS b` 会保留所有 other_table 行;未被匹配时 a.id 为 NULL,且若 other_table 中 ref_id 重复会导致 a.id 重复。当前 SELECT 只输出 a.id,未输出 b 的任何列,这个 RIGHT JOIN 的语义很可能不是期望的。 建议: 若目标是保留 my_table 并以 other_table 过滤/补列,应改为 `my_table AS a LEFT JOIN other_table AS b`;若目标确实是保留 other_table 全量行,应把 other_table 放在 FROM 左侧并 `LEFT JOIN my_table`,同时检查是否需要输出 b 的列。