最近 PawSQL 的 SQL 解析器撞上了一个诡异的异常情况。下面这条 SQL在 Oracle 客户端里跑得好好的PawSQL 却在解析时直接报了个数组越界SELECT category, count(1) FROM products GROUP BY CATEGORY UNION ALL SELECT 23 as category, 100 FROM product_23 GROUP BY 23解析器试图把GROUP BY 23映射到 SELECT 列表的第 23 列——但 SELECT 列表总共才 2 列。越界了。这引出一个更深层的问题GROUP BY里的整型常量到底是「列位置」还是「纯数值」答案取决于你在用哪个数据库——以及 Oracle 的哪个版本。Oracle 23c 之前整型常量就是常量在 Oracle 23c 之前GROUP BY 23里的23就是一个普通常量值。实际效果所有行被分到同一组。因为23是个常量GROUP BY 常量等价于不分组。这在大多数场景下不是用户的本意——你很可能想表达的是「按第 23 个选择列分组」。Oracle 23c 之后新增了一个开关Oracle 23c 引入了一个关键参数GROUP_BY_POSITION_ENABLED。参数值行为FALSE默认保持旧行为GROUP BY 23→ 按常量分组TRUEGROUP BY中的正整数视为位置指示器指代 SELECT 列表的第 N 列⚡ 这意味着同样的 SQL、同一个数据库版本、不同的参数设置执行结果可能完全不同。其他数据库怎么做这一点上MySQL 和 PostgreSQL 走了另一条路——它们默认就把 GROUP BY 里的整数当作位置指示器。也就是GROUP BY 1等价于按 SELECT 的第一列分组和 Oracle默认行为截然相反。跨数据库迁移时这个差异是隐藏的定时炸弹。 三条建议永远不要在 GROUP BY 里用常量。用明确的列名或别名这是跨平台行为一致的唯一保证。如果非要用位置指示器GROUP BY 1, 2先确认目标数据库的版本和默认行为。Oracle 23c 用户记得检查GROUP_BY_POSITION_ENABLED——改了这个参数所有用到位置分组的 SQL 行为都会变。 PawSQL 的应对措施PawSQL在解决了这个SQL解析异常之后还内置了一条审核规则——避免GROUP BY选择列的序号——专门在 SQL 进入生产环境之前自动识别GROUP BY中使用整型字面量无论是作为常量还是位置序号的写法并给出明确警告。整型常量可能导致分组行为在 Oracle/ MySQL/ PostgreSQL 之间完全不同位置序号虽然多数数据库支持却会显著降低代码的可读性和跨平台兼容性。