Laravel Eloquent Join только строка максимального значения - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть приложение чата, созданное с использованием 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)"));
    })

Это работает хорошо, но я хотел бы иметь возможность выбирать по максимальному созданному или максимальному измененному. Если я переключу идентификатор на creat_at ('messages.created_at', '=', DB::raw("(SELECT max(id) from messages WHERE messages.chat_id = chats.id)")), это может сработать, но если две записи имеют одинаковую метку времени, это может привести к нежелательному поведению. Есть ли какой-нибудь способ получить всю строку при выборе max, чтобы я мог выбрать id?

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Я не проверял это, поэтому я не уверен, что это будет работать. Однако я предлагаю это решение на основе документации 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();
1 голос
/ 18 апреля 2020

Я думаю, что вы хотите отсортировать все сообщения для определенного c чата по времени, от самого нового до самого старого. этот код объединит chats и messages, а затем отсортирует сообщения по времени создания по убыванию.

$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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...