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

如何简化查询仅发布过类型1和2帖子的用户列表的SQL语句?

优化方案:获取仅发布类型1和2帖子的用户列表

你的原始SQL逻辑正确,但可以通过分组聚合等方式简化写法,以下是几种更简洁高效的实现方案:

方法1:分组后用HAVING多条件过滤

通过分组统计用户的帖子类型分布,一步完成所有筛选逻辑:

SELECT user_id
FROM post
GROUP BY user_id
HAVING 
  -- 确保用户至少发布过1条类型1的帖子
  SUM(CASE WHEN type_id = 1 THEN 1 ELSE 0 END) > 0
  -- 确保用户至少发布过1条类型2的帖子
  AND SUM(CASE WHEN type_id = 2 THEN 1 ELSE 0 END) > 0
  -- 确保用户没有发布过1、2之外的其他类型帖子
  AND SUM(CASE WHEN type_id NOT IN (1,2) THEN 1 ELSE 0 END) = 0;

如果你的数据库支持布尔值转整数(如MySQL),可以进一步简化统计部分:

SELECT user_id
FROM post
GROUP BY user_id
HAVING 
  SUM(type_id = 1) > 0
  AND SUM(type_id = 2) > 0
  AND SUM(type_id NOT IN (1,2)) = 0;

方法2:利用去重计数+极值判断

如果用户仅发布过1和2类型的帖子,那么其所有帖子的去重类型数必为2,且类型的最小、最大值恰好是1和2:

SELECT user_id
FROM post
GROUP BY user_id
HAVING 
  COUNT(DISTINCT type_id) = 2
  AND MIN(type_id) = 1
  AND MAX(type_id) = 2;

注:该写法仅适用于不存在小于1或大于2的其他类型的场景,完全匹配你的需求。

方法3:简化EXISTS子查询写法

若偏好保留EXISTS的查询风格,可以合并前两个子查询,减少表扫描次数:

SELECT DISTINCT user_id
FROM post p1
WHERE 
  EXISTS (
    SELECT 1 
    FROM post p2 
    WHERE p2.user_id = p1.user_id 
      AND p2.type_id IN (1,2) 
    GROUP BY p2.user_id 
    HAVING COUNT(DISTINCT p2.type_id) = 2
  )
  AND NOT EXISTS (
    SELECT 1 
    FROM post p2 
    WHERE p2.user_id = p1.user_id 
      AND p2.type_id NOT IN (1,2)
  );

性能优化建议

为post表创建user_id和type_id的联合索引:

CREATE INDEX idx_post_user_type ON post(user_id, type_id);

该索引能大幅提升所有方案的查询效率,让数据库直接通过索引完成统计和筛选,无需扫描全表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:16:01