Assuming that there are 6 months of historical data with hundreds of rides per day:
Write a query that returns, for each of the last 90 days, a count of the rides taken in the 7 day window preceding that day
I would like to find a way to write this in MySQL but have had some trouble with having a rolling sum that resets along with how I could cut up timestamps to reflect a day of the year/date and to then group by that.
I have tried writing subqueries that will limit the sum to a week prior and then place an additional limit of 90 days after that but cannot seem to get the code to return any output.
I have tried writing this is PostgreSQL using a sort of "window" functionality but am much more comfortable working in MySQL and would like to be able to solve it that way. I am familiar on how to write limits, group and order among other things but I am having trouble with the rolling sum resetting per week.
Thank you for your help!
First you'll want a numbers table/query. There are some tricky CTE ways to do that but it might be easier for now just to add a table with the numbers 1-90 in 90 rows.
Then use that to generate, for each row, a date range. Sorry if the syntax isn't quite correct, but write a query along the lines:
SELECT num, DATE_ADD(CURRENT_DATE(), INTERVAL -(num+7) DAY) startdate, DATE_ADD(CURRENT_DATE(), INTERVAL -num DAY) enddate FROM numbers
Then you can cross-join that with your rides table grouped on num and counting the rows in the range:
SELECT num, startdate, enddate, SUM(CASE WHEN startdate <= ridedate AND ridedate <=
enddate THEN 1 ELSE 0 END) ridecount
FROM (date range query) dts, rides
GROUP BY dts.num
Hope that helps.
Assuming you have data on each day, a correlated subquery might be simplest approach:
select dt,
(select count(*)
from rides r
where r.ridedate >= d.dte - interval 7 day and
r.ridedate < d.date
) as rolling_7
from (select distinct ridedate as dt
from rides
) dt
Related
I'm currently running the following query to get the daily average of entries per user on my database, it's working as expected but I want to modify it to get the 7 day averages by day.
SELECT
AVG(bg),
AVG(carbs),
timestamp
FROM users_entries
WHERE uid = '10b47fded7d2ea8d' AND
timestamp >= '2019-01-01 00:00:00' AND timestamp <= '2019-01-30 00:00:00'
GROUP BY DAY(timestamp)
So for example, for the time frame, say 2019-01-01 00:00:00 to 2019-06-01 00:00:00 I would like to find all averages for 7 days and list them out. Basically take each day in the time frame, go back 7 days and get the average of the columns I select.
I'm thinking that this would require some sort of subquery but based on what I see online I do not understand them well enough to figure it out on my own, any help would be great.
In MySQL 8+, you can use window functions:
SELECT DATE(timestamp),
AVG(bg),
AVG(carbs),
AVG(AVG(bg)) OVER (ORDER BY DATE(timestamp) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as bg_7,
AVG(AVG(carbs)) OVER (ORDER BY DATE(timestamp) ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as bg_7,
FROM users_entries
WHERE uid = '10b47fded7d2ea8d' AND
timestamp >= '2019-01-01' AND
timestamp < '2019-01-30'
GROUP BY DATE(timestamp);
This is much more challenging in older versions of MySQL.
I put together a query for determining whether the time difference between the current date and a record from a database is exactly a month or more apart. I am comparing now() to a created_at column, which is a timestamp.
EX:
6-12-2014,
7-12-2014
AND
5-12-2014,
7-12-2014
Should be considered to be a desirable results.
SELECT count(*) FROM `subscriptions` WHERE
DATE_ADD(CAST(created_at as DATE),INTERVAL TIMESTAMPDIFF(MONTH, created_at, now()) MONTH) = CAST(now() as DATE);
However the query appears to not return all desired results. It returns 2-28-2014 and 7-28-2014, however it does not pull up 6-28-2014. Is there a better way of doing this than the solution I came up with?
Are you looking to count dates that are on the same day of the month as the current date? If so, try the DAYOFMONTH function:
SELECT COUNT(*)
FROM subscriptions
WHERE DAYOFMONTH(created_at) = DAYOFMONTH(NOW())
I have a table from which I'm trying to extracted summed timediff information grouped by days. I don't really know if this is possible
Table columns: mode_type, start_time.
A record exists in this table for each time an employee starts or stops a timer. mode_type = 1 for start, mode_type = 0 for stop.
I'd like to return a sum of the seconds used for each day in the last 30 days.
E.g:
date, seconds_used
02/04/2014, 25
03/04/2014, 12415
04/04/2014, 925
Currently I can return a list of seconds used per mode_type and date but this required later calc in PHP.
SELECT
mode_type,
Sum(Unix_Timestamp(start_time)) AS time,
start_time
FROM
activations
WHERE
start_time < Date(Now() + INTERVAL 1 MONTH)
GROUP BY
mode_type, Day(start_time)
ORDER BY
start_time
I'm stuck... is this possible or do I need to do revert to calculating the diff in PHP post request?
Thanks in advance.
Can you try with this:
SELECT DATE(start_time) AS startdate, TIME_TO_SEC(TIMEDIFF(NOW(),start_time)) AS secs
FROM activations
GROUP BY
startdate
I am writing a Python code where I need to use MySQLdb to retrieve data from a MySQL database. A part of the original database looks like this:
I used this command
SELECT TimeStamp,Pac
FROM SolarData
WHERE DATE(`TimeStamp`) = CURDATE()
GROUP BY HOUR(TimeStamp);
to group the data by hour, but the result is not what i expected:
The Pac number shown for every hour is the same number as the first record of each hour. It's not an accumulated number for the whole hour. What I need is an accumulated number of the whole hour.
That's because MySQL is like your alcoholic uncle when you don't use GROUP BY by the ANSI standard. You probably want:
SELECT HOUR(TimeStamp) AS Hour,
SUM(Pac) AS Pac
FROM SolarData
WHERE `TimeStamp` >= CURDATE()
AND `TimeStamp` < CURDATE() + INTERVAL 1 DAY
GROUP BY HOUR(TimeStamp);
It would be helpful to see the desired result you're looking for. Until then, the above query is just a guess based on group the data by hour. For future reference, use SQL Fiddle to post your table structure/data.
"How do I decorate the code so that the hour format can have the date on it as well like this 2014-01-14 07:00"
All of Hour belong to today (CURDATE()), and second part is always ':00', so following query might help you. Could try this?
SELECT CONCAT(CURDATE(), ' ', Hour, ':00'), Pac
FROM (
SELECT HOUR(TimeStamp) AS Hour,
SUM(Pac) AS Pac
FROM SolarData
WHERE DATE(`TimeStamp`) = CURDATE()
GROUP BY HOUR(TimeStamp)
) x;
I can normally do this but it appears my brain is not functioning well right now and I'm missing something.
Every day via a cron job that is run at 1am, I want to get a count of rows that were inserted yesterday, and the date.
ie
SELECT DATE(added) as date, COUNT(*) FROM bookings WHERE added = DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP BY date
'added' contains a timestamp ie '2011-04-18 12:31:31'
What am I getting wrong here? I know there are many rows added yesterday but my query is returning 0 results and no mysql_errors :(
Any ideas?
Please try
SELECT DATE(added) as yesterday, COUNT(*) FROM bookings WHERE DATE(added) = DATE(DATE_SUB(NOW(), INTERVAL 1 DAY)) GROUP BY yesterday
or perhaps
SELECT DATE(added) as yesterday, COUNT(*) FROM bookings WHERE DATE(added) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) GROUP BY yesterday
Updated
Corrected the WHERE part.
well whatever NOW() is will return the time portion and unless they were added at exactly that time the day before they wont be counted.
So either use BETWEEN and specify time range, or format the date in your query to only match on the day month year components and not time
WHERE added = does only match exact NOW() - 1 DAY, you should select by a range instead.