Kohana ORM(自定义查询)与 MySQL ORDER BY & GROUP BY

Posted

技术标签:

【中文标题】Kohana ORM(自定义查询)与 MySQL ORDER BY & GROUP BY【英文标题】:Kohana ORM (custom query) vs MySQL ORDER BY & GROUP BY 【发布时间】:2014-05-16 14:59:01 【问题描述】:

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

我当前的 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 中的每个对话,对于我已经检索到的数据,这将导致一个数据库命中 - 愚蠢!

让我知道你的想法!

谢谢。

【问题讨论】:

您尝试过使用Database_Query#as_object() 吗?例如DB::query(DATABASE::SELECT, $sql)->as_object('YourModelClass')->execute() 【参考方案1】:

使用 ORM 类没有很好的方法来执行此操作,即使您可以正确选择数据,也无法将其读回,因为您的 Model_Text 不具有 read_all 属性。

我认为最好的方法是使用两个查询,第一个是获取您感兴趣的对话,select contact, min(read) as read_all ... where time > $time_offsetgroup by contact。获得联系人和 read_all 后,您可以进行另一个查询,以获取每个对话的最新文本并将其加载到您的 Model_Text 中,如 Carl 建议的那样:DB::query(DATABASE::SELECT, $sql)->as_object('Model_Text')->execute()

【讨论】:

这就是我最终要做的事情。

以上是关于Kohana ORM(自定义查询)与 MySQL ORDER BY & GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章

Kohana ORM,在模型中定义字段

Kohana 3.2 中使用 ORM 模型(结果)的字段的自定义过滤器

Kohana 3 ORM:如何使用 2 个多对多关系执行查询

KOHANA:ORM + MySQL 找不到表

如何在 Kohana 3 ORM 关系中指定两个键

Kohana 3.1 ORM 数据库查询