Thanks a heap! Yes, it was UNION I was trying (and failing) to
conceptualize. I always forget about that one.

But, I came up with another solution. First, I needed to adjust the
query to better work across several years. The MySQL manual mentions
using partial dates, eg. '2009-07-00' where a more precise date is
unknown or unnecessary. I need to group by month AND year so I changed
MONTHNAME() to:

DATE(CONCAT_WS('-', YEAR(in_date), MONTH(in_date), '01'))

I created a function:

CREATE FUNCTION YEARMONTH (in_date DATE) RETURNS DATE LANGUAGE SQL
BEGIN
        RETURN DATE(CONCAT_WS('-', YEAR(in_date), MONTH(in_date), '01'));
END

Then I used a correlated subquery:

SELECT
COUNT(*) AS num_logins,
YEARMONTH(l.created) AS month,
(SELECT
COUNT(*) FROM downloads AS d
WHERE YEARMONTH(d.created) = month
) AS num_downloads
FROM logins AS l
GROUP BY month
ORDER BY month DESC;

Thanks again for the hint.

On Sun, Jul 12, 2009 at 7:50 PM, Martin Radosta<[email protected]> wrote:
> On 07/12/2009 07:16 PM, Martin Radosta wrote:
>
> On 07/11/2009 02:06 PM, brian wrote:
>
> I have a StatsController with which I'd like to make a summary of all
> logins and all downloads for each month.
>
> class Login extends AppModel
> {
>     public $belongsTo = array('User');
>     public $hasMany = array('Download');
> }
>
> class Download extends AppModel
> {
>     public $belongsTo = array(
>         'ItemFile', 'User', 'Login'
>     );
> }
>
> I can easily create separate queries but would need to merge them. i
> haven't been able to figure that part out.
>
> public function admin_summary()
> {
>     $logins = $this->Login->find(
>         'all',
>         array(
>             'fields' =>  array(
>                 'MONTHNAME(created) AS month',
>                 'COUNT(*) AS num_logins'
>             ),
>             'recursive' =>  -1,
>             'group' =>  array('month')
>         )
>     );
>     $downloads = $this->Download->find(
>         'all',
>         array(
>             'fields' =>  array(
>                 'MONTHNAME(created) AS month',
>                 'COUNT(*) AS num_downloads'
>             ),
>             'recursive' =>  -1,
>             'group' =>  array('month')
>         )
>     );
>     // ...
> }
>
> This gives me:
>
> Array
> (
>     [0] =>  Array
>     (
>         [Login] =>  Array
>         (
>             [month] =>  July
>             [num_logins] =>  16
>         )
>     )
>     [1] =>  Array
>     (
>         [Login] =>  Array
>         (
>             [month] =>  June
>             [num_logins] =>  168
>         )
>     )
>     [2] =>  Array
>     (
>         [Login] =>  Array
>         (
>             [month] =>  May
>             [num_logins] =>  64
>         )
>     )
> )
>
>
> app/controllers/stats_controller.php (line 171)
>
> Array
> (
>     [0] =>  Array
>     (
>         [Download] =>  Array
>         (
>             [month] =>  July
>             [num_downloads] =>  11
>         )
>     )
>     [1] =>  Array
>     (
>         [Download] =>  Array
>         (
>             [month] =>  June
>             [num_downloads] =>  367
>         )
>     )
>     [2] =>  Array
>     (
>         [Download] =>  Array
>         (
>             [month] =>  May
>             [num_downloads] =>  15
>         )
>     )
> )
>
> What I'm after is something like:
>
> Array
> (
>     [0] =>  Array
>     (
>         'July' =>  array(
>             'Download' =>  Array
>             (
>                 'num_downloads' =>  11
>             ),
>             'Login' =>  Array
>             (
>                 'num_logins' =>  16
>             )
>         )
>     )
>     ...
> )
>
> or even ...
>
> Array
> (
>     [0] =>  Array
>     (
>         'July' =>  array(
>             'Download' =>  11,
>             'Login' =>  16
>         )
>     )
>     ...
> )
>
>
> Incidentally, I've been tryng to figure out a way to do this in a
> single query (MySQL) but I get strange results:
>
> mysql>  SELECT MONTHNAME(created) AS month, COUNT(*) AS num_logins FROM
> logins GROUP BY month;
> +-------+------------+
> | month | num_logins |
> +-------+------------+
> | July  |         15 |
> | June  |        168 |
> | May   |         64 |
> +-------+------------+
> 3 rows in set (0.00 sec)
>
> mysql>  SELECT MONTHNAME(created) AS month, COUNT(*) AS num_downloads
> FROM downloads GROUP BY month;
> +-------+---------------+
> | month | num_downloads |
> +-------+---------------+
> | July  |            11 |
> | June  |           367 |
> | May   |            15 |
> +-------+---------------+
> 3 rows in set (0.00 sec)
>
> mysql>  SELECT MONTHNAME(l.created) AS month, COUNT(l.id) AS
> num_logins, COUNT(d.id) AS num_downloads FROM logins AS l LEFT JOIN
> downloads AS d ON d.login_id = l.id GROUP BY month;
> +-------+------------+---------------+
> | month | num_logins | num_downloads |
> +-------+------------+---------------+
> | July  |         20 |            11 |
> | June  |        477 |           367 |
> | May   |         71 |            15 |
> +-------+------------+---------------+
> 3 rows in set (0.23 sec)
>
> I figure it's because month is related to logins, not downloads.
> However, it seems odd that it's the login numbers that are wonky, not
> downloads. If anyone can think of a way to do this in one query I'd
> really appreciate it.
>
>
>
>
>
> Try this and let me know if it works:
>
> SELECT MONTHNAME(l.created) AS month, COUNT(l.id) AS
> num_logins, COUNT(d.id) AS num_downloads FROM logins AS l INNER JOIN
> downloads AS d ON d.login_id = l.id GROUP BY month;
>
>
>
>
> Sorry, did'nt read your problem in detail, try this query:
>
> SELECT MONTH , min( num_downloads ) AS num_downloads, min( num_logins ) AS
> num_logins
> FROM (
> SELECT MONTHNAME( created ) AS
> MONTH , COUNT( 1 ) AS num_downloads, NULL AS num_logins
> FROM downloads
> GROUP BY MONTH
> UNION
> SELECT MONTHNAME( created ) AS
> MONTH , NULL AS num_downloads, COUNT( 1 ) AS num_logins
> FROM logins
> GROUP BY MONTH
> ) AS q
> GROUP BY MONTH
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to