50 Most Common SQL Patterns and Their ActiveRecord Equivalents
Copy-paste ready examples for every Rails developer's toolkit
Quick Reference: Organized by difficulty • Performance notes included • Try examples live
Jump to Section
Beginner (1-20)
Intermediate (21-35)
Advanced (36-50)
Beginner Patterns (1-20): Basic SELECT Operations
1. Select All Records
BeginnerSQL
SELECT * FROM users;
ActiveRecord
User.all
⚡ Performance: Use User.find_each
for large datasets
2. Select Specific Columns
BeginnerSQL
SELECT id, name, email FROM users;
ActiveRecord
User.select(:id, :name, :email)
⚡ Performance: Selecting fewer columns reduces memory usage
3. Single WHERE Condition
BeginnerSQL
SELECT * FROM users WHERE active = true;
ActiveRecord
User.where(active: true)
💡 Tip: ActiveRecord automatically parameterizes values to prevent SQL injection
4. Multiple AND Conditions
BeginnerSQL
SELECT * FROM users
WHERE active = true AND age > 18;
ActiveRecord
User.where(active: true)
.where('age > ?', 18)
💡 Alternative: User.where(active: true, age: 19..Float::INFINITY)
5. IN Clause
BeginnerSQL
SELECT * FROM users
WHERE id IN (1, 2, 3, 4, 5);
ActiveRecord
User.where(id: [1, 2, 3, 4, 5])
⚡ Performance: Consider using ranges for consecutive numbers
10. ORDER BY with LIMIT
BeginnerSQL
SELECT * FROM posts
ORDER BY created_at DESC
LIMIT 10;
ActiveRecord
Post.order(created_at: :desc).limit(10)
💡 Common pattern for "recent posts" or "latest updates"
Intermediate Patterns (21-35): JOINs and Associations
21. Simple INNER JOIN
IntermediateSQL
SELECT users.*, posts.*
FROM users
JOIN posts ON users.id = posts.user_id;
ActiveRecord
User.joins(:posts)
.select('users.*, posts.*')
⚡ Performance: Use includes(:posts)
to avoid N+1 queries
25. JOIN with WHERE on Associated Table
IntermediateSQL
SELECT users.* FROM users
JOIN posts ON users.id = posts.user_id
WHERE posts.published = true;
ActiveRecord
User.joins(:posts)
.where(posts: { published: true })
💡 This finds users who have at least one published post
30. GROUP BY with COUNT
IntermediateSQL
SELECT user_id, COUNT(*) as post_count
FROM posts
GROUP BY user_id;
ActiveRecord
Post.group(:user_id).count
📊 Returns a hash: {user_id => count}
Advanced Patterns (36-50): Complex Queries
40. EXISTS Subquery
AdvancedSQL
SELECT * FROM users
WHERE EXISTS (
SELECT 1 FROM posts
WHERE posts.user_id = users.id
AND posts.published = true
);
ActiveRecord
User.where(id:
Post.where(published: true)
.select(:user_id)
)
🔍 Alternative: User.joins(:posts).where(posts: {published: true}).distinct
45. Complex CASE Statement
AdvancedSQL
SELECT *,
CASE
WHEN age < 18 THEN 'Minor'
WHEN age < 65 THEN 'Adult'
ELSE 'Senior'
END as age_group
FROM users;
ActiveRecord
User.select("*,
CASE
WHEN age < 18 THEN 'Minor'
WHEN age < 65 THEN 'Adult'
ELSE 'Senior'
END as age_group")
💡 For complex logic, consider using a Ruby method instead
50. Multiple Table JOIN with Aggregation
AdvancedSQL
SELECT u.name, COUNT(p.id) as post_count,
AVG(c.rating) as avg_rating
FROM users u
JOIN posts p ON u.id = p.user_id
LEFT JOIN comments c ON p.id = c.post_id
GROUP BY u.id, u.name
HAVING COUNT(p.id) > 5;
ActiveRecord
User.joins(posts: :comments)
.group('users.id', 'users.name')
.having('COUNT(posts.id) > 5')
.select('users.name,
COUNT(posts.id) as post_count,
AVG(comments.rating) as avg_rating')
🎯 The most complex pattern - combines everything!
Test These Patterns
Ready to convert your own SQL queries using these patterns? Our free online tool supports all of these conversion types and more.
Copy any SQL pattern above and paste it into our converter for instant ActiveRecord translation