Summary
Add a rule to detect numeric ordinal references in ORDER BY and GROUP BY clauses (e.g., ORDER BY 1, 2) instead of explicit column names.
Why This Matters
Using ordinal positions is a maintenance hazard:
- Fragile code — changing SELECT columns breaks ordering silently
- Unreadable —
ORDER BY 1, 3, 2 tells you nothing about intent
- Refactoring nightmare — adding/removing columns shifts numbers
- Bug source — off-by-one errors common when modifying
- Code review difficulty — reviewers can't verify correctness without counting
The Fragility Problem
-- Original query (sorts by name, date):
SELECT id, name, created_at FROM users ORDER BY 2, 3;
-- Someone adds email to SELECT:
SELECT id, email, name, created_at FROM users ORDER BY 2, 3;
-- Now sorts by email, name — NOT what was intended!
-- No error, no warning, just wrong results.
Explicit Names Are Self-Documenting
-- Bad: What is this sorting by?
SELECT id, name, created_at, status FROM users ORDER BY 2, 3 DESC, 4;
-- Good: Crystal clear intent
SELECT id, name, created_at, status FROM users ORDER BY name, created_at DESC, status;
Rule Specification
| Property |
Value |
| Rule ID |
STYLE004 |
| Name |
Ordinal in ORDER BY/GROUP BY |
| Category |
Style |
| Severity |
Info |
| Default |
Enabled |
Detection Patterns
-- Should trigger
SELECT name, COUNT(*) FROM users GROUP BY 1;
SELECT * FROM orders ORDER BY 1, 2;
SELECT id, name FROM users ORDER BY 1 DESC;
-- Should NOT trigger (explicit columns)
SELECT name, COUNT(*) FROM users GROUP BY name;
SELECT * FROM orders ORDER BY created_at, id;
SELECT id, name FROM users ORDER BY id DESC;
Suggested Message
"Using column ordinal (ORDER BY 1) instead of column name. Ordinals are fragile — changing SELECT columns silently breaks ordering. Use explicit column names: ORDER BY column_name."
Historical Context
Ordinal syntax was added to SQL for brevity in interactive sessions, not for application code. Most modern linters flag this:
References
Implementation Notes
- Detect:
ORDER BY or GROUP BY followed by numeric literal
- Match patterns:
ORDER BY 1, ORDER BY 1, 2, GROUP BY 1
- Regex-ish:
(ORDER|GROUP)\s+BY\s+\d
- Don't flag:
LIMIT 1, OFFSET 10 (different context)
- Consider:
ORDER BY 1 + 0 edge case (rare, but expression vs ordinal)
Summary
Add a rule to detect numeric ordinal references in
ORDER BYandGROUP BYclauses (e.g.,ORDER BY 1, 2) instead of explicit column names.Why This Matters
Using ordinal positions is a maintenance hazard:
ORDER BY 1, 3, 2tells you nothing about intentThe Fragility Problem
Explicit Names Are Self-Documenting
Rule Specification
STYLE004Detection Patterns
Suggested Message
Historical Context
Ordinal syntax was added to SQL for brevity in interactive sessions, not for application code. Most modern linters flag this:
References
Implementation Notes
ORDER BYorGROUP BYfollowed by numeric literalORDER BY 1,ORDER BY 1, 2,GROUP BY 1(ORDER|GROUP)\s+BY\s+\dLIMIT 1,OFFSET 10(different context)ORDER BY 1 + 0edge case (rare, but expression vs ordinal)