MySQL "ERROR 1064: You have an error in your SQL syntax": how to read it and fix it
Fix MySQL ERROR 1064: read the "near" text, then check reserved words like rank and groups, quotes, commas, old GRANT syntax and queries written for another database.
by OhSudo ·
Checked on real software: MySQL 8.4 · November 2026How we check
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM players' at line 1MySQL couldn’t parse your statement. The message looks vague, but the useful part is the end: near '…' starts at the point where the parser gave up. The mistake is usually right there, or just before it.
This came from SELECT rank FROM players. FROM is fine: the mistake is rank, the word just before it, because since MySQL 8.0 it’s a reserved word.
TL;DR
Read what comes after near, then look at the word just before it:
near ''at the end: the statement stops too early, usually a missing)or'.- The word before it is a column or table name: probably a reserved word. Quote it with backticks:
`rank`. - A word right after a list: a missing or extra comma.
- Copied from elsewhere: syntax from another database, or from an older MySQL.
1. Reserved words used as names
MySQL 8.0 added new reserved words, so a query that worked for years can break after an upgrade. Common ones: rank, groups, row, rows, system, function, lead, lag, window, over, recursive. Older ones are order, group, key, index, desc, from, to.
Backticks work in every statement. To avoid the problem altogether, choose names that aren’t reserved words (player_rank), and have your ORM quote identifiers.
2. Quotes
MySQL has three kinds, and they aren’t interchangeable:
| Quote | Means |
|---|---|
'text' |
A string |
`name` |
A table or column name |
"text" |
A string by default; a name with ANSI_QUOTES mode on |
Two classic mistakes, an apostrophe inside a string and “smart” quotes pasted from a document:
INSERT INTO notes (body) VALUES ('it's broken'); -- ERROR 1064, the string ends at it'INSERT INTO notes (body) VALUES ('it''s fine'); -- works‘text’ with curly quotes also gives ERROR 1064: retype them. In application code, never build SQL by joining strings: use parameters. It avoids this error, and SQL injection too.
3. Commas and brackets
SELECT id, name, FROM users; -- comma before FROMSELECT id name email FROM users; -- missing comma: "name" is read as an aliasCREATE TABLE t (id INT, name TEXT,); -- comma before )The second one is a good example of the rule: id name is valid (an alias), so MySQL only complains at email, one word later than the real mistake.
The empty near '' means the statement ended while MySQL still expected something:
ERROR 1064 (42000): … near '' at line 1Look for a missing ) or a closing quote.
4. Syntax from another database
Each database has its own dialect. These are the usual travellers:
| Wrong in MySQL | From | In MySQL |
|---|---|---|
SELECT TOP 5 * FROM t |
SQL Server | SELECT * FROM t LIMIT 5 |
WHERE name ILIKE 'a%' |
PostgreSQL | WHERE name LIKE 'a%' (case-insensitive by default collation) |
SELECT price::int |
PostgreSQL | SELECT CAST(price AS SIGNED) |
INSERT … RETURNING id |
PostgreSQL | SELECT LAST_INSERT_ID() (MariaDB does support RETURNING) |
[name] |
SQL Server | `name` |
The SQL Dialect Reference shows the same statement in MySQL, MariaDB, PostgreSQL, SQL Server, Oracle and SQLite, side by side.
5. Syntax from an older MySQL
Tutorials and scripts from years ago often use syntax that has since been removed. The most common by far is creating a user inside GRANT, which MySQL 8.0 no longer accepts:
-- ERROR 1064 on MySQL 8.0 and laterGRANT ALL PRIVILEGES ON shop.* TO 'app'@'%' IDENTIFIED BY 'secret';Do it in two steps:
Also from old dumps: TYPE=InnoDB instead of ENGINE=InnoDB. MariaDB still accepts some of what MySQL has removed, including GRANT … IDENTIFIED BY, so a script can work on one and fail on the other.
6. Procedures and triggers need DELIMITER
In the mysql client, each ; ends the statement, including the ones inside a procedure’s body, so MySQL sees half a procedure:
DELIMITER is a command of the client, not SQL. Don’t send it from application code.
Shell, we have a problem!
Similar, but different: ERROR 1054 (42S22): Unknown column and ERROR 1146 (42S02): Table doesn't exist mean the syntax is right, and the name isn’t. ERROR 1045: Access denied is about your login: see MySQL ERROR 1045. A refused emoji is a different error: see Incorrect string value. To practice writing queries, try the SQL Exercises, which run on PostgreSQL and SQLite. ERROR 1452 means the statement is valid, and a foreign key rejects its data.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.