MySQL查询需求:优先取is_main=1的行,无则取同fk_id任意行
解决方案
要实现针对指定fk_id优先取is_main=1的行,无符合条件行则取任意一行的需求,你可以用以下两种方法:
方法一:窗口函数(推荐,MySQL 8.0+ 支持)
利用ROW_NUMBER()窗口函数按fk_id分组,给记录按优先级排序后取每组第一条:
SELECT id, fk_id, name FROM ( SELECT id, fk_id, name, ROW_NUMBER() OVER ( PARTITION BY fk_id ORDER BY is_main DESC, id ASC -- is_main降序确保主记录优先,id升序保证无主记录时取最小id行 ) AS rn FROM my_table WHERE fk_id IN (1, 2, 3, 4) ) t WHERE rn = 1;
逻辑解释
PARTITION BY fk_id:将数据按fk_id拆分为独立分组ORDER BY is_main DESC:每个分组内,is_main=1的记录会排在最前面ORDER BY id ASC:当分组内没有is_main=1的记录时,默认取id最小的行(若不需要固定规则,可省略此排序,数据库会返回任意符合的行)- 外层筛选
rn=1,即每个分组的第一条记录,正好匹配你的需求
执行结果
该语句会返回你期望的记录:
| id | fk_id | name |
|---|---|---|
| 1 | 1 | first_name |
| 2 | 2 | second_name |
| 4 | 3 | 4th_name |
| 5 | 4 | 5th_name |
方法二:关联子查询(兼容旧版MySQL)
如果你的MySQL版本不支持窗口函数,可以用关联子查询实现:
SELECT m1.id, m1.fk_id, m1.name FROM my_table m1 WHERE m1.fk_id IN (1, 2, 3, 4) AND ( m1.is_main = 1 OR NOT EXISTS ( SELECT 1 FROM my_table m2 WHERE m2.fk_id = m1.fk_id AND m2.is_main = 1 ) ) GROUP BY m1.fk_id;
逻辑解释
- 先筛选出指定
fk_id的记录 - 条件判断:要么是
is_main=1的记录,要么是该fk_id下不存在is_main=1记录的任意行 - 通过
GROUP BY fk_id确保每个fk_id只返回一条记录
内容的提问来源于stack exchange,提问作者Giacomo M
相关产品推荐
相关产品推荐

