Search code examples
mysqlsymfony1propel

Sql query (inner join + count + group by) using Propel


I want to show the number of comments for each blog post (along with category, date, author etc) on a page that has a list of blog posts. How do i write the following mysql query in propel?

SELECT post.id, post.title, post.more_columns , COUNT(comments.post_id) AS numofcomments FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id, post.title, post.more_columns

where post is a blog table and comments, a table of comments with post_id as a foreign key to post.id. I cant seem to get 'numofcomments' as a column in the resultset. Currently i am using a non-ORM approach (which will be my last resort):

$con = Propel::getConnection(PostPeer::DATABASE_NAME);

    $sql = "SELECT post.* , COUNT(comments.post_id) AS numcomments FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id";  
    $stmt = $con->prepare($sql);
    $stmt->execute();

    $result = PostPeer::populateObjects($stmt);
    return $result;

How can i access 'numofcomments' in the resulting Propel resultset?

EDIT: What i wanted to know is how i can write the above query in Propel? What i can do now is get the post table with inner join on comments table and then run doCount on comments table for each post-id. This results in 1 query for Post table and many queries for comments table. I wish to reduce the sql queries to a minimum. Thanks :)


Solution

  • Well this is what worked but its a sad way to do it :|

    //inside a static function in class PostPeer:
    $c = new Criteria();
    self::addSelectColumns($c); //add all columns from PostPeer
    $c->addJoin(PostPeer::ID, CommentPeer::POST_ID, Criteria::LEFT_JOIN);
    $cu->addAsColumn('numofcomments', 'COUNT('.CommentPeer::POST_ID.')');
    $cu->addGroupByColumn(PostPeer::ID);
    $cu->addGroupByColumn(PostPeer::TITLE);
    :
    :
    //more group-by columns if needed
    return PostPeer::doSelectStmt($c);
    

    Then in template i access the array as:

    <div id="title">
       <?php echo post_array[1] ?>
    </div>
    //...and so on for other Post fields
    

    How do i make an array association in model so that i can write "post_array['title']" in template instead of "post_array[1]"? Also, is this workaround secure? Any better suggestion. I am using Propel 1.3