Группировать результаты на основе одного столбца или другого - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть таблица / модель для сообщений, которая имеет следующие столбцы sendid и receiveid.

Если я отправлю сообщение, в базу данных будет занесено следующее.

sendid = 1 (This is my user id)
receiveid = 12334

Если я получу сообщение, в базу данных будет занесено следующее:

sendid = 12334
receiveid = 1 (This is my user id)

Мне нужен запрос, который получит все сообщения и сгруппирует их по человеку (в основном это идентификатор, который не я). Так что если я отправлю сообщение с идентификатором пользователя 23123, то оно появится вверху. Если я тогда получу сообщение с идентификатором пользователя 8398, тогда они будут отображаться в верхней части. Как видите, человек может быть либо в столбце sendid, либо receiveid, так что именно здесь начинается борьба.

Это запрос, который у меня есть в данный момент. он не загружает сообщения, которые я отправил. Так что, если я отправлю сообщение с идентификатором пользователя 2323, они не будут go в верхней части страницы. Это крайне неэффективно (занимает 1-2 секунды в производстве). Это довольно ужасный запрос. Извинения, поскольку я не очень хорошо разбираюсь в SQL.

$getMessages = \App\Message::with("sender")->whereIn('id', function ($query) {
    return $query->select(DB::raw('max(id)'))
                ->from(with(new \App\Message)->getTable())
                ->where('receiveid', \Auth::user()->id)
                ->groupBy('sendid');
    })
    ->orderBy('created_at', 'desc')->simplePaginate(10, ['*'], 'messages_page');

Что можно сделать, чтобы улучшить это?

1 Ответ

0 голосов
/ 17 апреля 2020

Если я правильно понимаю задачу, ее можно решить следующим образом:

//subquery to retrieve all recievers' ids
$recieversSubquery = \App\Message::where('sendid', \Auth::user()->id)
    ->select('receiveid as pen_pal_id', 'created_at');

//subquery to retrieve all senders' ids
$sendersSubquery = \App\Message::where('receiveid', \Auth::user()->id)
    ->select('sendid as pen_pal_id', 'created_at');

//final query with ordering and pagination
$getMessages = $recieversSubquery
    ->union($sendersSubquery)
    ->orderBy('created_at', 'desc')
    ->simplePaginate(10, ['*'], 'messages_page');

Вот еще одно решение:

$getMessages = \App\Message::select('created_at', DB::raw('CASE WHEN sendid = ? THEN receiveid ELSE sendid END as pen_pal_id', [\Auth::user()->id]))
    ->where('sendid', \Auth::user()->id)
    ->orWhere('receiveid', \Auth::user()->id)
    ->orderBy('created_at', 'desc')
    ->simplePaginate(10, ['*'], 'messages_page');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...