У меня есть две таблицы:
Темы
id, created_at, updated_at, deleted_at
Сообщения
id, thread_id, user_id, created_at, updated_at, deleted_at
Вот ссылкак созданной мной скрипте SQL, которая строит эту взаимосвязь:
http://sqlfiddle.com/#!9/915829/3/0
Модель потока имеет эту связь для сообщений
/**
* Messages relationship.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*
* @codeCoverageIgnore
*/
public function messages()
{
return $this->hasMany(Message::class, 'thread_id', 'id');
}
Модель сообщений имеет эту связь для потока:
/**
* Thread relationship.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*
*/
public function thread()
{
return $this->belongsTo(Thread::class, 'thread_id', 'id');
}
Сначала я запускаю запрос, который получает все потоки для определенного пользователя.Получив все потоки, я извлекаю идентификатор каждого потока в массив.Теперь я хочу получить последнее сообщение для каждого идентификатора потока.Я пробовал это:
Message::whereIn('thread_id', $threadIds)
Но это дает мне каждое сообщение, связанное с каждым thread_id, глядя на это, я вижу, что это может вызвать некоторые серьезные проблемы, если, скажем, некоторые изтемы были связаны с тысячами сообщений.Я также попробовал следующее:
Message::whereIn('thread_id', $threadIds)->take(1)
, который возвращает только один результат, который я тоже не хочу.Мне интересно, знал ли кто-нибудь о способе получить последнее сообщение только для каждого из $ threadIds.
Вот пример моей схемы с некоторыми примерами данных:
CREATE TABLE `messages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`thread_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`body` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `threads` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`subject` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `threads` (`id`, `subject`, `created_at`, `updated_at`, `deleted_at`)
VALUES
(1, 'test subject 1', '2019-02-01 00:32:56', '2019-02-01 00:32:56', NULL),
(2, 'test subject 2', '2019-02-01 00:34:42', '2019-02-01 00:34:42', NULL);
INSERT INTO `messages` (`id`, `thread_id`, `user_id`, `body`, `created_at`, `updated_at`, `deleted_at`)
VALUES
(1, 1, 2, 'test1', '2019-02-01 00:32:56', '2019-02-01 00:32:56', NULL),
(2, 1, 1, 'test2', '2019-02-01 00:32:59', '2019-02-01 00:32:59', NULL),
(3, 1, 2, 'test3', '2019-02-01 00:34:42', '2019-02-01 00:34:42', NULL),
(4, 2, 1, 'test4', '2019-02-01 00:35:56', '2019-02-01 00:35:56', NULL),
(5, 2, 3, 'test5', '2019-02-01 00:36:59', '2019-02-01 00:36:59', NULL),
(6, 2, 1, 'test6', '2019-02-01 00:37:42', '2019-02-01 00:37:42', NULL);
Допустим, я хочу получать последние сообщения для потоков с идентификаторами: 1 и 2, я хотел бы получить результатустановите так:
id thread_id user_id body created_at updated_at deleted_at
3 1 2 test3 2019-02-01T00:34:42Z 2019-02-01T00:34:42Z (null)
6 2 1 test6 2019-02-01T00:37:42Z 2019-02-01T00:37:42Z (null)
Я искал в Интернете похожие вопросы и нашел один из них по переполнению стека здесь , который довольно похож, но, к сожалению, остался без ответа.Заранее благодарен всем, кто попытается ответить на этот вопрос.