PostgreSQL自连接转TypeORM查询结果不符问题求助
解决TypeORM原生查询误用RIGHT JOIN返回错误用户列表的问题
为啥RIGHT JOIN会出错
你原来用PostgreSQL的INNER JOIN自连接时,逻辑是找那些有对应的被创建用户的创建者——左表放创建者,右表放被创建用户,关联条件是左表的userId等于右表的creatorId,INNER JOIN只会保留两边匹配上的记录,也就是确实创建过用户的那些人。
但换成RIGHT JOIN后,它会保留右表(被创建用户)的所有记录,左表没匹配的就补NULL,最后返回的自然是被创建的用户,不是你要的创建者。
正确的TypeORM写法
写法1:和原PostgreSQL逻辑一致的INNER JOIN
import { getConnection } from "typeorm"; async function getUsersWhoCreatedOthers() { const creators = await getConnection().query(` SELECT DISTINCT u.* FROM "USER" u INNER JOIN "USER" created_users ON u."userId" = created_users."creatorId" `); return creators; }
加DISTINCT是因为一个创建者可能创建多个用户,避免结果里重复出现同一个人。
写法2:用EXISTS子查询(更高效,不用去重)
async function getUsersWhoCreatedOthers() { const creators = await getConnection().query(` SELECT u.* FROM "USER" u WHERE EXISTS ( SELECT 1 FROM "USER" created_users WHERE created_users."creatorId" = u."userId" ) `); return creators; }
这个逻辑是直接查“有没有用户是当前用户创建的”,满足条件就返回当前用户,天然不会重复,性能一般比JOIN加去重更好。
写法3:用TypeORM QueryBuilder(少写原生SQL,不容易错)
如果不想写纯原生SQL,用QueryBuilder也能实现:
import { getRepository } from "typeorm"; import { User } from "./entities/User"; // 替换成你的User实体路径 async function getUsersWhoCreatedOthers() { const userRepo = getRepository(User); const creators = await userRepo .createQueryBuilder("u") .innerJoin("User", "created_users", "u.userId = created_users.creatorId") .distinct(true) .getMany(); return creators; }
或者用QueryBuilder写EXISTS的逻辑:
async function getUsersWhoCreatedOthers() { const userRepo = getRepository(User); const creators = await userRepo .createQueryBuilder("u") .where((qb) => { const subQuery = qb.subQuery() .select("1") .from(User, "created_users") .where("created_users.creatorId = u.userId") .getQuery(); return `EXISTS(${subQuery})`; }) .getMany(); return creators; }
验证要点
查完之后,你可以核对返回的用户的userId,看看是不是都能在其他用户的creatorId字段里找到对应的值,确保结果正确。另外注意表名和字段名要和你的数据库、实体定义一致,PostgreSQL对大小写敏感,别写错了。
内容的提问来源于stack exchange,提问作者Abderazak Amiar
相关产品推荐
相关产品推荐

