leftJoin +groupBy() 如何连接的是左表的最后一条记录 而不是左表的第一条记录

客户表 customer
| id | name|
| —客户id— | —客户名称— |
| 1 | 张三 |
| 2 | 李四|

操作表 action
| id | c_id| content|
| —操作记录id— | —客户id— | —记录内容— |
| 1 | 1 | content-1 |
| 2 | 1 | content-2 |
| 3 | 2 | content-3 |
| 4 | 2 | content-4 |

方法 1

$record=Customer::leftJoin('action as a','a.c_id','=','customer.id')
->select('customer.id as c_id','a.id as a_id','a.content')
->groupBy('customer.id')
->orderBy('a.id','desc')
->get();

方法 2

$record=Customer::leftJoin('action as a',function ($join){
    $join->on('a.c_id','=','customer.id')
        ->orderBy('a.id','desc');
  },null,null,'left')
->select('customer.id as c_id','a.id as a_id')
->groupBy('customer.id')
->orderBy('a.id','desc')
->get();

返回结果都是这个:
| c_id | a_id| content|
| —客户id— | —操作记录id— | —记录内容— |
| 1 | 1 | content-1|
| 2 | 3 | content-3|

希望返回
| c_id | a_id| content|
| —客户id— | —操作记录id— | —记录内容— |
| 1 | 2 | content-2|
| 2 | 4 | content-4|

这样返回的是 action 表记录 是关于customer.id 的第一条记录 而不是最后一条记录
问下大家有什么方法,让action表 返回关于customer.id 的最后一条记录

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

排序对group不生效,其实你这个问题本质就是分组取前几条,相对比较复杂,百度一搜一堆,但我觉得你可以换个思路,简单的看你的数据,可能用 max(id)就可以实现

4年前 评论
wenreal (楼主) 4年前
Adachi (作者) 4年前
Adachi (作者) 4年前
Adachi (作者) 4年前
讨论数量: 6

排序对group不生效,其实你这个问题本质就是分组取前几条,相对比较复杂,百度一搜一堆,但我觉得你可以换个思路,简单的看你的数据,可能用 max(id)就可以实现

4年前 评论
wenreal (楼主) 4年前
Adachi (作者) 4年前
Adachi (作者) 4年前
Adachi (作者) 4年前
jcc123

这样

select * from $record order by id desc
4年前 评论
wenreal (楼主) 4年前

$subQuery=Customer::join("action as a","a.c_id","=","customer.id","left")
            ->select('customer.id as c_id','a.id as a_id')
            ->orderBy("a.id","desc");
        $bindings = $subQuery->getBindings();
        $sql = str_replace('?', '%s', $subQuery->toSql());
        $sql = sprintf($sql, ...$bindings);
        $query = DB::table(DB::raw("({$sql}) as t"))
            ->groupBy("c_id")
            ->get()->toArray();
4年前 评论

groupBy 组内排序需要使用子查询,因为 groupBy 的优先级比 orderBy 高,orderBy排的是分组后的数据

4年前 评论
never_stop
SELECT
    b.*,
    c.* 
FROM
    (
SELECT
    ANY_VALUE (  id ) AS id,
    ANY_VALUE ( content-1 ) AS content-1,
    ANY_VALUE ( content-2 ) AS content-2
FROM
    ( SELECT * FROM action ORDER BY id DESC LIMIT 10000000000 ) AS a 
GROUP BY
    a.c_id 
HAVING
    id != 0
    ) AS b
LEFT JOIN customer c ON b.id = c.id 

大家觉得这种查询适用什么情况

4年前 评论
 Customer::query()
            ->with(['action'=>function($query){
                $query->orderBy('id','desc')
                    ->limit(1);
            }])
            ->get();
4年前 评论
wenreal (楼主) 4年前

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