2014-05-16 39 views
0

我有一個包含消息的表。我想將這些消息分組爲對話,檢查是否有未讀消息和預覽最新消息。Kohana ORM(自定義查詢)vs MySQL ORDER BY&GROUP BY

我現在的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中的每個對話都會觸發一次數據庫,因爲我已經檢索到了數據 - 這很愚蠢!

讓我知道你的想法!

謝謝。

+0

您是否嘗試過使用['Database_Query#as_object()'] (http://kohanahanaworkwork.org/3.2/guide/api/Database_Query#as_object)?例如'DB :: query(DATABASE :: SELECT,$ sql) - > as_object('YourModelClass') - > execute()' –

回答

0

即使您可以正確選擇數據,也沒有一種方法可以對ORM類執行此操作,因爲您的Model_Text不具有read_all屬性,您將無法讀取它。

我認爲最好的辦法是用兩個查詢,第一個是獲得您感興趣的對話,select contact, min(read) as read_all ... where time > $time_offsetgroup by contact。一旦你有聯繫和read_all,你可以進行另一個查詢,獲取每個對話的最新文本,並按照Carl的建議將其加載到您的Model_Text中:DB::query(DATABASE::SELECT, $sql)->as_object('Model_Text')->execute()

+0

這就是我最終做的事情。 – Zoon