- 背景
当前项目业务中,
需要以字段
account_id
分组,获取"redbook_effect"
数据表中最新的数据记录集合
- 根据网上的经验描述,如果 group 和 order 一起使用
- 会先进行分组获取,
- 再对得到的结果集进行排序
- 所以如此一来,得到的最终数据中,对应字段 "account_id" 的记录并非是最新的
---- 解决方案:【使用子查询,先进行排序,再分组】
- 参考文档
【ThinkPHP5 开发文档 —— 子查询】
【where,group by,having,order by 执行顺序和编写顺序】
- 处理源码如下:
$where = [['note_content_tag', '<>', '']];
//调用 buildSql 方法后不会进行实际的查询操作,而只是生成该次查询的 SQL 语句
$subQuery = Db::name(`redbook_effect`)
->field('id,account_id,note_content_tag')
->order('id desc')
->where($where)
->buildSql();
//然后使用子查询构造新的查询
$list = Db::table($subQuery.' a')
->field('account_id,note_content_tag')
->group('account_id')
->select();
- 如上操作,生成的 sql 完整语句:
SELECT `account_id`,`note_content_tag`
FROM (
SELECT `id`,`account_id`,`note_content_tag`
FROM `mz_redbook_effect`
WHERE `note_content_tag` <> ''
ORDER BY `id` DESC ) a
GROUP BY `account_id`;
▷ 附录
①. 报错:"Every derived table must have its own alias"
- 以上处理,注意
Db::table($subQuery.' a')
中需使用别名, 可视为一张派生表a
,否则会报错:"Every derived table must have its own alias"
总结: 因为在嵌套查询中,子查询的结果是作为一个派生表给上一级进行查询,所以子查询的结果必须有一个别名
②. 大批量数据处理
- 对于大数据量的查询操作, 建议 可以使用新版提供的游标查询功能 【>>> 大批量数据处理】
( 该查询方式利用了PHP的生成器特性,可以大幅减少大量数据查询的内存占用问题 )