pagehelper-org/Mybatis-PageHelper · error · PageException
The column " " needs to define an alias
Error message
The column "${expression}" needs to define an alias What it means
When PageHelper rewrites SQL Server queries it must duplicate ORDER BY expressions into the wrapping select's column list (via ROW_NUMBER). If an ORDER BY expression is not a simple column (e.g. a function like LOWER(name)) and does not appear in the original SELECT list, or appears as a complex expression without an alias, the parser cannot reference it safely and demands the query column define an alias.
Solutions
- Add an alias to the complex select expression and order by the alias: SELECT UPPER(name) AS upper_name FROM t ORDER BY upper_name
- Order by a plain column instead of an expression
- Include the ORDER BY expression as a plain column in the SELECT list with an alias
- Remove the expression from ORDER BY or move ordering into an outer wrapper query that you page over
Example fix
// before SELECT UPPER(name) FROM users ORDER BY UPPER(name) // after SELECT UPPER(name) AS upper_name FROM users ORDER BY upper_name
Defensive patterns
Strategy: validation
Validate before calling
// Ensure every ORDER BY expression used in a paged SQL Server query is a plain column or aliased select item
for (String orderByExpr : extractOrderByExpressions(sql)) {
if (orderByExpr.contains("(") && !selectListContainsAlias(sql, orderByExpr)) {
throw new IllegalArgumentException("ORDER BY expression '" + orderByExpr + "' needs a select alias for pagination");
}
} Try / catch
try {
return mapper.selectPaged(params);
} catch (PageException e) {
if (e.getMessage().contains("needs to define an alias")) {
log.warn("Aliasing required for paged ORDER BY, falling back to manual paging");
return manualPagedSelect(params);
}
throw e;
} Prevention
- Always alias computed/function columns: SELECT UPPER(name) AS upper_name
- ORDER BY aliases or plain columns, never raw expressions, in paged queries
- Add a lint/test that paginates all production SQL against SQL Server
When it happens
Trigger: SQL Server pagination where an ORDER BY item is a non-Column expression (function, arithmetic) that is not a plain column in the select list, or the ORDER BY expression matches a select item that is a function/expression without an alias (e.g. SELECT UPPER(name) FROM t ORDER BY UPPER(name)).
Common situations: Ordering by a function or computed expression in SQL Server paged queries; ORM-generated SQL with expression-based ORDER BY; legacy SQL migrated to SQL Server pagination.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unable to process the SQL, you can submit issues in GitHub…
- The order by in the original SQL
- The SQL statement cannot be converted to a pagination query!
- the pagination statement must be a select query!
- The pagination statement already contains the top, and can…
AI-assisted analysis of pagehelper-org/Mybatis-PageHelper@c692616c5b (2026-09-08).
Data as JSON: /api/errors/2cfe9727909b96ca.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/github/pagehelper/parser/defaults/DefaultSqlServerSqlParser.java:461
if (selectExpressionItem != null) { // OrderByElement 在查询列表中
Alias alias = selectExpressionItem.getAlias();
if (alias != null) { // 查询列含有别名时用查询列别名
iterator.set(cloneOrderByElement(orderByElement, alias.getName()));
} else { // 查询列不包含别名
if (expression instanceof Column) {
// 查询列为普通列,这时因为列在嵌套查询外时名称中不包含表名,故去除排序列的表名引用
// 例(仅为解释此处逻辑,不代表最终分页结果):
// SELECT TEST.A FROM TEST ORDER BY TEST.A
// -->
// SELECT A FROM (SELECT TEST.A FROM TEST) ORDER BY A
((Column) expression).setTable(null);
} else {
// 查询列不为普通列时(例如函数列)不支持分页
// 此种情况比较难预测,简单的增加新列容易产生不可预料的结果
// 而为列增加别名是非常简单的,故此要求排序复杂列必须使用别名
throw new PageException("The column \"" + expression + "\" needs to define an alias");
}
}
} else { // OrderByElement 不在查询列表中,需要自动生成一个查询列
if (expression instanceof Column) { // OrderByElement 为普通列
Table table = ((Column) expression).getTable();
if (table == null) { // 表名为空
if (allColumns ||
(allColumnsTables.size() == 1 && plainSelect.getJoins() == null) ||
aliases.contains(((Column) expression).getColumnName())) {
// 包含`*`查询列 或者 只有一个 `t.*`列且为单表查询 或者 其实排序列是一个别名
// 此时排序列其实已经包含在查询列表中了,不需做任何操作
continue;
}
} else { //表名不为空
String tableName = table.getName();
if (allColumns || allColumnsTables.contains(tableName)) {View on GitHub (pinned to c692616c5b)