How to define a custom ORDER BY order in mySQL
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
MySQL's ORDER BY clause sorts results in ascending or descending order by default. When you need a custom sort order — like prioritizing specific statuses, sorting by a business-defined sequence, or applying conditional ordering — you can use FIELD(), CASE expressions, or calculated columns to define exactly how rows should be ordered.
Method 1: FIELD() Function
FIELD() returns the position of a value in a list, making it ideal for custom ordering:
This sorts by status in the exact order specified: urgent first, delivered last.
Values not in the FIELD() list return 0 and sort first. To push unknown values to the end:
Method 2: CASE Expression
CASE provides the most flexibility for custom sorting:
Conditional Sorting with CASE
Method 3: ELT() and FIND_IN_SET()
Alternative functions for custom ordering:
Method 4: Join with a Sort Table
For complex or frequently changing sort orders, use a lookup table:
This is the most maintainable approach for sort orders that change frequently or are managed by end users.
Multiple Sort Criteria
Combine custom ordering with standard sorting:
Custom Numeric Ordering
Dynamic Custom Ordering
Use a parameter to switch sort direction:
Common Pitfalls
- FIELD() returns 0 for missing values: Values not in the
FIELD()list get position0, which sorts them before position1. Handle unknown values explicitly or push them to the end. - Performance:
FIELD()andCASEinORDER BYprevent MySQL from using indexes for sorting. For large tables, consider adding asort_ordercolumn and indexing it. - Case sensitivity:
FIELD()uses the column's collation for comparison. If your column is case-insensitive (utf8_general_ci),FIELD(status, 'Urgent')matches'urgent'. For case-sensitive matching, useBINARY. - NULL handling:
FIELD(NULL, ...)returns0. NULLs sort first in ascending order by default. UseCASE WHEN col IS NULL THEN 999 ENDto push NULLs last. - Enum columns: If the column is an
ENUMtype, MySQL stores values as integers internally.ORDER BY statuson an ENUM already uses the declaration order, which may be what you want.
Summary
- Use
FIELD(col, 'val1', 'val2', ...)for simple custom ordering of known values - Use
CASE WHEN ... THEN N ENDfor conditional or complex sort logic - Use a join with a sort-order lookup table for maintainable, changeable sort orders
- Values not in
FIELD()return 0 and sort first — handle explicitly - Custom
ORDER BYexpressions prevent index usage — add asort_ordercolumn for large tables

