Kotlin Exposed关联子查询字段排序与列查询报错求助
解决Kotlin Exposed关联子查询字段引用与排序报错问题
问题原因
Exposed的QueryAlias仅能识别原表字段或显式声明了别名的表达式,你之前使用的匿名自定义Function未被Exposed跟踪,导致外层查询无法找到该列,触发Field not found in original table fields错误。
解决方案核心
给自定义聚合列添加显式别名,让Exposed在子查询中记录该列的存在,外层即可通过别名正确引用。
修改后的完整代码
// 用Exposed表达式API组合聚合逻辑,替代手动拼接SQL的匿名Function val avgScore = ScoredKeywordTable.score.avg() val countScore = ScoredKeywordTable.score.count() // 给聚合列添加显式别名 val aggScoreColumn = (avgScore + (countScore * 0.3)).alias("agg_score") val aggKeywordQuery = ScoredKeywordTable .slice( ScoredKeywordTable.scoredPageId, aggScoreColumn // 子查询中直接使用带别名的列 ) .select { ScoredKeywordTable.userId eq userId and (ScoredKeywordTable.keywordId inList keywordIds) } .groupBy(ScoredKeywordTable.scoredPageId) .orderBy(aggScoreColumn, SortOrder.DESC) .alias("aggKeywordQuery") val result = Join(ScoredPageTable) .join(aggKeywordQuery, JoinType.INNER, additionalConstraint = { ScoredPageTable.id eq aggKeywordQuery[ScoredKeywordTable.scoredPageId] }) .slice( ScoredPageTable.id, aggKeywordQuery[ScoredKeywordTable.scoredPageId], aggKeywordQuery[aggScoreColumn] // 正确引用子查询的聚合列到结果集 ) .selectAll() .orderBy(aggKeywordQuery[aggScoreColumn], SortOrder.DESC) // 使用聚合列排序 .toList()
关键改动说明
- 替换匿名Function:用Exposed内置的表达式API组合聚合逻辑,既避免手动拼接SQL的风险,也让Exposed能正确识别列信息。
- 添加列别名:通过
.alias("agg_score")给聚合列命名,QueryAlias会跟踪这个别名,外层查询就能通过aggKeywordQuery[aggScoreColumn]引用。 - 统一列引用:子查询的
slice、orderBy,以及外层的slice、orderBy都使用带别名的列,确保前后引用一致。
生成的正确SQL
SELECT scored_page.id, aggKeywordQuery.scored_page_id, aggKeywordQuery.agg_score FROM scored_page INNER JOIN ( SELECT scored_keyword.scored_page_id, AVG(scored_keyword.score) + (COUNT(scored_keyword.score) * 0.3) AS agg_score FROM scored_keyword WHERE (scored_keyword.user_id = 1000) AND (scored_keyword.keyword_id IN (1329)) GROUP BY scored_keyword.scored_page_id ORDER BY agg_score DESC ) aggKeywordQuery ON (scored_page.id = aggKeywordQuery.scored_page_id) ORDER BY aggKeywordQuery.agg_score DESC
内容的提问来源于stack exchange,提问作者JeffgNpc
相关产品推荐
相关产品推荐

