我有一张桌子,上面有消息。我想将这些消息分组为对话,检查是否有未读消息并预览最新消息。

我当前的ORM如下所示:

$text = new Model_Text;
$text->select(DB::expr('min(`text`.`read`) AS `read_all`'))
->where('time', '>', $time_offset);
->order_by('read', 'DESC')->order_by('time', 'ASC')
->group_by('contact')->with('user')->find_all();


但是正如您所知,MySQL在订购之前会进行分组,这意味着我没有收到最新消息,而min('text'.'read')技巧可确保我始终知道对话中是否有未读消息。

为了在每次对话中获取最新消息,我将执行以下MySQL查询:

SELECT min(q1.`read`) as read_all, q2.* FROM texts q1
INNER JOIN (
    SELECT * FROM texts ORDER BY time DESC
) q2 ON(q1.contact = q2.contact)
GROUP BY q1.contact
ORDER BY q2.`time` DESC, q2.`read` ASC


但是我完全不知道如何使用ORM最佳实现此查询。

我最好的猜测是直接使用Kohana的DB类执行上述查询,并为返回的每一行加载一个ORM对象。但是,这将导致对于每个已加载到ORM的会话的数据库命中,这是我已经检索到的数据的愚蠢!

让我知道你的想法!

谢谢。

最佳答案

即使您可以正确选择数据,也无法通过ORM类执行此操作,因为Model_Text没有read_all属性,因此您将无法读取数据。

我认为最好的方法是使用两个查询,第一个是获取您感兴趣的对话,即select contact, min(read) as read_all ... where time > $time_offsetgroup by contact。获得联系信息并阅读全部之后,您可以进行另一个查询,以获取每次对话的最新文本,然后按照卡尔的建议将其加载到您的Model_Text中:DB::query(DATABASE::SELECT, $sql)->as_object('Model_Text')->execute()

08-04 13:46