如何在TypeORM QueryBuilder的orderBy中使用ABS()和减号运算符?
解决TypeORM中使用ABS函数排序时的"relation 'ABS(address'不存在"错误
问题场景
原生SQL中执行以下语句可正常按纬度距离排序:
ORDER BY ABS(a.latitude - 41.876698387331906) ASC
但在TypeORM中使用以下代码时,系统提示"relation 'ABS(address'不存在":
.orderBy('ABS(address.latitude - 41.41.876698387331906)', 'ASC')
问题原因
TypeORM会将orderBy方法传入的普通字符串默认解析为表/列名,而非SQL函数表达式,因此错误地把ABS(address当成了关联表名称,导致报错。另外你的代码里数值多写了一个41.,正确数值应为41.876698387331906,这个错误也需要修正。
解决方法
方法1:使用TypeORM的Raw函数(推荐)
Raw函数用于直接传递原生SQL片段,能避免TypeORM的自动解析问题,同时保障SQL注入安全:
import { Raw } from "typeorm"; // 在查询构建器中使用 yourQueryBuilder // 其他查询逻辑... .orderBy(Raw(() => `ABS(address.latitude - 41.876698387331906)`), 'ASC');
如果是当前实体的字段而非关联表字段,可以用别名参数:
.orderBy(Raw(alias => `ABS(${alias}.latitude - 41.876698387331906)`), 'ASC');
方法2:用引号包裹SQL表达式
通过引号将整个函数表达式包裹,告诉TypeORM这是原生SQL内容而非表/列名(引号规则需匹配你的数据库类型):
- PostgreSQL使用双引号:
.orderBy(`"ABS(address.latitude - 41.876698387331906)"`, 'ASC');
- MySQL使用反引号:
.orderBy(`\`ABS(address.latitude - 41.876698387331906)\``, 'ASC');
内容的提问来源于stack exchange,提问作者Gabriel Alvarez
相关产品推荐
相关产品推荐

