<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Counting associated records</title>
	<atom:link href="http://cakebaker.42dh.com/2008/01/07/counting-associated-records/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Sat, 13 Mar 2010 15:19:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: cakebaker</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-148604</link>
		<dc:creator>cakebaker</dc:creator>
		<pubDate>Fri, 26 Feb 2010 15:48:41 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-148604</guid>
		<description>@neudor: Yes, this is a more efficient approach than what I described in the article. Thanks for mentioning it!</description>
		<content:encoded><![CDATA[<p>@neudor: Yes, this is a more efficient approach than what I described in the article. Thanks for mentioning it!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: neudor</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-148498</link>
		<dc:creator>neudor</dc:creator>
		<pubDate>Fri, 26 Feb 2010 05:05:26 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-148498</guid>
		<description>Hey there. There is another very useful way to retrieve the number of associated records.
I did this for Posts and Comments, but in my case their names are Threads and Messages

&lt;code&gt;
$this-&gt;Thread-&gt;recursive = -1;
$threads = $this-&gt;paginate(&#039;Thread&#039;);
$this-&gt;set(&#039;threads&#039;, $threads);
    
$thread_ids = array();
for($i=0; $i&lt;count($threads); $i++) {
    $thread_ids[] = $threads[$i][&#039;Thread&#039;][&#039;id&#039;];
}
    
$this-&gt;Message-&gt;recursive = -1;
$messages = $this-&gt;Message-&gt;find(&#039;all&#039;, array(
    &#039;conditions&#039; =&gt; array(
        &#039;Message.created &lt;=&#039; =&gt; date(&quot;Y-m-d H:i:s&quot;),
        &#039;thread_id&#039; =&gt; $thread_ids
    ),
    &#039;group&#039; =&gt; &#039;Message.thread_id&#039;,
    &#039;fields&#039; =&gt; array(&#039;thread_id&#039;, &#039;COUNT(*) as `count`&#039;)
));
$count = array();
for($i=0; $i&lt;count($messages); $i++) {
    $count[$messages[$i][&#039;Message&#039;][&#039;thread_id&#039;]] = $messages[$i][&#039;0&#039;][&#039;count&#039;];
}
    
for($i=0; $i&lt;count($threads); $i++)  {
    $id = $threads[$i][&#039;Thread&#039;][&#039;id&#039;];
    $threads[$i][&#039;Thread&#039;][&#039;messages_count&#039;] = $count[$id];
}
    
debug($threads);
&lt;/code&gt;

This approach requires only two queries in any case.</description>
		<content:encoded><![CDATA[<p>Hey there. There is another very useful way to retrieve the number of associated records.<br />
I did this for Posts and Comments, but in my case their names are Threads and Messages</p>
<pre><code>$this-&gt;Thread-&gt;recursive = -1;
$threads = $this-&gt;paginate('Thread');
$this-&gt;set('threads', $threads);
    
$thread_ids = array();
for($i=0; $i&lt;count($threads); $i++) {
    $thread_ids[] = $threads[$i]['Thread']['id'];
}
    
$this-&gt;Message-&gt;recursive = -1;
$messages = $this-&gt;Message-&gt;find('all', array(
    'conditions' =&gt; array(
        'Message.created &lt;=' =&gt; date("Y-m-d H:i:s"),
        'thread_id' =&gt; $thread_ids
    ),
    'group' =&gt; 'Message.thread_id',
    'fields' =&gt; array('thread_id', 'COUNT(*) as `count`')
));
$count = array();
for($i=0; $i&lt;count($messages); $i++) {
    $count[$messages[$i]['Message']['thread_id']] = $messages[$i]['0']['count'];
}
    
for($i=0; $i&lt;count($threads); $i++)  {
    $id = $threads[$i]['Thread']['id'];
    $threads[$i]['Thread']['messages_count'] = $count[$id];
}
    
debug($threads);</code></pre>
<p>This approach requires only two queries in any case.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cakebaker</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-137778</link>
		<dc:creator>cakebaker</dc:creator>
		<pubDate>Thu, 08 Oct 2009 14:56:41 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-137778</guid>
		<description>@Will: Hm, it seems like your comment got eaten by Wordpress :&#124;</description>
		<content:encoded><![CDATA[<p>@Will: Hm, it seems like your comment got eaten by Wordpress :|</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Will</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-137758</link>
		<dc:creator>Will</dc:creator>
		<pubDate>Thu, 08 Oct 2009 06:46:01 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-137758</guid>
		<description>or, 

echo count($post[&#039;ApprovedComment&#039;])

?</description>
		<content:encoded><![CDATA[<p>or, </p>
<p>echo count($post['ApprovedComment'])</p>
<p>?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cakebaker</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-55514</link>
		<dc:creator>cakebaker</dc:creator>
		<pubDate>Thu, 10 Jan 2008 18:36:04 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-55514</guid>
		<description>@Brandon: Good question. From a logical point of view it is the appropriate place, and in a company I worked some years ago we used stored procedures for almost everything (with MS SQL server). But in the meantime I don&#039;t use stored procedures anymore, as it is much easier to implement this logic on the model level instead of the database level. You don&#039;t have to learn a new language, and you can use the tools you are used to (at least with SQL server it was a pain to write stored procedures *g*).</description>
		<content:encoded><![CDATA[<p>@Brandon: Good question. From a logical point of view it is the appropriate place, and in a company I worked some years ago we used stored procedures for almost everything (with MS SQL server). But in the meantime I don&#8217;t use stored procedures anymore, as it is much easier to implement this logic on the model level instead of the database level. You don&#8217;t have to learn a new language, and you can use the tools you are used to (at least with SQL server it was a pain to write stored procedures *g*).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon P</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-55241</link>
		<dc:creator>Brandon P</dc:creator>
		<pubDate>Wed, 09 Jan 2008 20:53:12 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-55241</guid>
		<description>Sorry, callbacks = triggers :) Got CakePHP on the brain</description>
		<content:encoded><![CDATA[<p>Sorry, callbacks = triggers :) Got CakePHP on the brain</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon P</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-55240</link>
		<dc:creator>Brandon P</dc:creator>
		<pubDate>Wed, 09 Jan 2008 20:52:54 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-55240</guid>
		<description>@cakebaker:
What is your opinion on using this kind of functionality at the database level (stored procedures, callbacks, etc)?  Seems to me that is the most appropriate place.</description>
		<content:encoded><![CDATA[<p>@cakebaker:<br />
What is your opinion on using this kind of functionality at the database level (stored procedures, callbacks, etc)?  Seems to me that is the most appropriate place.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cakebaker</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-54848</link>
		<dc:creator>cakebaker</dc:creator>
		<pubDate>Tue, 08 Jan 2008 18:43:48 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-54848</guid>
		<description>@all: Thanks for your comments!

@Simon: Yes, your code snippet is more efficient than what I wrote.

@Ivo, Michal, GreyCells: To make it work with GROUP BY I have to use a manual query as CakePHP no longer uses a join:
&lt;pre&gt;
$this-&gt;execute(&#039;SELECT Post.*, COUNT(Comment.id) AS comment_count FROM posts AS Post LEFT OUTER JOIN comments AS Comment ON Comment.post_id = Post.id GROUP BY Post.id&#039;);
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>@all: Thanks for your comments!</p>
<p>@Simon: Yes, your code snippet is more efficient than what I wrote.</p>
<p>@Ivo, Michal, GreyCells: To make it work with GROUP BY I have to use a manual query as CakePHP no longer uses a join:</p>
<pre>
$this-&gt;execute('SELECT Post.*, COUNT(Comment.id) AS comment_count FROM posts AS Post LEFT OUTER JOIN comments AS Comment ON Comment.post_id = Post.id GROUP BY Post.id');
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: GreyCells</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-54668</link>
		<dc:creator>GreyCells</dc:creator>
		<pubDate>Tue, 08 Jan 2008 09:39:18 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-54668</guid>
		<description>To use GROUP BY in a $conditions array:

$conditions = array(&#039;Post.id&#039; =&gt; 42, &#039;1=1 GROUP BY Post.id);

I think the same applies to HAVING (i.e. &#039;1=1 HAVING count(Comment.id) &gt; 5)</description>
		<content:encoded><![CDATA[<p>To use GROUP BY in a $conditions array:</p>
<p>$conditions = array(&#8216;Post.id&#8217; =&gt; 42, &#8216;1=1 GROUP BY Post.id);</p>
<p>I think the same applies to HAVING (i.e. &#8216;1=1 HAVING count(Comment.id) &gt; 5)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michał Bachowski</title>
		<link>http://cakebaker.42dh.com/2008/01/07/counting-associated-records/comment-page-1/#comment-54635</link>
		<dc:creator>Michał Bachowski</dc:creator>
		<pubDate>Tue, 08 Jan 2008 08:14:01 +0000</pubDate>
		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/01/07/counting-associated-records/#comment-54635</guid>
		<description>Hi,

I agree with Ivo - approach with GROUP BY is much faster.
I usually write more complex queries by myself - I don`t try to fit the query to CakePHP manner.

BTW: if you use PostgreSQL, you can write:
‘COUNT(Comment.id) as Post__comment_count’

And CakePHP will parse the column to own array format automaticaly.

Regards</description>
		<content:encoded><![CDATA[<p>Hi,</p>
<p>I agree with Ivo &#8211; approach with GROUP BY is much faster.<br />
I usually write more complex queries by myself &#8211; I don`t try to fit the query to CakePHP manner.</p>
<p>BTW: if you use PostgreSQL, you can write:<br />
‘COUNT(Comment.id) as Post__comment_count’</p>
<p>And CakePHP will parse the column to own array format automaticaly.</p>
<p>Regards</p>
]]></content:encoded>
	</item>
</channel>
</rss>
