MySQL查询构建求助:按用户名排序并唯一选取company_id
原查询的问题很明确:DISTINCT只返回唯一的company_id,但同一个company_id对应多个name值,你用ORDER BY name时,数据库没法确定用哪个name做排序依据,只能随机选一个,结果自然不符合预期。哪怕关闭了ONLY_FULL_GROUP_BY,这种写法逻辑本身就不严谨,排序字段和查询结果没有明确关联。
要拿到唯一的company_id并按用户名排序,得先明确你的排序规则——是按每个公司对应的最大用户名、最小用户名,还是按所有用户排序后取首次出现的公司ID?下面是两种常用方案:
方案1:按每个公司的最大用户名降序排序
用GROUP BY分组,配合聚合函数锁定排序用的用户名:
SELECT `company_id` FROM `users` GROUP BY `company_id` ORDER BY MAX(`name`) DESC;
这个查询会先按company_id分组,用每个组里最大的name值来排序。对应你的数据,company_id=1的最大用户名是user 3,company_id=2的是user 2,所以排序后结果是1在前,2在后。
方案2:按所有用户降序排序后,取不重复的company_id(保留首次出现的顺序)
如果需要先把所有用户按name从大到小排,再提取不重复的company_id(只留第一次出现的),可以用子查询加窗口函数实现(MySQL 8.0+支持):
SELECT DISTINCT `company_id` FROM ( SELECT `company_id`, `name`, ROW_NUMBER() OVER (PARTITION BY `company_id` ORDER BY `name` DESC) AS rn FROM `users` ) AS t WHERE rn = 1 ORDER BY `name` DESC;
这个子查询会先给每个公司的用户按name降序编号,只保留每个公司的第一条记录,再去重排序,结果和方案1一致,但逻辑更贴近“先排所有用户再去重”的需求。
关闭ONLY_FULL_GROUP_BY只是绕过了MySQL的语法检查,但并没有解决逻辑上的问题——排序字段和查询结果没有明确绑定,得到的结果是随机不可靠的。必须让排序字段和company_id建立明确关联(比如用聚合函数、窗口函数),才能得到稳定符合预期的结果。
内容的提问来源于stack exchange,提问作者Dipu Ahmed

