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

SQL筛选异常分配角色用户及查询语句优化咨询

SQL查询优化调整方案

原有语句的问题

你原来的写法逻辑无法满足需求:同一行的introleid不可能同时属于子角色集合和父角色集合,两个集合的ID没有重叠,所以NOT IN条件相当于完全未生效,最终只会查出所有持有目标子角色的用户,没有过滤掉其中已经持有父角色的正常用户。

正确优化方案

方案1:使用NOT EXISTS实现(可读性最高,执行效率也较好)

SELECT DISTINCT url.intuserid
FROM user_role_link url
WHERE 
  -- 过滤:用户持有目标子角色
  url.introleid IN (256, 308, 313, 314, 484, 485)
  AND url.bitLive = 1
  AND url.bitDeleted = 0
  -- 核心过滤:该用户不存在任何一个目标父角色
  AND NOT EXISTS (
    SELECT 1 
    FROM user_role_link url2
    WHERE 
      url2.intuserid = url.intuserid
      AND url2.introleid IN (225, 228, 229, 230, 231, 232, 233, 236, 237, 239, 240, 241, 242)
      AND url2.bitLive = 1
      AND url2.bitDeleted = 0
  )

方案2:使用分组聚合判断(适合需要同时统计用户持有的角色数的场景)

SELECT url.intuserid
FROM user_role_link url
WHERE url.bitLive = 1 AND url.bitDeleted = 0
GROUP BY url.intuserid
HAVING 
  -- 至少持有一个目标子角色
  SUM(CASE WHEN url.introleid IN (256, 308, 313, 314, 484, 485) THEN 1 ELSE 0 END) > 0
  -- 完全没有持有目标父角色
  AND SUM(CASE WHEN url.introleid IN (225, 228, 229, 230, 231, 232, 233, 236, 237, 239, 240, 241, 242) THEN 1 ELSE 0 END) = 0

可选扩展:关联角色表展示角色信息

如果需要同时展示用户持有的异常子角色名称,可以关联dbo.user_role表:

SELECT DISTINCT url.intuserid, ur.DescriptionRole AS 异常角色名称
FROM user_role_link url
JOIN dbo.user_role ur ON url.introleid = ur.roleid
WHERE 
  url.introleid IN (256, 308, 313, 314, 484, 485)
  AND url.bitLive = 1
  AND url.bitDeleted = 0
  AND NOT EXISTS (
    SELECT 1 
    FROM user_role_link url2
    WHERE 
      url2.intuserid = url.intuserid
      AND url2.introleid IN (225, 228, 229, 230, 231, 232, 233, 236, 237, 239, 240, 241, 242)
      AND url2.bitLive = 1
      AND url2.bitDeleted = 0
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:24:01