【发布时间】:2019-02-01 02:13:40
【问题描述】:
我有两张桌子:
线程
id, created_at, updated_at, deleted_at
消息
id, thread_id, user_id, created_at, updated_at, deleted_at
这是我创建的用于建立这种关系的 SQL Fiddle 的链接:
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');
}
Message Model 对于 Thread 有这种关系:
/**
* Thread relationship.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*
*/
public function thread()
{
return $this->belongsTo(Thread::class, 'thread_id', 'id');
}
我首先运行一个查询来获取特定用户的所有线程。获得所有线程后,我将每个线程的 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);
假设我想获取 id 为 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)
我在网上查找了类似的问题,并在堆栈溢出here 上找到了一个非常相似的问题,但不幸的是没有得到答复。提前感谢任何试图回答这个问题的人。
【问题讨论】:
-
线程和消息的关系是什么?在 Model 中有你的集合 hasMany 或 belongsTo? laravel.com/docs/5.7/eloquent-relationships
-
@LimKeanPhang ,是的,模型中的关系是 hasMany 和 belongsTo,我已经更新了我的问题以显示模型中的关系。
-
@Strawberry 我相信我正在关注你的所有 3 件很高兴看到的事情,我解释了我有
Message::whereIn('thread_id', $threadIds)的工作查询,我正在寻求帮助来改进它。 -
@Strawberry 很抱歉造成混淆,我已经添加了一个指向我刚刚创建的 SQL 小提琴的链接,它构建了 2 个表,添加了一些示例数据,并且我添加了我目前正在使用的 SQL 语句使用。感谢您的信息,这是我第一次在 SO 上发布 PHP / SQL 问题。
-
sqlfiddle.com/#!9/915829/5 - 请注意,您的第一个查询可能是不必要的。查看联接
标签: php mysql laravel eloquent