ORDER BY
The ORDER BY clause sorts query results.
Basic Sorting#
Ascending Order (Default)#
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age
Descending Order#
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age DESC
Explicit Ascending#
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age ASC
Multiple Sort Columns#
MATCH (u:User)
RETURN u.city, u.name, u.age
ORDER BY u.city, u.age DESC, u.name
This sorts by: 1. City (ascending) 2. Then age (descending) within each city 3. Then name (ascending) for same city and age
Sort by Expression#
Computed Values#
MATCH (u:User)
RETURN u.firstName, u.lastName
ORDER BY u.firstName + ' ' + u.lastName
Function Results#
MATCH (u:User)
RETURN u.name, u.email
ORDER BY toLower(u.email)
Aggregations#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, count(p) AS posts
ORDER BY posts DESC
Sort by Relationship Properties#
MATCH (a:User)-[r:KNOWS]->(b:User)
WHERE a.name = 'Alice'
RETURN b.name, r.since
ORDER BY r.since DESC
Sort with Aliases#
MATCH (u:User)
RETURN u.name AS userName, u.age AS userAge
ORDER BY userAge DESC, userName
Null Handling#
NULL values sort to the end by default:
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age
// NULLs appear last
Descending order:
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age DESC
// NULLs appear first
Sort by Multiple Properties#
Primary and Secondary Sort#
MATCH (p:Post)
RETURN p.title, p.likes, p.created
ORDER BY p.likes DESC, p.created DESC
Mixed Ascending/Descending#
MATCH (u:User)
RETURN u.country, u.city, u.name
ORDER BY u.country ASC, u.city DESC, u.name ASC
Sort with LIMIT#
MATCH (p:Post)
RETURN p.title, p.likes
ORDER BY p.likes DESC
LIMIT 10
Sort Aggregated Results#
Sort by Count#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, count(p) AS postCount
ORDER BY postCount DESC
Sort by Average#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, avg(p.likes) AS avgLikes
ORDER BY avgLikes DESC
Sort by Multiple Aggregations#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name,
count(p) AS posts,
avg(p.likes) AS avgLikes
ORDER BY posts DESC, avgLikes DESC
Case-Insensitive Sorting#
MATCH (u:User)
RETURN u.name
ORDER BY toLower(u.name)
Sort by Date/Time#
Recent First#
MATCH (p:Post)
RETURN p.title, p.created
ORDER BY p.created DESC
Oldest First#
MATCH (u:User)
RETURN u.name, u.joinedDate
ORDER BY u.joinedDate ASC
Sort by String Length#
MATCH (p:Post)
RETURN p.title
ORDER BY size(p.title) DESC
Sort by Array Size#
MATCH (u:User)
RETURN u.name, size(u.tags) AS tagCount
ORDER BY tagCount DESC
Common Patterns#
Top N Items#
MATCH (p:Post)
RETURN p.title, p.views
ORDER BY p.views DESC
LIMIT 10
Bottom N Items#
MATCH (p:Product)
RETURN p.name, p.sales
ORDER BY p.sales ASC
LIMIT 5
Most Active Users#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, count(p) AS posts
ORDER BY posts DESC
LIMIT 20
Recent Activity#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, p.title, p.created
ORDER BY p.created DESC
LIMIT 50
Alphabetical List#
MATCH (u:User)
RETURN u.name
ORDER BY u.name ASC
Leaderboard#
MATCH (u:User)
RETURN u.name, u.score
ORDER BY u.score DESC, u.name ASC
Timeline#
MATCH (e:Event)
RETURN e.description, e.timestamp
ORDER BY e.timestamp ASC
Performance Tips#
- Create Indexes on Sorted Properties ```cypher CREATE INDEX ON :User(age)
// Fast sorting with index MATCH (u:User) RETURN u ORDER BY u.age ```
-
Limit Before Sorting When Possible
cypher // If you only need top 10, use LIMIT ORDER BY u.age DESC LIMIT 10 -
Sort Early in Query ```cypher // Good: Sort before expensive operations MATCH (u:User) ORDER BY u.created DESC LIMIT 100 WITH u // ... more operations
// Bad: Sort after expensive operations MATCH (u:User) // ... expensive operations ORDER BY u.created DESC ```
- Avoid Sorting Large Result Sets ```cypher // Good: Filter then sort MATCH (u:User) WHERE u.active = true RETURN u ORDER BY u.name
// Bad: Sort then filter MATCH (u:User) ORDER BY u.name WHERE u.active = true RETURN u ```
Sorting NULL Values#
Control NULL placement:
// NULLs last (default ascending)
ORDER BY u.age ASC
// NULLs first (default descending)
ORDER BY u.age DESC
// Force NULLs to end
ORDER BY
CASE WHEN u.age IS NULL THEN 1 ELSE 0 END,
u.age
Random Order#
MATCH (u:User)
RETURN u
ORDER BY rand()
LIMIT 10
Next Steps#
- Limit results with LIMIT
- Filter with WHERE
- Return data with RETURN
- Read Cypher Introduction