【问题标题】:Laravel Eloquent Join only maximum value rowLaravel Eloquent 仅加入最大值行
【发布时间】:2020-07-31 10:50:12
【问题描述】:

我有一个使用 Laravel 构建的聊天应用程序。 聊天模型有很多消息。 我想使用每个聊天中最新消息中的数据加入相关聊天。 到目前为止,这就是它的设置方式

chats()->join('messages', function ($join) {
        $join->on('messages.chat_id', '=', 'chats.id')
            ->on('messages.id', '=', DB::raw("(SELECT max(id) from messages WHERE messages.chat_id = chats.id)"));
    })

这很好用,但我希望能够通过 max created_at 或 max modified_at 进行选择。 如果我将 id 切换为 created_at ('messages.created_at', '=', DB::raw("(SELECT max(id) from messages WHERE messages.chat_id = chats.id)")) 这可能会起作用,但如果两条记录具有相同的时间戳,则可能会导致不需要的行为。选择 max 时是否有某种方法可以检索整行以便我可以选择 id?

【问题讨论】:

  • 我现在正在开发一个聊天系统,我使用“最新”解决了它...messages->latest()->paginate(20) 然后我颠倒顺序让它们显示在页面上的显示方式与聊天的显示方式相同(最旧的在顶部,最新的在底部)。

标签: mysql laravel eloquent


【解决方案1】:

我没有测试过它,所以我不确定它是否会起作用。不过,我建议根据 Laravel 的文档使用此解决方案(https://laravel.com/docs/7.x/queries#joins 请参阅“子查询连接”):

$latestMessages = DB::table('messages')
    ->select('*', DB::raw('RANK() OVER (PARTITION BY chat_id ORDER BY modified_at DESC, created_at DESC, id DESC) as latest_rank'))
    ->where('latest_rank', 1);

$chats = DB::table('chats')
    ->joinSub($latestMessages, 'latest_messages', function ($join) {
        $join->on('chats.id', '=', 'latest_messages.chat_id');
    })->get();

【讨论】:

  • 不幸的是,这会导致语法错误SQLSTATE[42000]: Syntax error or access violation: 1064
【解决方案2】:

我认为您想按时间对特定聊天的所有消息进行排序,从最新到最旧。 此代码将加入chatsmessages,然后根据创建时间对消息进行降序排序。

$latestMessage = Message::select('chat_id', DB::raw('MAX(created_at) as 
               last_message_created_at'))
               ->groupBy('chat_id');

$chats = Chat::joinSub($latestMessage, 'messages', function ($join) {
        $join->on('chats.id', '=', 'messages.chat_id');
    })->get();

【讨论】:

  • 这不是我想要的。如果我只是按照您建议的方式加入,我将获得聊天中每条消息的条目,而不仅仅是最近的一条。我不想排序,我只想要最近的消息。
  • 如果你想最近使用->first()而不是上面代码中的->get()
  • 只返回一个聊天。我想要所有的聊天,但每次聊天只有一条消息。
  • @Marissa 我找到你了,让我将其编辑为可以解决此问题的其他内容
  • 谢谢,这很好用。有没有办法添加选择消息的实际内容?
猜你喜欢
  • 2014-11-21
  • 2018-07-27
  • 1970-01-01
  • 2014-04-17
  • 2018-08-16
  • 2022-01-13
  • 2011-02-05
  • 1970-01-01
  • 2021-07-03
相关资源
最近更新 更多