如何生成含科西嘉2A、2B的法国所有省编号SQL语句?
修正生成法国省份编号的递归SQL语句
问题背景
需要生成法国所有省份的编号:范围为1至97,其中科西嘉地区的编号需用2A和2B替代原有的20。
原递归SQL用于生成1至99的数值编号:
WITH RECURSIVE dep as ( SELECT 1 as id UNION ALL SELECT id + 1 FROM dep WHERE id < 99 )
尝试添加2A、2B时执行报错:#1292 - Truncated incorrect DOUBLE value: '2B',错误SQL如下:
WITH RECURSIVE dep as ( SELECT 1 as id UNION ALL SELECT id + 1 FROM dep WHERE id < 99 UNION ALL SELECT '2A' UNION ALL SELECT '2B' )
期望输出的编号列表顺序为:1-19、2A、2B、21-97。
错误原因
递归CTE中初始的id列是数值类型,后续UNION ALL字符串类型的2A、2B时,MySQL会自动尝试将字符串转换为数值,导致类型不匹配,触发截断错误。
修正后的SQL
WITH RECURSIVE dep AS ( -- 将初始值转为字符串,统一列类型 SELECT CAST(1 AS CHAR) AS id UNION ALL -- 递增后保持字符串类型 SELECT CAST(id + 1 AS CHAR) FROM dep WHERE id < 97 ) -- 排除20,加入科西嘉特殊编号,再按规则排序 SELECT id FROM dep WHERE id != '20' UNION ALL SELECT '2A' UNION ALL SELECT '2B' ORDER BY -- 让2A、2B排在20的位置(19之后、21之前) CASE WHEN id IN ('2A', '2B') THEN 20 ELSE CAST(id AS UNSIGNED) END, -- 保证2A在2B之前 id;
说明
- 统一列类型:将所有
id转换为字符串类型,避免类型转换冲突; - 范围控制:递归生成1至97的编号(匹配需求范围,无需生成到99);
- 过滤与补充:移除原编号
20,添加2A和2B; - 排序规则:通过
CASE语句将2A、2B映射到20的排序位置,确保它们处于19和21之间,同时按字符串顺序保证2A在2B之前。
内容的提问来源于stack exchange,提问作者Elikill58
相关产品推荐
相关产品推荐

