我有一个消息表。
+----+---------+----------+
| id | conv_id | body |
+----+---------+----------+
| 1 | 1 | haha |
| 2 | 1 | blabl|
| ...| ... | ... |
| 25| 2 | hehe |
+----+---------+----------+
... =其余的消息,其中conv_id为2或1或3或n。
假设我有conv_id = array(2,1)
,我希望在与conv_id
中的一系列ID匹配后获取10条消息,所以我做了
select * from `messages` where `conv_id` in (2, 1) order by `created_at` desc limit 10
上面的sql给了我10条消息 匹配conv_ids并获取所有组合消息。但是,这是我想要的 NOT 。相反,我想要10条消息的每个 conv_id匹配。
我如何获得10条的每条转化符号?请不要PHP for循环。谢谢!
注意:数组conv_id可以轻松扩展,以包含彼此独有的许多其他值,而不仅仅是2或1。
奖励积分!以下是详细信息:
Messages::with('User')->whereIn('conv_id',$conv_id)->orderBy('created_at','desc')->take(10);
答案 0 :(得分:1)
我认为Jared是对的但是如果你可以在表中添加另一列,解决方案会更有效率。添加一个列,指示每个conv_id的消息编号(最早将有1,最新的将具有会话消息的数量)。之后,您可以使用HAVING
子句扫描表格两次来实现目标。
SELECT * FROM messages JOIN
(SELECT conv_id, MAX(msg_no) FROM messages WHERE conv_id IN (2,1) GROUP BY conv_id) as M
ON messages.conv_id=M.conv_id HAVING messages.msg_no > M.msg_no-10
答案 1 :(得分:1)
另一种可能性。使用group_concat - substring_index技巧获取最后一个conv_ids及其第10个(消息)id,并重新加入message-table。
SELECT `messages`.*
FROM (
SELECT
conv_id,
substring_index(
substring_index(
group_concat(`messages`.id),
',',
10
),
',',
-1
) AS lastMessageId
FROM `messages`
WHERE `conv_id` in (2, 1)
GROUP BY `conv_id`
) AS msub
INNER JOIN `messages` ON `messages`.conv_id = msub.conv_id AND `messages`.id <= msub.lastMessageId
答案 2 :(得分:0)
警告:此方法可能有误。我试图对其进行验证,并在得出结论后对其进行更新
昨天我刚从deczo Getting just the latest value on a joined table with Eloquent的答案中学到了关于雄辩关系的新内容。而且我认为我们也可以根据你的情况调整它。
你本来想要做的事情,我把我的观点视为:
在Eloquent中,我可能会按照以下方式做点什么:
Conversation::with('messages')->whereIn('conv_id', [1, 2])->get();
但我注意到你的两个问题。
所以我决定这里应该是两个模型,一个叫做Message,另一个叫做Conversation。
两者都调用同一个表,但我们会告诉Eloquent使用不同的列作为主键。
因此,为了获得对话模型,我在我的newQuery函数中添加了distinct()
,并仅选择conv_id
,因为这是关于对话的唯一信息。
所以最后我有这个:
<强>模型/ Message.php 强>
class Message extends Eloquent
{
protected $table = 'messages';
protected $primaryKey = 'id';
public $timestamps = false;
}
<强>模型/ Conversation.php 强>
class Conversation extends Eloquent
{
protected $table = 'messages';
protected $primaryKey = 'conv_id';
public $timestamps = false;
public function newQuery($excludeDeleted = true)
{
return parent::newQuery()
->select('conv_id')
->distinct();
}
public function messages()
{
return $this->hasMany('Message', 'conv_id')
->orderBy('id', 'desc')
->take(10);
}
}
现在我能做到:
Conversation::with('messages')->whereIn('conv_id', [1, 2])->get();
它为我提供了conv_id
1和2的对话列表,以及每个对话的10条最新消息。
这是我第一次这样做。所以我进行了代码测试,但它确实有效。
更新:我的回答中的代码只执行这两个查询(从DB :: getQueryLog()检索):
select distinct `conv_id` from `messages` where `conv_id` in (?, ?);
select * from `messages` where `messages`.`conv_id` in (?, ?) order by `id` desc limit 10;