Mysql timestampdiff sum between overlapped intervals - mysql

I have the following table structure:
+----+---------------------+---------------------+
| id | created_at | closed |
+----+---------------------+---------------------+
| 1 | 2017-04-03 04:00:00 | 2017-04-03 04:30:00 |
| 2 | 2017-04-03 04:25:00 | 2017-04-03 04:35:00 |
+----+---------------------+---------------------+
In my real SQL query I use timestampdiff to clacualte the diffirence between two dates in timestap field. There is no problem if the ctreated_at and closed_at of all records start in diffirent time intervals, so I would able to get time consumed for all rows as follows:
SELECT SUM(timestampdiff(SECOND, created_at, closed_at)) as TotalTime FROM table
My problem is like the shown table above, the time interval crossing. The above query will result 900 but it I should have 600
I have tried something like:
SELECT timestampdiff(
MINUTE,
a.created_at,
(SELECT max(b.closed) from times as b WHERE b.created_at < a.closed)
) as periods
FROM `times` as a
The result is:
+---------+
| periods |
+---------+
| 35 |
| 10 |
+---------+
Here I want only the first result whuch represnts the net time of the overlapped periods. Using MAX with the previous query should returns the first record but it will lead to neglect any other periods groups added in the futere supposed the table becomes:
+----+---------------------+---------------------+
| id | created_at | closed |
+----+---------------------+---------------------+
| 1 | 2017-04-03 04:00:00 | 2017-04-03 04:30:00 |
| 2 | 2017-04-03 04:25:00 | 2017-04-03 04:35:00 |
| 3 | 2017-04-03 05:00:00 | 2017-04-03 05:15:00 |
+----+---------------------+---------------------+
the above query returns:
+---------+
| periods |
+---------+
| 35 |
| 10 |
| 15 |
+---------+
Again here I don't want the second record because it describes its period which is previously counted in the first record. Indeed I don't know does it possible in MySQL to get (for the example above) only two records or even three records but the second is null, 0, negative value, etc to be distinguished among other really values.

