3

I seem to be having a bit of trouble coming up a query to achieve what I want. I have a table like the following..

| Date(TIMESTAMP)     | Count |
|---------------------|-------|
| 2016-02-01 01:00:00 | 52    |
| 2016-01-05 11:30:00 | 14    |
| 2016-02-01 04:20:00 | 36    |
| ...                 | ...   |

The table has about 40,000 rows. What I would like to do is grab the totals for multiple date ranges so I end up with the following...

| Period     | Total |
|------------|-------|
| All        | 10245 |
| Past year  | 1401  |
| Past month | 104   |
| Past week  | 26    |

Currently I am running through a loop in my PHP script and doing an individual query for each date range I'm looking for. Actually there are about 10 queries I'm doing per loop to grab different stats but for the example I'm simplifying it. This takes forever and I am hoping there is a more elegant way to do this, however I've spent quite a bit of time now trying different things and researching and have gotten nowhere. I understand how to use CASE to group but not when a record may need to be in multiple bins. Any help?

user1456456
  • 33
  • 1
  • 4

3 Answers3

0

Try this UNION query:

SELECT 'All', COUNT(*) AS Total FROM yourTable
UNION
SELECT 'Past year', COUNT(*) AS Total
FROM yourTable
WHERE DATE(TIMESTAMP) > DATE_ADD(NOW(), INTERVAL -1 YEAR)
UNION
SELECT 'Past month', COUNT(*) AS Total
FROM yourTable
WHERE DATE(TIMESTAMP) > DATE_ADD(NOW(), INTERVAL -1 MONTH)
UNION
SELECT 'Past week', COUNT(*) AS Total
FROM yourTable
WHERE DATE(TIMESTAMP) > DATE_ADD(NOW(), INTERVAL -1 WEEK)
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
0

1st. get known to function getting first date of year, first date of month and first date of week. Then compose your sql using count and filter with first and last date of different period.

ref:

MySQL Select First Day of Year and Month

month https://stackoverflow.com/a/19259159/1258492

week https://stackoverflow.com/a/11831133/1258492

select 'All' as period, count(1) from 
tbl
union

select 'Past Year' as period, count(1) from 
tbl
where timestamp between 
MAKEDATE(year(now())-1,1) and
last_day(MAKEDATE(year(now())-1,1) + interval 11 month)

union 

select 'Past Month' as period, count(1) from 
tbl
where timestamp between 
LAST_DAY(NOW() - INTERVAL 2 MONTH) + INTERVAL 1 DAY and
LAST_DAY(NOW() - INTERVAL 1 MONTH)

union 
select 'Past Week' as period, count(1) from 
tbl 
where timestamp between 
adddate(curdate(), INTERVAL 1-DAYOFWEEK(curdate())-7 DAY)  and
adddate(curdate(), INTERVAL 7-DAYOFWEEK(curdate())-7 DAY) ;
Community
  • 1
  • 1
RAY
  • 2,201
  • 2
  • 19
  • 18
0

You may use subqueries. Use one subquery per time breakdown like so:

SELECT everything, 'past year'
FROM 
    (
     SELECT sum(c) AS 'everything' 
     FROM reports
    ) t1,
    (
    SELECT sum(c) AS 'past year'  
    FROM reports
    WHERE d  >= DATE_ADD(CURDATE(), INTERVAL -1 YEAR)
    ) t2
Jeff H
  • 138
  • 1
  • 6