You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM中单查询获取订阅社区与用户的帖子时连接冲突问题

问题分析

你当前的SQL用了两个内连接,相当于要求帖子必须同时满足「属于用户订阅的社区」和「作者是用户订阅的用户」,这就把两类数据的交集查出来了,而不是你要的两类数据的并集,所以逻辑冲突。

解决方案

方案一:原生SQL用EXISTS实现OR逻辑

用两个EXISTS子查询分别判断两个条件,只要满足其中一个就返回帖子:

select p.*
from post p
where 
  -- 条件1:帖子属于用户订阅的社区
  exists (
    select 1 
    from subsite s
    join subsite_follow f on f.subsite_id = s.id
    where s.slug = p.subsite_slug and f.user_id = $1
  )
  OR
  -- 条件2:帖子作者是用户订阅的用户
  exists (
    select 1
    from user_following uf
    where uf.user_id_2 = p.author_id and uf.user_id_1 = $1
  )

方案二:用UNION合并两个独立查询

如果两类帖子的结果集没有重复(或允许去重),可以用UNION合并两个查询:

-- 订阅社区的帖子
select p.*
from post p
join subsite s on p.subsite_slug = s.slug
join subsite_follow f on f.subsite_id = s.id and f.user_id = $1
UNION
-- 订阅用户的帖子
select p.*
from post p
join user_following uf on uf.user_id_2 = p.author_id and uf.user_id_1 = $1
  • 若允许同一帖子因满足两个条件重复出现,用UNION ALL替代UNION,性能更优。

方案三:TypeORM QueryBuilder写法

符合ORM使用习惯,便于维护:

// 方式1:基于EXISTS子查询
const posts = await getRepository(Post)
  .createQueryBuilder('p')
  .where(
    '(exists (select 1 from subsite s join subsite_follow f on f.subsite_id = s.id where s.slug = p.subsite_slug and f.user_id = :userId))',
    { userId: req.user.id }
  )
  .orWhere(
    '(exists (select 1 from user_following uf where uf.user_id_2 = p.author_id and uf.user_id_1 = :userId))',
    { userId: req.user.id }
  )
  .getMany();

// 方式2:左连接+条件判断
const posts = await getRepository(Post)
  .createQueryBuilder('p')
  .leftJoin('subsite', 's', 's.slug = p.subsite_slug')
  .leftJoin('subsite_follow', 'f', 'f.subsite_id = s.id and f.user_id = :userId')
  .leftJoin('user_following', 'uf', 'uf.user_id_2 = p.author_id and uf.user_id_1 = :userId')
  .where('f.id IS NOT NULL OR uf.id IS NOT NULL')
  .setParameter('userId', req.user.id)
  .distinct(true) // 去重,避免同一帖子满足双条件时重复返回
  .getMany();

内容的提问来源于stack exchange,提问作者Free

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:35:03