Laravel 子查询使用having的问题

为什么JoinSub中子语句的Having以及group 会出现在外面的主语句上。。。

期望执行

select 
    a.*
from table_name as a 
inner join 
(
    select 
        count(id) as total, user_id , MAX(create_time) as create_time 
    from table_name
    where order_status = 1
    group by user_id
     having total = 2
) as b on a.user_id = b.user_id and a.create_time = b.create_time;

代码

$subQuery = $builder->from('table_name')
            ->selectRaw('count(id) as total, user_id , MAX(create_time) as create_time')
            ->groupBy(['user_id'])
            ->havingRaw("total = {$times}");

$builder->from('table_name as a')->joinSub($subQuery,'b', function ($join) {
            $join->on('a.user_id', '=', 'b.user_id');
            $join->on('a.create_time', '=', 'b.create_time');
        });

Laravel 中打印的sql语句

Column not found: 1054 Unknown column 'total' in 'having clause' (SQL: select `a`.* from `table_name` as `a` inner join (select count(id) as total, user_id , MAX(create_time) as create_time from `table_name` as `a` group by `user_id` having total = 2) as `b` on `a`.`user_id` = `b`.`user_id` and `a`.`create_time` = `b`.`create_time` where 1 = 1 group by `user_id` having total = 2 order by `a`.`create_time`

![Laravel 子查询使用having的问题]

Laravel 子查询使用having的问题

红色为疑惑位置。

cxxxx
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

因为你第二条语句还是使用的 $builder 变量,此时会被认为是前面子查询的链式调用, 所以查询条件是叠加的,第二条语句尝试修改为:

\DB::query()->from('table_name as a')->joinSub($subQuery,'b', function ($join) {
            $join->on('a.user_id', '=', 'b.user_id');
            $join->on('a.create_time', '=', 'b.create_time');
        });

试试可不可以

2年前 评论
cxxxx (楼主) 2年前
讨论数量: 3

因为你第二条语句还是使用的 $builder 变量,此时会被认为是前面子查询的链式调用, 所以查询条件是叠加的,第二条语句尝试修改为:

\DB::query()->from('table_name as a')->joinSub($subQuery,'b', function ($join) {
            $join->on('a.user_id', '=', 'b.user_id');
            $join->on('a.create_time', '=', 'b.create_time');
        });

试试可不可以

2年前 评论
cxxxx (楼主) 2年前
cxxxx
        $times = 2;
        $sql = "
            select
                count(id) as total, user_id , MAX(create_time) as create_time
            from table_name
            where
                order_status = 1
            group by user_id
            having
                total = {$times}
        ";
        $builder->from('table_name as a')->joinSub($sql,'b',function($join) {
            $join->on('a.user_id', '=', 'b.user_id');
            $join->on('a.create_time', '=', 'b.create_time');
        });
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!