You need to do group by the time on hourly basis and the take difference time for of max.
SELECT max(timestampdiff(
MINUTE,
a.created_at,closed) as periods
FROM `times` as a group by hour(created_at)
Now you will get result as per ur requirement.

Related

Obtaining max values for each day in the past 28 days

I've seen some of the past posts where there were questions about extracting max values for each day. Based on this, I tried SELECT ts, MAX(current) FROM mytable WHERE ts > date_add(now(), interval -28 day); but I only got one row back which is not what I want.
In this table, ts is my timestamp and current is another column of values. I want to get the max current values for each day in the past 28 days. However, my current values are recorded into the table every 30 mins each day. Therefore, there are many ts values for each day. Could this be the reason why the above query design doesnt work? If so, how can I amend it?
Here is an example of how my table look like for a few rows:
+---------------------+--------------+
| ts | current |
+---------------------+--------------+
| 2018-01-20 16:27:10 | 439.37 |
| 2018-01-20 17:00:18 | 378.07 |
| 2018-01-20 17:30:15 | 204.80 |
| 2018-01-20 18:00:16 | 196.50 |
| 2018-01-20 18:30:16 | 179.40 |
| 2018-01-20 19:00:16 | 183.00 |
| 2018-01-20 19:30:16 | 105.00 |

SQL - select x entries within a timespan

I'm creating a database (in MySQL) with a table of measurements. For each measurement I want to store the DateTime it came in. For showing plots within an app for different intervals (measurements of the day/week/month/year) I want sample the data points I have, so I can return e. g. 30 data points for the whole year as well as for the day/hour. This is the same as done with stock price graphs:
stock price plot for 1 day
vs
stock price plot for 1 month
As you can see, the amount of data points is the same in both pictures.
So how can I select x entries within a timespan in MySQL via SQL?
My data looks like this:
+====+====================+=============+==========+
| id | datetime | temperature | humidity |
+====+====================+=============+==========+
| 1 | 1-15-2016 00:30:00 | 20 | 40 |
+----+--------------------+-------------+----------+
| 2 | 1-15-2016 00:35:00 | 19 | 41 |
+----+--------------------+-------------+----------+
| 3 | 1-15-2016 00:40:00 | 20 | 40 |
+----+--------------------+-------------+----------+
| 4 | 1-15-2016 00:45:00 | 20 | 42 |
+----+--------------------+-------------+----------+
| 5 | 1-15-2016 00:50:00 | 21 | 42 |
+----+--------------------+-------------+----------+
| 6 | 1-15-2016 00:55:00 | 20 | 43 |
+----+--------------------+-------------+----------+
| 7 | 1-15-2016 01:00:00 | 21 | 43 |
+====+====================+=============+==========+
Let's say, I always want two data points (in reality a lot more). So for the last half hour I want the database to return data point 1 and 4, for the last ten minutes I want it to return 6 and 7.
Thanks for helping!
PS: I'm sorry for any errors in my English
OK, assuming a very simple systematic approach, you can get the first and last entry for any defined period:
select *
from table
where mydatetime =
(select
max(mydatetime)
from table
where mydatetime between '2017-03-01' and '2017-03-15'
)
OR mydatetime =
(select
min(mydatetime)
from table
where mydatetime between '2017-03-01' and '2017-03-15'
)
I believe your answer can be found at the following location:
https://stackoverflow.com/a/1891796/7176046
If you are looking to filter out any items not within your date/time your query would use:
Select * from table where Date/Time is (What you want to sort by)

Calculate the fullness of an apartment using SQL expression

I have a database which looks like this:
Reservations Table:
-------------------------------------------------
id | room_id | start | end |
1 | 1 | 2015-05-13 | 2015-05-16 |
2 | 1 | 2015-05-18 | 2015-05-20 |
3 | 1 | 2015-05-21 | 2015-05-24 |
-------------------------------------------------
Apartment Table:
---------------------------------------
id | room_id | name |
1 | 1 | test apartment |
---------------------------------------
Meaning that in the month 05 (May) there is 31 days in the database we have 3 events giving us 8 days of usage 31 - 8 = 23 / 31 = 0.741 * 100 = %74.1 is the percentage of the emptiness and %25.9 is the percentage of usage. how can i do all of that in SQL? (mySQL).
This is my proposal:
SELECT SUM(DAY(`end`)-DAY(`start`))/EXTRACT(DAY FROM LAST_DAY(`start`)) FROM `apt`;
LAST_DAY function gives as output the date of last day of the month.
Check this
http://sqlfiddle.com/#!9/7c53b/2/0
Not the most efficient query but will get the job done.
select
sum(a.days)*100/(SELECT DAY(LAST_DAY(min(start))) from test1)
as usePercent,
100-(sum(a.days)*100/(SELECT DAY(LAST_DAY(min(start))) from test1))
as emptyPercent
FROM
(select DATEDIFF(end,start) as days from test1) a
What I did is first get the date difference and count them. Then in a nested query use the day(last_day()) function to get the last day of month. Then calculated by using your logic.

Mysql: Execute query for each date

I am using Mysql 5.5.43-0+deb7u1.
I have managed to create this query to fetch rain data for particular day (I use MODbecause rain data is updated at every full hour while other data gets update more frequently.)
SELECT date,SUM(rainmm) FROM weather WHERE MOD(minute(time),60)=0 AND date=CURDATE()-1;
+------------+-------------+
| date | sum(rainmm) |
+------------+-------------+
| 2015-06-23 | 0.1 |
+------------+-------------+
1 row in set (0.15 sec)
I am looking for a way to get results for all days with single query instead of needing to check every day manually. I am unsure if I should use loops and iterate number for days from current date or if there is better way to accomplish this.
Desired result:
SELECT date, [Smart query to get all days at once]
+------------+-------------+
| date | sum(rainmm) |
+------------+-------------+
| 2015-06-23 | 0.1 |
| 2015-06-24 | 0.0 |
| ... | ... |
| 2015-11-11 | 11.1 |
+------------+-------------+
Does this do what you want
SELECT date,SUM(rainmm) FROM weather WHERE MOD(minute(time),60)=0
GROUP BY date
ORDER BY date;

MYSQL check the value of the next row

I have a table 'mytable' like this
ID | dateTime | data |
------------------------------------------
1 | 2013-09-01 00:15:00 | some data |
2 | 2013-09-01 00:15:00 | some data |
4 | 2013-09-01 00:15:00 | some data |
5 | 2013-09-01 00:30:00 | some data |
6 | 2013-09-01 00:30:00 | some data |
7 | 2013-09-01 00:30:00 | some data |
8 | 2013-09-01 00:45:00 | some data |
9 | 2013-09-01 00:45:00 | some data |
10 | 2013-09-01 00:45:00 | some data |
I was fine before but I accidentally changed the dateTime to round to 15 minutes (I was supposed to round it for 5 minutes) please refere to this, No I want to round the time for 5 minutes.
I think the only way I can do this, is to get the dateTime of one record then check the record in the next row, if both are same then add 5 minutes into it.
How do I get the value of the next row and compare it with previous one?
Can anyone help me with this??
Thanks
This query will output the new datetime values, where I add 5 minutes every time the datetime is the same as the previous row, ordered by Id:
SELECT ID,
DATE_ADD(dateTime, INTERVAL 5 * (ID -
(SELECT MIN(ID) FROM MyTable T2 WHERE T2.dateTime = T1.dateTime)
) MINUTE) AS dateTime,
data
)
FROM MyTable T1
It works by adding 5 times the difference in ID values between the current row and the first row (minimum ID) of the same dateTime value.
While this will definitely do what you want, depending on how you rounded down to 15 minutes, the output will not necessarily be the same as if you had rounded down to 5 minutes from your original data. Your best option would be to restore from a backup.