3 Ways to Find a Substring's Position in MySQL
Compare MySQL LOCATE(), INSTR(), and POSITION() to find a substring’s 1-based position, including argument order and start-position behavior.
On this page
MySQL has three equivalent spellings for finding a substring’s position: LOCATE(), INSTR(), and POSITION(). They return a 1-based position, 0 when no match is found, and NULL if an argument is NULL. The main difference is argument order and whether you can specify a starting position. See the MySQL string function reference.
| Form | Syntax | Use it when |
|---|---|---|
LOCATE() |
LOCATE(substr, str[, pos]) |
You want an optional starting position |
INSTR() |
INSTR(str, substr) |
You prefer the string-first argument order |
POSITION() |
POSITION(substr IN str) |
You want the SQL-standard spelling |
Compare the three forms
Each form below finds the first bar in foobarbar, at position 4:
SELECT
LOCATE('bar', 'foobarbar') AS locate_result,
INSTR('foobarbar', 'bar') AS instr_result,
POSITION('bar' IN 'foobarbar') AS position_result;
locate_result instr_result position_result
------------- ------------ ---------------
4 4 4INSTR(str, substr) reverses the two arguments used by LOCATE(substr, str). POSITION(substr IN str) is equivalent to the two-argument LOCATE() form. Read the SQLiz references for LOCATE(), INSTR(), and POSITION().
Start searching later in the string
Only LOCATE() accepts a starting position. The result remains an absolute position in the original string:
SELECT LOCATE('bar', 'foobarbar', 5) AS next_match;
next_match
----------
7The search begins at position 5, skips the occurrence that starts at position 4, and returns the next occurrence at position 7.
Not found, NULL, and case behavior
All three return 0 when the substring is absent. LOCATE() and INSTR() return NULL if any argument is NULL; POSITION() does too because it is equivalent to LOCATE() with two arguments.
For nonbinary strings, matching follows MySQL’s collation. A case-insensitive collation can match Bar when searching for bar; if either argument is binary, MySQL performs a case-sensitive match. Check the column’s collation if the result differs from what you expect.
These functions find literal substrings. To search by a regular expression, use REGEXP_LIKE() or the REGEXP operator instead.