Search code examples
mysqlmulti-query

Optimize my two queries in to one


I have two tables, one for keep track on chat statistics, and one for keeping track on mail statistics.

My current queries are looking like this:

SELECT COUNT(id) as chat_amount, DATE_FORMAT(timestamp, '%b %e') as period FROM tblChats WHERE timestamp BETWEEN '{$start}' AND '{$end}' AND UserID = 0 GROUP BY DAY(timestamp) DESC, MONTH(timestamp) DESC, YEAR(timestamp) DESC

SELECT COUNT(id) as mail_amount, DATE_FORMAT(timestamp, '%b %e') as period FROM tblMails WHERE timestamp BETWEEN '{$start}' AND '{$end}' AND UserID = 0 GROUP BY DAY(timestamp) DESC, MONTH(timestamp) DESC, YEAR(timestamp) DESC

I would like to merch these two queries in to one so that the returned data is presented like this:

Array ( 
[0] => Array ( 
    [period] => 2012-11-09 
    [chat_amount] => 1500 
    [mail_amount] => 100 
) 
[1] => Array ( 
    [period] => 2012-11-08 
    [chat_amount] => 500 
    [mail_amount] => 350 
) 
[2] => Array ( 
    [period] => 2012-11-07 
    [chat_amount] => 2000 
    [mail_amount] => 1300 
) 
[3] => Array ( 
    [period] => 2012-11-06 
    [chat_amount] => 1000 
    [mail_amount] => 970 
) 

)

How can i achieve something like this? Thank you in advance.


Solution

  • While Saharsh's answer appears to give you the results in the format you want - it's a very expensive query.

    Since you've cited your expected output as a serialized PHP array, this implies that you're using PHP to process the data. A much more efficient approach is to use the following query then merge the data into a PHP array:

     SELECT rtype, DATE_FORMAT(iperiod, '%b %e') AS period, amount
     FROM
     (SELECT 'chat' AS rtype,
       COUNT(id) as amount, 
       DATE(timestamp) as iperiod 
       FROM tblChats 
       WHERE timestamp BETWEEN '{$start}' AND '{$end}' 
       AND UserID = 0 
       GROUP BY DATE(timestamp)
     UNION
       SELECT 'mail' as rtype, 
       COUNT(id) as mail_amount, 
       DATE(timestamp) as iperiod 
       FROM tblMails 
       WHERE timestamp BETWEEN '{$start}' AND '{$end}' 
       AND UserID = 0 
     GROUP BY DATE(timestamp)) ilv
     ORDER BY period DESC;
    

    BTW: DATE_FORMAT(timestamp, '%b %e') will not produce '2012-11-09', and does the DESC modifier work on a GROUP BY expression?