mysql query for elapsed time per day - mysql

I have such this table as below and I trying to calculate the elapsed time for which the value "relay" is to 1 per day by creating a view.
id, date, time, dateandtime,timestamp,sensor,temperature,humidity,status
xx 15/03/2018 11:39:00 15/03/2018 11:39:00.0 15/03/2018 11:39 sensor1 23 41 0
xx 15/03/2018 11:40:00 15/03/2018 11:40:00.0 15/03/2018 11:39 sensor2 23 41 1
Here is the query that I come with, however the output is not as except for the past or previous day...
select date,time,TIMESTAMPDIFF(MINUTE,MAX(Date), timestamp) as minutes FROM temperaturedata where relay = 1 group by date
Here is the results:
date time minutes
2018-03-15 11:39:00 699
2018-03-16 11:01:00 661
Some clarifications, I am trying to get how long per day and hour the status has been set to 1.
something like:
date, starttime, endtime, minutes;
As starttime would be when the first of instance to 1 appears and endtime the last time, minutes the total amount of minutes for which the status was to 1.
hope it make a bit more sense. :)
Any guidance would be more than welcome.
THanks.
J.

Related

MySQL, grouping by and performing a SUM within the groups

The table below contains records of shifts which have taken place. The start and end fields are the start and end timestamps of those shifts. I'm looking to build a query that will extract the total hours per month that the shifts cover.
Example table:
ID Start End
1 2018-10-23 10:30:00 2018-10-23 11:45:00
2 2018-10-22 22:00:00 2018-10-22 23:00:00
3 2018-11-22 22:00:00 2018-11-22 23:00:00
The ideal output would read:
Month Hours
10 2:15
11 1:00
I've got some of the elements worked out, using a SUM(timediff(end,start)) and GROUP BY, but havn't managed to get something good out!
Thanks!
Here you go:
select
month(start) as month,
time_format(sec_to_time(
sum(timestampdiff(second, start, end))
), '%H:%i') as hours,
sum(timestampdiff(second, start, end)) as seconds
from shift
group by month(start)
Result:
month hours seconds
----- ----- -------
10 02:15 8,100
11 01:00 3,600
Note: I added the extra column seconds in case you want to use this numeric value to do some extra processing.

Find the rate for given date from mysql table

I have a table:
adate pdt_id pdt_rate
2017-10-02 5 20
2017-10-05 5 25
2017-10-07 5 23
2017-10-11 5 20
I have to find the rate of product with pdt_id 5 for between dates 2017-10-01 and 2017-10-10
For 2017-10-01 there is no rate in table so I take the lesser date like 2017-09-30 (no record), 2017-09-29 (no record) and so on (unfortunately no record). So I turn the bigger date than 2017-10-01 is 2017-10-02 (yes, there is a record) so I stop the searching and finalize as
2017-10-01 rate is 20
Now find the next date 2017-10-02, there is record and is 20
2017-10-02 rate is 20
Following the similar criteria I got
2017-10-03 rate is 20
2017-10-04 rate is 20
2017-10-05 rate is 25
....
2017-10-10 rate is 23
So my question is How to Find the rate for given date if the date exist other wise take the rate of lesser date and if the lesser date is not exist find the rate of next bigger date?
Finally we get rate for all dates(from start date to end date).
How can I achieve this?
$begin = new DateTime('2017-10-01');
$end = new DateTime('2017-10-10');
$daterange = new DatePeriod($begin, new DateInterval('P1D'), $end);
foreach($daterange as $date){
$dateval = $date->format("Y-m-d");
// here I want find the rate for each date
}
Here is one method:
select t.*
from t
order by (adate <= '2017-10-01') desc
abs(datediff(adate, '2017-10-01'))
limit 1;

Get average day or week values

I have statistical data like this:
time val1
1424166578 51
1424166877 55
1424167178 57
1424167477 57
time is a unix timestamp. There is one record every 5 minutes excluding nights and sundays. This continues over several weeks.
Now I want to get these values for an average day and an average week. The result should include values for every 5 minutes like normal but for average past days or weeks.
The result should look like this:
time val1
0 43.423
300 46.635
600 51.887
...
So time could be a timestamp with relative time since day or week start. Perhaps it is better to use DATETIME... not sure.
If I use GROUP BY FROM_UNIXTIME(time, '%Y%m%d') for example I get one value for the whole day. But I want all average values for all days.
You seem to be interested in grouping dates by five minute intervals instead of dates. This is fairly straightforward:
SELECT
HOUR(FROM_UNIXTIME(time)) AS HH,
(MINUTE(FROM_UNIXTIME(time)) DIV 5) * 5 AS MM,
AVG(val1) AS VAL
FROM your_table
WHERE time > UNIX_TIMESTAMP(CURRENT_TIMESTAMP - INTERVAL 7 DAY)
GROUP BY HH, MM
The following result will explain how date is clamped:
time FROM_UNIXTIME(time) HH MM
1424166578 2015-02-17 14:49:38 14 45
1424166877 2015-02-17 14:54:37 14 50
1424167178 2015-02-17 14:59:38 14 55
1424167477 2015-02-17 15:04:37 15 00
I would approach this as:
select date(from_unixtime(time)) as day, avg(val)
from table t
group by date(from_unixtime(time))
order by day;
Although you can use the format argument, I think of that more for converting the value to a string than to a date/time.

