NestJS+PostgreSQL用Repository-orm实现优先按nickName否则按firstName排序
问题原因
你当前的写法会先全局按nickName排序,所有nickName为空的记录会被集中排在一起,再在同nickName分组内按firstName排序,无法实现「非空nickName和firstName作为同一优先级字段排序」的需求。
解决方案
PostgreSQL 可以用COALESCE函数返回第一个非空参数,刚好匹配你的排序规则,以下是两种实现方式:
方式1:使用QueryBuilder(通用推荐,兼容所有TypeORM版本)
const contacts = await this.contactRepository .createQueryBuilder('contact') // 优先取nickName,为空则取firstName作为排序字段 .orderBy('COALESCE(contact.nickName, contact.firstName)', 'ASC') // 保留原逻辑的 lastName 排序规则 .addOrderBy('contact.lastName', 'ASC') .getMany();
方式2:实体新增预计算列(适合多处复用该排序规则的场景)
第一步先在Contact实体中新增计算列:
import { Entity, Column } from 'typeorm'; @Entity() export class Contact { // 原有其他字段省略 @Column({ type: 'text', // 定义排序字段的计算逻辑,nickName为空则取firstName asExpression: 'COALESCE(nick_name, first_name)', generatedType: 'STORED', }) sortName: string; }
第二步直接用原find方法排序即可:
const contacts = await this.contactRepository.find({ order: { sortName: 'ASC', lastName: 'ASC' }, });
注意事项
如果你的业务中nickName为空的判断标准是空字符串而非NULL,请将上述COALESCE逻辑替换为CASE WHEN语句:
CASE WHEN contact.nickName <> '' THEN contact.nickName ELSE contact.firstName END
内容的提问来源于stack exchange,提问作者Gilad Fuchs
相关产品推荐
相关产品推荐

