SQL分组查询如何筛选无用户或用户数最少的用户组
问题场景
- 存在
profile用户档案表,字段user_group_labels存储关联的用户组ID,外键关联用户组表主键ID - 需要单条SQL实现筛选逻辑:
- 第一优先级:返回未分配任何用户的用户组
- 第二优先级:如果不存在无用户的分组,返回关联用户数最少的用户组
- 示例数据如下:
profile表数据:
用户组表数据:+----+----------+-------------------+ | id | uid | user_group_labels | +----+----------+-------------------+ | 1 | xxxxxxxx | 5051288 | | 2 | yyyyyyyy | 5051288 | | 3 | zzzzzzzz | 5051286 | | 4 | aaaaaaaa | 5051286 | | 5 | bbbbbbbb | 5051286 | +----+----------+-------------------++---------+-----------------+ | id | user_group_name | +---------+-----------------+ | 5051288 | xxxxxxxx | | 5051286 | yyyyyyyy | | 4906315 | zzzzzzzz | +---------+-----------------+ - 示例预期返回:
+---------+-----------------+ | id | user_group_name | +---------+-----------------+ | 4906315 | zzzzzzzz | +---------+-----------------+返回逻辑:ID为4906315的分组无任何关联用户,符合第一优先级规则;如果移除该分组数据,则返回ID为5051288的分组,该组关联2个用户,是剩余分组中关联用户数最少的。
实现方案
通过左连接+分组计数+排序取第一条的写法即可实现,SQL如下(注意将user_group替换为实际业务中的用户组表名):
SELECT g.id, g.user_group_name FROM user_group g LEFT JOIN profile p ON g.id = p.user_group_labels GROUP BY g.id, g.user_group_name ORDER BY COUNT(p.id) ASC LIMIT 1;
逻辑说明
- 左连接会保留所有用户组记录,没有关联profile数据的分组,对应的p表字段值为NULL
COUNT(p.id)会自动忽略NULL值,因此无关联用户的分组计数结果为0,有关联用户的分组计数为实际关联的用户数量- 按计数结果升序排序时,计数为0的分组会排在最前,天然满足优先返回无用户分组的要求;如果不存在计数为0的分组,计数最小(关联用户最少)的分组会排在最前
- 最后用
LIMIT 1取排序后的第一条记录,完全匹配需求。
内容的提问来源于stack exchange,提问作者UtkuErem
相关产品推荐
相关产品推荐

