简体   繁体   中英

MySQL single query to count rows in multiple date ranges

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

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.

PS 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

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.

Use Union ?

Select a from B
Union
Select B from C
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM