2016-02-12 83 views
0

原始的SQL查詢:我怎樣才能以cakephp-3的方式寫這個查詢?

SELECT * 
FROM 
    (SELECT p.id, 
      p.title, 
      p.mark, 

    (SELECT max(created) 
     FROM comments c 
     WHERE c.post_id=p.id 
     AND c.mark=1) AS latest_at 
    FROM posts p) AS Post 
WHERE Post.latest_at IS NOT NULL 
ORDER BY latest_at DESC LIMIT 10 

我有這兩個表:

$postsTable = TableRegistry::get('Posts'); 
$comments = TableRegistry::get('Comments'); 

我已經在CakePHP中-3方式進行內部查詢:

SELECT p.id, 
     p.title, 
     p.mark, 
     (SELECT max(created) 
      FROM comments c 
      WHERE c.post_id=p.id AND c.mark=1) AS latest_at 
     FROM posts p 

CakePHP的-3方式的內sql與cakephp-3 querybuilder(下面的查詢是否正確?):

 $subquery = $comments->find(); 
     $subquery->select([$subquery->func()->max('created')]) 
       ->from(['c'=>'comments']) 
       ->where(['c.post_id=p.id','mark=1']); 

     $pquery = $postsTable->find() 
     ->select(['p.id','p.title','p.mark','latest_at'=>$subquery]) 
     ->from(['p'=>'posts']); 

我怎樣才能以cakephp-3的方式寫外部選擇查詢? (select * from(derived table))

在此先感謝。任何答案將不勝感激。

+1

這可以幫助你http://book.cakephp.org/3.0/en/orm/query-builder.html – JayIsTooCommon

回答

2

直接回答你的問題,這就是如何在使用子查詢另一個查詢的一部分:

$query = $this->MyTable->connection()->newQuery(); 
$query->select('*')->from(['Post' => $subqueryObject])->fetchAll('assoc'); 

這將返回結果數組,如果你知道它是什麼類型的實體應該是保溼來,那麼這樣做:

$query = $this->Posts 
    ->find() 
    ->select($listOfFields) 
    ->from(['Posts' => $subqueryObject], true) 
    ->toArray(); 
-1

對於特殊情況,cakephp允許您編寫RAW SQL並保持cakephp方式。只需在你的模型中創建一個函數,你可以通過將它放在$this->query("...")中來以這種方式編寫該查詢。

實施例(在模型):

public function getPosts(){ 
     $this->query("SELECT * FROM Posts AS Post"); //put complext query here 
} 

然後,在控制器:

$posts = $this->Post->getPosts(); 
1

這是一個非常複雜的解決方案,以一種非常簡單的問題(即獲得了最新的評論的信息)。

一個更好的查詢是:

select posts.* from posts join comments on (comments.post_id = posts.id) group by posts.id order by comments.created desc limit 1 

做此查詢的ORM的方法是:

$post = $postsTable 
    ->find() 
    ->select(['Posts.id', 'Posts.title', 'Posts.mark', 'Comments.created']) 
    ->leftJoinWith('Comments', function ($q) { 
     return $q->where(['Comments.mark' => true]); 
    })) 
    ->group(['Posts.id']) 
    ->order(['Comments.created' => 'desc']) 
    ->first(); 
+0

您的查詢不返回預期的結果。它不會返回與我的sql查詢相同的結果。我的查詢返回預期的結果。這是因爲你通過'posts.id'分組,然後'通過comments.created排序'。它帶有一篇文章的第一條評論。一篇文章有​​多條評論。您必須先以最新的日期發表評論,這意味着該帖子的最後評論。 – shibly

+0

看到這個:http://stackoverflow.com/questions/35394034/how-can-i-write-equivalent-sql-query-with-join – shibly