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

如何简化含IN子查询的CASE WHEN语句并提升SQL查询效率

优化用户组关联查询的方案

表结构

UserGroups表

group_iduser_id
11
21
12
13

users表

idname
1John
2Mary
3Bob
4Carol

原查询问题

原查询通过多次IN子查询判断用户组归属来生成class_group字段,频繁的子查询会导致数据库多次扫描UserGroups表,查询效率低下。

优化方案

方案1:聚合用户组归属后关联

先对UserGroups表按用户聚合,标记每个用户是否属于目标组,再和users表关联判断,仅需一次聚合扫描:

SELECT
    u.id,
    u.name,
    CASE
        WHEN ug.has_group1 = 1 AND ug.has_group2 = 0 THEN 1
        WHEN ug.has_group2 = 1 AND ug.has_group1 = 0 THEN 2
        WHEN ug.has_group1 = 1 AND ug.has_group2 = 1 THEN 1
        ELSE class.group -- 保留原逻辑的默认值,按需调整关联class表的逻辑
    END AS class_group
FROM users u
LEFT JOIN (
    SELECT
        user_id,
        MAX(CASE WHEN group_id = 1 THEN 1 ELSE 0 END) AS has_group1,
        MAX(CASE WHEN group_id = 2 THEN 1 ELSE 0 END) AS has_group2
    FROM UserGroups
    GROUP BY user_id
) ug ON u.id = ug.user_id
-- 按需添加原查询中的其他关联表,比如LEFT JOIN class ...

方案2:多次LEFT JOIN直接关联目标组

通过两次LEFT JOIN分别关联组1、组2的记录,利用JOIN结果的非空性判断归属,写法更直观:

SELECT
    u.id,
    u.name,
    CASE
        WHEN g1.user_id IS NOT NULL AND g2.user_id IS NULL THEN 1
        WHEN g2.user_id IS NOT NULL AND g1.user_id IS NULL THEN 2
        WHEN g1.user_id IS NOT NULL AND g2.user_id IS NOT NULL THEN 1
        ELSE class.group -- 保留原逻辑的默认值,按需调整关联class表的逻辑
    END AS class_group
FROM users u
LEFT JOIN UserGroups g1 ON u.id = g1.user_id AND g1.group_id = 1
LEFT JOIN UserGroups g2 ON u.id = g2.user_id AND g2.group_id = 2
-- 按需添加原查询中的其他关联表,比如LEFT JOIN class ...

性能提示

如果在UserGroups表上创建(user_id, group_id)联合索引,以上两种方案的查询效率会进一步提升,数据库能快速定位到用户对应的组记录。

内容的提问来源于stack exchange,提问作者Juan Elias da Cunha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:25:52