必须用反引号包裹mysql保留字列名如order、group、limit,否则报error 1064;反引号非单引号或双引号,嵌套查询中也需包裹,表别名仅在本身为保留字时才需加,跨数据库迁移需注意引号规则差异。

MySQL里用反引号包裹保留字列名
MySQL把order、group、limit这类词当作保留字,直接写SELECT order FROM table会报错ERROR 1064。必须用反引号`把列名括起来,不是单引号,也不是双引号。
- 正确写法:
SELECT `order`, `group` FROM orders - 嵌套查询也得加:
SELECT id FROM (SELECT `order` FROM orders) AS t - 表别名不用加反引号,除非别名本身也是保留字,比如
SELECT `order` FROM orders AS `order` - 反引号对大小写不敏感,但建议保持原写法一致,避免混淆
SQL Server和PostgreSQL用方括号或双引号
SQL Server认方括号[ ],PostgreSQL认双引号" ",两者都不接受反引号。混用会直接报语法错误。
- SQL Server:
SELECT [order], [user] FROM dbo.orders - PostgreSQL:
SELECT "order", "user" FROM orders - 注意:PostgreSQL里双引号强制大小写敏感,
"Order"和"order"是两个不同列名 - 如果建表时没用双引号,列名默认转小写,查的时候用
"order"反而找不到——这是常见坑
ORM或查询构建器里怎么处理
用sequelize、SQLAlchemy或MyBatis时,框架通常自动加引号,但手动拼SQL或用原始查询就容易漏。
- Sequelize里字段名带保留字,用
sequelize.col('order')生成带反引号的表达式 - SQLAlchemy用
text("SELECT `order` FROM orders"),不能依赖query.order_by(Table.order)——它不会自动加引号 - MyBatis的
<select></select>里写SELECT `order`没问题,但动态SQL用${}拼接时,必须自己加反引号,#{}不生效
建表时就避开保留字最省事
加引号能解决问题,但每处都写`order`既啰嗦又易错,尤其跨数据库迁移时引号规则不统一。
- 优先改列名:
order_id、sort_order、item_order比单纯order更安全 - 查官方保留字列表(MySQL 8.0有370+个,SQL Server也有200+),建表前扫一遍
- 开发阶段用
SHOW WARNINGS或启用sql_mode=STRICT_TRANS_TABLES,让隐式问题提前暴露
引号只是补救手段,真正麻烦的是在视图、存储过程、索引定义里反复出现保留字——这时候改名成本远低于到处加引号。











