MySQL Operators
An operator is a symbol or keyword that works on values: + adds, > compares, AND combines conditions. You use them in SELECT lists, WHERE clauses, UPDATE assignments and everywhere else an expression is allowed. This page walks through every group with runnable examples.
1. Operator Groups
Table: items (4 rows)
| id | name | price | qty | discount_pct | flags | specs |
|---|---|---|---|---|---|---|
| 1 | Notebook | 60.00 | 25 | NULL | 5 | {"pages": 200, "ruled": true} |
| 2 | Pen | 15.00 | 120 | 10 | 1 | {"colour": "blue"} |
| 3 | Backpack | 1450.00 | 7 | 20 | 6 | {"laptop": true, "litres": 25} |
| 4 | Stapler | 180.00 | 0 | NULL | 0 | {} |
2. Arithmetic Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Add | 7 + 2 | 9 |
- | Subtract | 7 - 2 | 5 |
* | Multiply | 7 * 2 | 14 |
/ | Divide (decimal result) | 7 / 2 | 3.5000 |
DIV | Integer division | 7 DIV 2 | 3 |
% / MOD | Remainder | 7 % 2 | 1 |
SELECT 7 + 2 AS a, 7 / 2 AS b, 7 DIV 2 AS c, 7 % 2 AS d, -7 % 2 AS e, 7 / 0 AS div_by_zero;
Result: 1 row
| a | b | c | d | e | div_by_zero |
|---|---|---|---|---|---|
| 9 | 3.5000 | 3 | 1 | -1 | NULL |
Division by zero returns NULL (with a warning) in a SELECT. In real queries:
SELECT name, price, qty,
price * qty AS stock_value,
price - price * COALESCE(discount_pct, 0) / 100 AS sale_price,
qty DIV 12 AS full_dozens,
qty % 12 AS loose_items
FROM items;
Result: 4 rows
| name | price | qty | stock_value | sale_price | full_dozens | loose_items |
|---|---|---|---|---|---|---|
| Notebook | 60.00 | 25 | 1500.00 | 60.000000 | 2 | 1 |
| Pen | 15.00 | 120 | 1800.00 | 13.500000 | 10 | 0 |
| Backpack | 1450.00 | 7 | 10150.00 | 1160.000000 | 0 | 7 |
| Stapler | 180.00 | 0 | 0.00 | 180.000000 | 0 | 0 |
3. Comparison Operators
| Operator | Meaning |
|---|---|
= | Equal |
<>, != | Not equal |
<, >, <=, >= | Less / greater (or equal) |
<=> | NULL-safe equal: NULL <=> NULL is 1 |
BETWEEN a AND b | Inclusive range |
IN (…) | Equals any value in a list |
LIKE, REGEXP | Pattern match |
IS [NOT] NULL | NULL test |
IS [NOT] TRUE/FALSE | Boolean test |
Comparisons return 1 (true), 0 (false) or NULL (unknown):
SELECT 5 > 3 AS gt, 'abc' = 'ABC' AS ci_equal, NULL = NULL AS eq_null, NULL <=> NULL AS null_safe, 3 BETWEEN 1 AND 3 AS btw, 2 IN (1, 2, 3) AS in_list;
Result: 1 row
| gt | ci_equal | eq_null | null_safe | btw | in_list |
|---|---|---|---|---|---|
| 1 | 1 | NULL | 1 | 1 | 1 |
SELECT name, price FROM items WHERE price BETWEEN 50 AND 500 AND name <> 'Pen';
Result: 2 rows
| name | price |
|---|---|
| Notebook | 60.00 |
| Stapler | 180.00 |
SELECT name, discount_pct FROM items WHERE discount_pct <=> NULL; -- NULL-safe: finds the NULLs
Result: 2 rows
| name | discount_pct |
|---|---|
| Notebook | NULL |
| Stapler | NULL |
4. Logical Operators
SELECT TRUE AND NULL AS and_null, FALSE AND NULL AS false_and_null, TRUE OR NULL AS or_null, NOT NULL AS not_null, TRUE XOR FALSE AS xor_result;
Result: 1 row
| and_null | false_and_null | or_null | not_null | xor_result |
|---|---|---|---|---|
| NULL | 0 | 1 | NULL | 1 |
SELECT name FROM items WHERE (price < 100 OR qty = 0) AND NOT name LIKE 'P%';
Result: 2 rows
| name |
|---|
| Notebook |
| Stapler |
See AND, OR, NOT and AND with OR.
5. Bitwise Operators
Bitwise operators work on the binary form of integers. A common use is storing several yes/no flags in one number: here bit 1 = on sale, bit 2 = bestseller, bit 4 = eco-friendly:
SELECT 6 & 3 AS bit_and, 6 | 3 AS bit_or, 6 ^ 3 AS bit_xor, 1 << 3 AS shift_left, 16 >> 2 AS shift_right, BIN(6) AS binary_6;
Result: 1 row
| bit_and | bit_or | bit_xor | shift_left | shift_right | binary_6 |
|---|---|---|---|---|---|
| 2 | 7 | 5 | 8 | 4 | 110 |
SELECT name, flags, BIN(flags) AS bits,
(flags & 1) > 0 AS on_sale,
(flags & 2) > 0 AS bestseller,
(flags & 4) > 0 AS eco
FROM items;
Result: 4 rows
| name | flags | bits | on_sale | bestseller | eco |
|---|---|---|---|---|---|
| Notebook | 5 | 101 | 1 | 0 | 1 |
| Pen | 1 | 1 | 1 | 0 | 0 |
| Backpack | 6 | 110 | 0 | 1 | 1 |
| Stapler | 0 | 0 | 0 | 0 | 0 |
6. String Concatenation
In MySQL || means OR (unless the PIPES_AS_CONCAT SQL mode is on), so join strings with CONCAT() or CONCAT_WS():
SELECT 'a' || 'b' AS pipes_is_or, CONCAT('Note', 'book') AS concat, CONCAT_WS(' - ', name, price) AS concat_ws FROM items WHERE id = 1;
Result: 1 row
| pipes_is_or | concat | concat_ws |
|---|---|---|
| 0 | Notebook | Notebook - 60.00 |
7. Assignment Operators
= assigns in SET and UPDATE … SET; := assigns to a user variable anywhere:
SET @tax_rate = 18;
SELECT name, price, ROUND(price * (1 + @tax_rate / 100), 2) AS with_tax FROM items WHERE id <= 2;
Result: 2 rows
| name | price | with_tax |
|---|---|---|
| Notebook | 60.00 | 70.80 |
| Pen | 15.00 | 17.70 |
UPDATE items SET qty = qty + 50 WHERE id = 4;
SELECT name, qty FROM items WHERE id = 4;
Result: 1 row
| name | qty |
|---|---|
| Stapler | 50 |
8. JSON Operators -> and ->>
col->'$.path' extracts a JSON value; ->> also removes the quotes:
SELECT name, specs->'$.colour' AS with_quotes, specs->>'$.colour' AS unquoted, specs->>'$.pages' AS pages FROM items WHERE id IN (1, 2);
Result: 2 rows
| name | with_quotes | unquoted | pages |
|---|---|---|---|
| Notebook | NULL | NULL | 200 |
| Pen | "blue" | blue | NULL |
SELECT name FROM items WHERE specs->'$.laptop' = TRUE;
Result: 1 row
| name |
|---|
| Backpack |
9. Operator Precedence
| Priority (high → low) | Operators |
|---|---|
| 1 | ! |
| 2 | - (unary minus), ~ |
| 3 | ^ |
| 4 | *, /, DIV, % |
| 5 | -, + |
| 6 | <<, >> |
| 7 | & |
| 8 | | |
| 9 | Comparisons: =, <=>, >=, LIKE, IN, IS … |
| 10 | BETWEEN, CASE |
| 11 | NOT |
| 12 | AND |
| 13 | XOR |
| 14 | OR |
| 15 (lowest) | = (assignment), := |
SELECT 2 + 3 * 4 AS no_parens, (2 + 3) * 4 AS with_parens, 1 + 2 = 3 AS comparison_last;
Result: 1 row
| no_parens | with_parens | comparison_last |
|---|---|---|
| 14 | 20 | 1 |
10. Automatic Type Conversion
MySQL converts types to make an operation work, which can surprise you:
SELECT '10' + 5 AS string_plus_number, '3 apples' + 2 AS leading_number, 'abc' = 0 AS text_vs_zero, '2026-03-14' + 0 AS date_text_plus_zero;
Result: 1 row
| string_plus_number | leading_number | text_vs_zero | date_text_plus_zero |
|---|---|---|---|
| 15 | 5 | 1 | 2026 |
11. Summary
- Arithmetic: + − * / DIV %; division by zero gives NULL.
- Comparison: = <> < > <= >= <=> BETWEEN IN LIKE IS NULL; results are 1, 0 or NULL.
- Logical: AND, OR, NOT, XOR; bitwise: & | ^ ~ << >>.
- Use CONCAT for strings (|| is OR); -> and ->> read JSON.
- Know the precedence, and use parentheses.