MySQL → Kingbase PG模式 高频SQL替换清单

MySQL → Kingbase PG模式 高频SQL替换清单

适用:DB_MODE=pg(原生PG兼容模式),金仓V8/V9通用; 说明:金仓PG模式遵循PG语法,不再兼容mysql专属函数、语法、特殊值,下面是项目里最常碰到的,直接替换。

一、判空函数

MySQL PG(金仓) 备注
IFNULL(col, val) COALESCE(col, val) 推荐,标准SQL,支持多参数 COALESCE(a,b,c)
NULLIF(a,b) NULLIF(a,b) 通用,不用改

示例

复制代码
-- mysql
select IFNULL(name,'未知') from t;
-- pg
select COALESCE(name,'未知') from t;

二、字符串聚合 GROUP_CONCAT

MySQL PG(金仓)
GROUP_CONCAT(name SEPARATOR ',') STRING_AGG(name, ',')

示例

复制代码
-- mysql
SELECT GROUP_CONCAT(username SEPARATOR ',') FROM sys_user GROUP BY dept_id;
-- pg
SELECT STRING_AGG(username, ',') FROM sys_user GROUP BY dept_id;

注意:PG 默认会自动去重吗?不会,和GROUP_CONCAT默认一样;需要去重:STRING_AGG(DISTINCT username, ',')

三、日期格式化 DATE_FORMAT

MySQL PG(金仓)
DATE_FORMAT(ctime,'%Y-%m-%d %H:%i:%s') TO_CHAR(ctime,'YYYY-MM-DD HH24:MI:SS')

格式对照重点

  • %Y → YYYY
  • %m → MM
  • %d → DD
  • %H → HH24(24小时制) / HH12(12小时)
  • %i → MI(分钟,不是MM!)
  • %s → SS(秒)

示例

复制代码
-- mysql
select DATE_FORMAT(create_time,'%Y-%m-%d') from t;
-- pg
select TO_CHAR(create_time,'YYYY-MM-DD') from t;

反向:字符串转日期 STR_TO_DATE('2026-10-21','%Y-%m-%d') → TO_DATE('2026-10-21','YYYY-MM-DD')

四、字符串截取 SUBSTRING_INDEX

MySQL:SUBSTRING_INDEX(str, delim, count),PG没有原生函数

复制代码
-- mysql 取第一个分隔符前面:SUBSTRING_INDEX('a-b-c','-',1) → a
-- mysql 取最后一个分隔符后面:SUBSTRING_INDEX('a-b-c','-',-1) → c

PG实现方案:

复制代码
-- 取第1段
split_part('a-b-c', '-', 1);
-- 取第3段
split_part('a-b-c', '-', 3);

短板:split_part 只能按序号取,不支持负数倒序 ;如果业务大量用到 -1 取最后一段,需要自定义函数。

五、字符串拼接

MySQL PG
CONCAT(a,b,c) CONCAT(a,b,c)
`a

重点警告: MySQL里 select 1 || 2 结果是 1(逻辑or); PG里 select 1 || 2 是字符串拼接 '12'。 如果老代码有 || 做判断,必须改成 OR。

六、分页 LIMIT

MySQL PG
LIMIT offset,size LIMIT size OFFSET offset
复制代码
-- mysql
select * from t limit 0,10;
-- pg
select * from t limit 10 offset 0;

七、布尔、0/1真假

MySQL:0=false,1=true PG:原生 boolean 类型 true / false; 如果用数字判断也支持,但推荐标准写法:

复制代码
-- mysql where del_flag = 0
-- pg 建议:where del_flag is false

八、特殊日期:0000-00-00

MySQL 允许 0000-00-00 作为特殊零日期; 👉 PG模式完全不支持,直接报错 改造方案:

  1. 数据库字段改成可NULL;
  2. 业务用 NULL 代替 0000-00-00;
  3. 代码里判断:日期为空展示"无"。

九、反引号 `````

MySQL标识符反引号 table PG模式:只能双引号 "table"

复制代码
-- mysql
select `id`,`user_name` from `yz_sys_user`;
-- pg
select "id","user_name" from "yz_sys_user";

MyBatis:要么把反引号统一改成双引号;要么去掉标识符引号(名字无关键字时)

十、自增主键

MySQL:AUTO_INCREMENT PG/金仓:SERIAL / BIGSERIAL 或者 identity(推荐V8新写法)

复制代码
-- mysql
id bigint primary key auto_increment
-- pg
id bigserial primary key
-- 或者标准identity(推荐)
id bigint primary key generated always as identity

十一、IF表达式

MySQL:IF(条件,val1,val2) PG:CASE WHEN

复制代码
-- mysql
select IF(sex=1,'男','女') from t;
-- pg
select CASE WHEN sex=1 THEN '男' ELSE '女' END from t;

金仓V8新版本也兼容 IF() 函数,但PG标准不推荐,为了稳妥统一用CASE。

十二、LIKE 大小写

MySQL 默认大小写不敏感; PG 默认大小写敏感!

复制代码
-- pg 不区分大小写like
select * from t where lower(name) like lower('%abc%');
-- 或者使用 ILIKE(PG专属)
select * from t where name ILIKE '%abc%';

十三、REPLACE、TRIM、LENGTH、SUBSTRING

✅ 这些函数基本通用: REPLACE()、TRIM()、LENGTH()、SUBSTRING() 行为基本一致,改动很小。

十四、MyBatis层面额外注意点

  1. 方言配置:不要用 MySQLDialect,切换为 PostgreSQLDialect
  2. 分页插件(PageHelper):方言改成 postgresql
  3. 主键回填:mysql useGeneratedKeys 写法,PG略有区别,需要指定 keyProperty + 序列

十五、快速自查清单(切换PG模式前跑一遍)

  • 全文检索代码有没有 IFNULL、DATE_FORMAT、GROUP_CONCAT、SUBSTRING_INDEX
  • 有没有 0000-00-00 日期
  • SQL有没有大量反引号 `````
  • 有没有 LIMIT m,n 分页写法
  • 有没有 || 逻辑判断
  • MyBatis方言、分页插件配置

相关推荐
数据库急诊室_阿哲3 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋4 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子4 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
Joy T5 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
杨凯凡6 小时前
MySQL 死锁怎么排查?InnoDB 锁等待与 Spring Boot 整事务重试实战
数据库·spring boot·mysql
Aloudata6 小时前
Claude 做数据分析的这两年:一份复盘与发展线索
大数据·数据库·人工智能·数据挖掘·数据分析·dataagent
Decay__6 小时前
01_SQLServer 体系架构全解 —— 实例进程、关系引擎、SQLOS 与事务日志深入
运维·数据库·sql·mysql·架构
zhanghaha13146 小时前
C# 系列教程_12 字符串 string 保姆级系统教程(面向新手,大量示例 + 原理讲解)
开发语言·数据库·c#
韩曙亮6 小时前
【错误记录】安卓 adb 调试 5037 端口占用排查 ( adb 的三层结构 | 找出本机占用 5037 的进程 )
android·数据库·adb·安卓·错误记录
瑞雪兆丰年兮6 小时前
JavaWeb-day07-MySQL(DQL&多表设计)
java·开发语言·数据库·sql·mysql·javaweb·web