如何在MySQL或Go中从不同WHERE条件查询10条记录
问题描述
现有users表,原分页查询逻辑为select * from users limit size offset (index-1)*size,要求调整为每页10条记录,其中必须包含1条rank_value > 0的记录,剩余9条为rank_value = 0的记录,需实现该分页查询逻辑。
建表语句
CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT '', `age` int(11) NOT NULL DEFAULT '0', `rank_value` int(11) NOT NULL DEFAULT '0', `insert_at` bigint NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
原Go查询代码
// init db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8") if err != nil { log.Fatal(err) } // create dbr session sess := dbr.NewConnection(db, nil) // query list var users []User _, err = sess.Select("*").From("users").OrderBy("insert_at desc").Offset((Index - 1) * Size).Limit(Size).Load(&users) if err != nil { log.Fatal(err) } for _, user := range users { fmt.Println(user.Name) }
解决方案
方案一:MySQL单SQL实现
核心逻辑是分别查询两类数据的分页结果,再合并返回。假设页码为page,固定每页10条:
-- 合并高权重与普通记录,支持统一排序 SELECT * FROM ( -- 取当前页的1条高权重记录 (SELECT * FROM users WHERE rank_value > 0 ORDER BY insert_at DESC LIMIT 1 OFFSET (page-1)*1) UNION ALL -- 取当前页的9条普通记录,若高权重记录不足则补全 (SELECT * FROM users WHERE rank_value = 0 ORDER BY insert_at DESC LIMIT 10 OFFSET (page-1)*9) ) AS temp LIMIT 10;
边界处理:当rank_value > 0的记录总数不足当前页需求时,自动用普通记录补全至10条。
方案二:Go代码层面实现
通过两次查询分别获取高权重和普通记录,再合并结果,灵活处理边界场景:
const pageSize = 10 const normalCount = 9 const highRankCount = 1 page := 1 // 当前页码,可根据业务传入调整 var highRankUsers []User var normalUsers []User // 查询当前页的高权重记录 _, err = sess.Select("*").From("users"). Where("rank_value > ?", 0). OrderBy("insert_at desc"). Offset((page - 1) * highRankCount). Limit(highRankCount). Load(&highRankUsers) if err != nil { log.Fatal(err) } // 计算需要补充的普通记录数量:高权重不足时,用普通记录补全至10条 needNormalCount := normalCount if len(highRankUsers) < highRankCount { needNormalCount = pageSize - len(highRankUsers) } // 查询对应数量的普通记录 _, err = sess.Select("*").From("users"). Where("rank_value = ?", 0). OrderBy("insert_at desc"). Offset((page - 1) * normalCount). Limit(needNormalCount). Load(&normalUsers) if err != nil { log.Fatal(err) } // 合并结果并按insert_at降序排序(可选) users := append(highRankUsers, normalUsers...) sort.Slice(users, func(i, j int) bool { return users[i].InsertAt > users[j].InsertAt }) for _, user := range users { fmt.Println(user.Name) }
优势:可灵活处理高权重记录不足的场景,便于添加日志、监控等业务逻辑。
内容的提问来源于stack exchange,提问作者Elsa
相关产品推荐
相关产品推荐