Group by hour showing breakdown for each day within date range MYSQL

I'm trying to create a query to show the breakdown of leads relating to finance contracts grouped by hour.
Here's an example of what I have so far for hours:
SELECT CONCAT(HOUR(received), ':00-', HOUR(received)+1, ':00') AS Hours,
COUNT(*) as `leads`
FROM (digital_lead)
WHERE `received` BETWEEN '2014-11-01 00:00:00' AND '2014-11-24 00:00:00'
GROUP BY HOUR(received)
And here's the result ....
Hours usage
0:00-1:00 36
1:00-2:00 25
2:00-3:00 16
3:00-4:00 4
4:00-5:00 7
5:00-6:00 8
6:00-7:00 13 // etc all the way to 23:00 - 24:00
OK - so that seems to work, however, it aggregates all of the leads for that time slot over the course of the period set in the BETWEEN statement. I would like to be able to show the breakdown per hour for each day within the period range.
So that would look something like:
Date Hours leads
2014-11-01
0:00-1:00 36
1:00-2:00 25
2:00-3:00 16
3:00-4:00 4
4:00-5:00 7
5:00-6:00 8
6:00-7:00 13 // etc all the way to 23:00 - 24:00
So each date would be displayed and then the hours for that day and so forth.
Thanks.
Group by date as well:
SELECT DATE(received), HOUR(received), ...
...
GROUP BY DATE(received), HOUR(received)
Since you're grouping by hour() only, you'll essentialy be getting
Hour
1 sum of leads in hour 1 of jan 1, jan 2, jan 3, ... dec 31
2 sum of leads in hour 2 of jan 1, jan 2, jan 3, ... dec 31
Rather than
Jan 1 Hour 1 sum of leads for just that one hour on the one day
Jan 1 Hour 2 sum of leads for just that one hour on the one day
..
Dec 31 Hour 23 sum of leads

MYSQL Queries to find immediate next DateTime

I was writing a mini scheduler that perform certain task.
For calculating trigger time, I am using MYSQL. I am stucked at writing one of the query.
Find immediate DateTime which is greater than the given prevtime,
AND
the Day of the required immediate datetime should be ANY of given days
AND
time(HH:MM:SS) portion of required immediate datetime should be equal to given time.
Examples:
(a)
If given days are ('MON', 'WEDNES', 'SAT'),
given time is 10:15:00,
given prevtime is 2014-11-12 23:17:00
Then MYSQL should return
2014-11-15 10:15:00
(b)
Given Days: ('SUN','SAT','TUES')
Given Time: 09:10:00
Given prevtime is 2014-11-30 07:05:12
MYSQL should return 2014-11-30 09:10:00
(c)
Given Days: ('MON','THURS','SAT')
Given Time: 11:00:00
Given prevtime is 2014-12-29 11:55:12
MYSQL should return 2015-01-01 11:00:00
(d)
Days: (SUN, THURS, SAT)'
Given prevtime is 2014-02-27 18:15:00
Given Time 15:15:00
MYSQL Query result: 2014-03-01 15:15:00
(e)
DAYS: (TUES, WED, FRI)
Prev Date: 2014-12-23 09:30:00
Time : 08:00:00
Expected Result:
2014-12-24 08:00:00
(f)
DAYS: SUN, TUES, THURS
Prev Date: 2014-07-31 10:10:00
Time: 06:07:08
Expected Res:
2014-08-03 06:07:08
Using numeric weekday numbers, 0=Monday, 6=Sunday:
set #day1=0;
set #day2=2;
set #day3=5;
set #time=time('10:15:00');
set #prevtime=timestamp('2014-11-12 23:17:00');
select if(weekday(#nexttime:=date_add(concat(date(#prevtime),' ',#time),interval if(#time>time(#prevtime),0,1) day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,date_add(#nexttime,interval 1 day))))))) as nexttime;
If you have only one weekday, you can set all three variables to the same number.
You should be able to formulate the where clause using the DAYNAME(), HOUR(), MINUTE() and SECOND() functions:
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
If performance is inadequate and you start wishing you could index on DAYNAME(columname) for example, you can consider denormalizing your data and storing the DAYNAME value separately.
It might be simpler to switch to Postgres at that point though:
http://www.postgresql.org/docs/9.1/static/indexes-expressional.html