Overview
These rules flag the use of ordinal positions (column numbers like1, 2, 3) in ORDER BY and GROUP BY clauses. Ordinal positions are fragile and break when column lists change.
Rules covered:
order-by-ordinal: FlagsORDER BY 1,ORDER BY 2, etc.group-by-ordinal: FlagsGROUP BY 1,GROUP BY 2, etc.
order-by-ordinal
When This Rule Triggers
This rule triggers when:ORDER BYuses numeric positions:ORDER BY 1,ORDER BY 1, 2, etc.
ORDER BYuses column names or expressions- No
ORDER BYclause is present
Why It Matters
Fragility to Column Changes
Ordinal positions inORDER BY refer to columns by their position in the SELECT list:
SELECT list, the ORDER BY behavior silently changes:
Problems This Causes
- Silent breakage: Query still runs but produces different results
- Hard to review: Code reviewers don’t immediately see what column is being sorted
- Refactoring hazards: Adding/removing/reordering SELECT columns breaks ORDER BY
- Poor readability:
ORDER BY 2, 3, 1is unclear without looking at SELECT list
Better Alternative: Use Column Names
Always use explicit column names or expressions:Examples
Problematic: ORDER BY 1
Problematic: ORDER BY 1
id). If columns are reordered, behavior changes.Problematic: ORDER BY 1, 2
Problematic: ORDER BY 1, 2
Good: ORDER BY column name
Good: ORDER BY column name
Good: ORDER BY multiple columns
Good: ORDER BY multiple columns
Good: ORDER BY expression
Good: ORDER BY expression
group-by-ordinal
When This Rule Triggers
This rule triggers when:GROUP BYuses numeric positions:GROUP BY 1,GROUP BY 1, 2, etc.
GROUP BYuses column names or expressions- No
GROUP BYclause is present
Why It Matters
Same Issues as ORDER BY
Ordinal positions inGROUP BY have the same problems as in ORDER BY:
GROUP BY is More Critical
WithGROUP BY, ordinal position mistakes can cause:
- Wrong aggregations: Grouping by the wrong column produces incorrect counts/sums
- Runtime errors: Grouping by an aggregate function (like
count(*)) causes errors - Subtle data bugs: Incorrect groups may not be immediately obvious
Better Alternative: Use Column Names
Always use explicit column names or expressions:Examples
Problematic: GROUP BY 1
Problematic: GROUP BY 1
status). Fragile to SELECT list changes.Problematic: GROUP BY 1, 2
Problematic: GROUP BY 1, 2
Good: GROUP BY column name
Good: GROUP BY column name
Good: GROUP BY multiple columns
Good: GROUP BY multiple columns
Good: GROUP BY expression
Good: GROUP BY expression
day in some databases, but expression is clearer.Historical Context
Why Do Ordinals Exist?
Ordinal positions inORDER BY and GROUP BY come from early SQL standards when:
- Column names weren’t always available (especially for computed columns)
- Typing was minimized (important on slow terminals)
- SQL was often generated by tools, not written by hand
Modern Alternatives
Today, better alternatives exist:- Column aliases: Give expressions names with
AS - Repeat expressions: Modern optimizers handle repeated expressions efficiently
- Readability over brevity: Explicit code is better than terse code
Implementation Details
order-by-ordinal
The rule works by:- Walking the SQL AST to find
SelectStmtnodes - Iterating through
SortClause(ORDER BY) items - Checking if each
SortBynode contains anA_Constwith an integer value - Reporting a warning at the location of the ordinal
order_by_ordinal.go
group-by-ordinal
The rule works by:- Walking the SQL AST to find
SelectStmtnodes - Iterating through
GroupClause(GROUP BY) items - Checking if each item is an
A_Constnode with an integer value - Reporting a warning at the location of the ordinal
group_by_ordinal.go