Reputation: 1348
I have to count the rows in several date ranges (today, week, month) from a mysql table.
Currently I am running through a loop in my PHP script and doing an individual query for each date range, which I know is a bad idea.
<?php
$now = "2016-04-21";
$today = $now;
$week = date( 'Y-m-d', strtotime( '-7 day', strtotime( $now ) ) );
$month = substr( $now, 0, 7 );
$res1 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND DATE_FORMAT( date, '%Y-%m-%d' ) = '$today'" );
$res2 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND ( t.date BETWEEN ( '$week' ) AND ( '$today' ) )");
$res3 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND DATE_FORMAT( t.date, '%Y-%m' ) = '$month'" );
So I would like to use a SINGLE QUERY to do so.
I have found count rows in multiple date ranges and query for grabbing multiple date ranges but I'm not sure which is the best, and how to do in my case
Upvotes: 0
Views: 1376
Reputation: 1866
You can combine all your conditions by OR
to select all data in one query. And this construction can be used in SELECT
to sum rows that meet some condition
SUM(IF(condition, sum_column_name, 0))
Your query can look like this if you want to return one row with three sums
SELECT
SUM(IF(t.date = '$today', pageview, 0)) AS pageview_today,
SUM(IF(t.date BETWEEN '$week' AND '$today', pageview, 0)) AS pageview_week,
SUM(IF(DATE_FORMAT(t.date, '%Y-%m') = '$month', pageview, 0)) AS pageview_month
FROM statistics t
WHERE user = '$id' AND (
t.date = '$today'
OR (t.date BETWEEN '$week' AND '$today')
OR DATE_FORMAT(t.date, '%Y-%m') = '$month'
)
Or you can make 3 queries and combine them with UNION
as was mentioned by @quazardous. And this method will give you 3 different rows.
Upvotes: 1
Reputation: 1408
If you really want to retrieve the three values using one query:
$res = mysql_query("
SELECT sum1, sum2, sum3
FROM (SELECT SUM(pageview) AS sum1 FROM statistics WHERE user = '$id' AND DATE_FORMAT( date, '%Y-%m-%d' ) = '$today') AS T1
JOIN (SELECT SUM(pageview) AS sum2 FROM statistics WHERE user = '$id' AND ( t.date BETWEEN ( '$week' ) AND ( '$today' ) )) AS T2
JOIN (SELECT SUM(pageview) AS sum3 FROM statistics WHERE user = '$id' AND DATE_FORMAT( t.date, '%Y-%m' ) = '$month') AS T3");
Although this is not much better performance wise, i don't really see a reason to do this.
P.S. it's a bad habit to insert variables into queries like this. In this case your safe but if you use user inputted variables you're open to SQL injection. Try learning prepared statements
Upvotes: 1