selecting all records between a certain period in mysql - mysql

I have the following table,for example:
id....name....fromtime....totime
1.....a.......00:00.......00:09:59
2.....a.......00:10.......00:19:59
3.....a.......00:20.......00:29:59
4.....a.......00:30.......00:39:59
5.....a.......00:40.......00:49:59
I want to retrieve all records that belong to a (not a problem) and are between 00:05 and 00:25 that is, for the above example, are rows 1 to 3 leaving 4 and 5 out.
How can I accomplish that using mysql?
Thanks

Look into using the 'between' clause with a new column that combines fromtime and totime.
For instance, SELECT id, fromtime-totime As "elapsed_time" FROM your_table WHERE elapsed_time BETWEEN 5 AND 25. Or something like that. The query will vary depending on the types of your columns.
See more here:
http://www.tutorialspoint.com/mysql/mysql-between-clause.htm
http://www.geeksengine.com/database/basic-select/arithmetic-operations.php

AND FromTime >= subtime( $time ) , '00:10:00' ) - to get also the first row
AND ToTime <= addtime( TIME( $time ) , '00:20:00' ) - 00:20:00 is an example ofcourse

Related

mysql group based on time intervals

I want to query a table which is like
Table structure for table archive
|------
|Column|Type|Null|Default
|------
|//**id**//|int(11)|No|
|datetime|timestamp|No|CURRENT_TIMESTAMP
|gatewayid|int(11)|No|
|RSSI|float|No|
|distance|float|No|
|beaconid|int(11)|No|
== Dumping data for table archive
|1|2017-08-22 12:14:19|1|-65|36|1
|2|2017-08-22 12:14:19|2|-60|30|1
|3|2017-08-22 12:14:19|3|-60|30|1
|4|2017-08-22 12:14:19|1|-52|63|2
|5|2017-08-22 12:14:19|2|-36|33|2
|6|2017-08-22 12:14:19|3|-65|33|2
|7|2017-08-22 12:14:19|1|-69|66|3
|8|2017-08-22 12:14:19|2|-65|33|3
|9|2017-08-22 12:14:19|3|-66|33|3
|10|2017-08-22 12:16:09|1|-65|36|1
|11|2017-08-22 12:16:09|2|-60|30|1
|12|2017-08-22 12:16:09|3|-60|30|1
|13|2017-08-22 12:16:09|1|-52|63|2
|14|2017-08-22 12:16:09|2|-36|33|2
|15|2017-08-22 12:16:09|3|-65|33|2
|16|2017-08-22 12:16:09|1|-69|66|3
|17|2017-08-22 12:16:09|2|-65|33|3
|18|2017-08-22 12:16:09|3|-66|33|3
|19|2017-08-22 12:32:05|1|-65|36|1
|20|2017-08-22 12:32:05|2|-60|30|1
|21|2017-08-22 12:32:05|3|-60|30|1
|22|2017-08-22 12:32:05|1|-52|63|2
|23|2017-08-22 12:32:05|2|-36|33|2
|24|2017-08-22 12:32:05|3|-65|33|2
|25|2017-08-22 12:32:05|1|-69|66|3
I want to average RSSI values based on theses rules
- group based on gatewayid,beaconid and datetime
- the group by datetime should be in every 5 minutes for example
well in fact I want avrage RSSI values for rows which their beaconid and gatewayid are the same and they are added in a 5 minutes interval,
I have written this query
select DATE_ADD( '1900-01-01T00:00:00',INTERVAL 15+TIMESTAMPDIFF(minute, '1900-01-01T00:00:00', datetime) minute),
(sum(RSSI)/count(*)) as mean_rssi,
(sum(distance)/count(*)) as mean_distance,
beaconid,
gatewayid
from archive
GROUP by DATE_ADD( '1900-01-01T00:00:00',INTERVAL 15+TIMESTAMPDIFF(minute, '1900-01-01T00:00:00', datetime) minute),
beaconid,
gatewayid
Here is sqlfiddle for create statement
this query returns all rows without any changes,where am I doing wrong?
thanks
Your query appears to be correct it's just that your data is unique on interval/beaconid/getewayid so it happens to return 'all' rows...
If I understand your data you probably want to group by 5 min intervals, and to get a value that is the same for every five min interval you may opt to just divide the timestamp by 300 seconds - something like:
select min(`datetime`) as `start`,
(sum(RSSI)/count(*)) as mean_rssi,
(sum(distance)/count(*)) as mean_distance,
beaconid,
gatewayid
from archive
group by UNIX_TIMESTAMP(`datetime`) / 60*5,
beaconid,
gatewayid
also use sqlfiddle or rextester it is much easier to help you if you use those...

DateTime operation with MySQL

I'm pretty bad with dates.
I have a mysql table with one field, which is OF DateTime type, called HoraRegistratBBDD.
What I want to do is to select data (any kind of data) from a specific day. So far I was doing this:
SELECT COUNT(*)
FROM
(
SELECT mydata
FROM mytable
WHERE DATE(`HoraRegistratBBDD`) = '".$fecha."' AND
FetOPerdutIMotiu = '1'
GROUP BY Partit,
mydata
) AS Col;
Where $fecha is something like "2016-09-03". THIS WORKS.
But I have a problem. When my HoraRegistratBBDD has (for example) this value:
2016-09-02 10:28:41
I would like to substract 15 hours from it. Meaning that I would like to treat this value like it's actually
2016-09-01 19:28:41
How can I do my query considering that I want to substract hours from it (therefore, day will change sometimes)?
If you want to subtract 15 hours from the HoraRegistratBBDD column, then you can use DATE_SUB:
SELECT mydata FROM mytable
WHERE DATE_SUB(HoraRegistratBBDD, INTERVAL 15 HOUR) = ...
The function that you are looking for is DATE_SUB.
Here are a few links:
http://www.w3schools.com/sql/func_date_sub.asp
How to subtract 3 hours from a datetime in MySQL?
The first one shows you how it works and the other one is a similar question and it has been answered.
SELECT COUNT(*)
FROM
(
SELECT mydata, DATE_FORMAT(HoraRegistratBBDD,'%Y-%m-%d') AS niceDate
FROM mytable
WHERE
FetOPerdutIMotiu = '1'
HAVING niceDate = '".$fecha."'
GROUP BY Partit,
mydata
) AS Col;

How to return difference between timestamps in SQL?

I run a query on my table that makes it return timestamps in ascending order (oldest to newest). As in I put in a line ORDER BY timestamp.
I need my results to have a column called "Days Taken" which contains the difference between each of the timestamps, i.e. (Timestamp 2 - Timestamp 1), (Timestamp 3 - Timestamp 2), (Timestamp 4 - Timestamp 3) and so on. How do I do this using SQL?
value timestamp Days Taken
2 2016-03-16 05:11:40 -
3 2016-03-18 03:46:42 ?
4 2016-03-18 04:09:44 ?
5 2016-03-21 04:01:46 ?
6 2016-03-22 04:38:17 ?
I'm unable to use the column value as an index because it is defined as a string and not an int which is why this doesn't work for me. Days Taken is the value I'd like to calculate.
Edited to add: I'm running DbVisualizer for Vertica which does not seem to support subqueries in the ON clause.
Try something along these lines:
select datediff(dd, a.timestamp, b.timestamp)
from #Table a
join #Table b on a.timeStamp = (select max(c.timeStamp)
from #Table c where c.timeStamp < b.timeStamp)

Selecting first value of every minute in table

I've been trying to work this one out for a while now, maybe my problem is coming up with the correct search query. I'm not sure.
Anyway, the problem I'm having is that I have a table of data that has a new row added every second (imagine the structure {id, timestamp(datetime), value}). I would like to do a single query for MySQL to go through the table and output only the first value of each minute.
I thought about doing this with multiple queries with LIMIT and datetime >= (beginning of minute) but with the volume of data I'm collecting that is a lot of queries so it would be nicer to produce the data in a single query.
Sample data:
id datetime value
1 2015-01-01 00:00:00 128
2 2015-01-01 00:00:01 127
3 2015-01-01 00:00:04 129
4 2015-01-01 00:00:05 127
...
67 2015-01-01 00:00:59 112
68 2015-01-01 00:01:12 108
69 2015-01-01 00:01:13 109
Where I would want the result to select the rows:
1 2015-01-01 00:00:00 128
68 2015-01-01 00:01:12 108
Any ideas?
Thanks!
EDIT: Forgot to add, the data, whilst every second, is not reliably on the first second of every minute - it may be :30 or :01 rather than :00 seconds past the minute
EDIT 2: A nice-to-have (definitely not required for answer) would be a query that is flexible to also take an arbitrary number of minutes (rather than one row each minute)
SELECT t2.* FROM
( SELECT MIN(`datetime`) AS dt
FROM tbl
GROUP BY DATE_FORMAT(`datetime`,'%Y-%m-%d %H:%i')
) t1
JOIN tbl t2 ON t1.dt = t2.`datetime`
SQLFiddle
Or
SELECT *
FROM tbl
WHERE dt IN ( SELECT MIN(dt) AS dt
FROM tbl
GROUP BY DATE_FORMAT(dt,'%Y-%m-%d %H:%i'))
SQLFiddle
SELECT t1.*
FROM tbl t1
LEFT JOIN (
SELECT MIN(dt) AS dt
FROM tbl
GROUP BY DATE_FORMAT(dt,'%Y-%m-%d %H:%i')
) t2 ON t1.dt = t2.dt
WHERE t2.dt IS NOT NULL
SQLFiddle
In MS SQL Server I would use CROSS APPLY, but as far as I know MySQL doesn't have it, so we can emulate it.
Make sure that you have an index on your datetime column.
Create a table of numbers, or in your case a table of minutes. If you have a table of numbers starting from 1 it is trivial to turn it into minutes in the necessary range.
SELECT
tbl.ID
,tbl.`dt`
,tbl.value
FROM
(
SELECT
MinuteValue
, (
SELECT tbl.id
FROM tbl
WHERE tbl.`dt` >= Minutes.MinuteValue
ORDER BY tbl.`dt`
LIMIT 1
) AS ID
FROM Minutes
) AS IDs
INNER JOIN tbl ON tbl.ID = IDs.ID
For each minute find one row that has timestamp greater than the minute. I don't know how to return the full row, rather than one column in MySQL in the nested SELECT, so at first I'm making a temp table with two columns: Minute and id from the original table and then explicitly look up rows from original table knowing their IDs.
SQL Fiddle
I've created a table of Minutes in the SQL Fiddle with the necessary values to make example simple. In real life you would have a more generic table.
Here is SQL Fiddle that uses a table of numbers, just for illustration.
In any case, you do need to know in advance somehow the range of dates/numbers you are interested in.
It is trivial to make it work for any interval of minutes. If you need results every 5 minutes, just generate a table of minutes that has values not every 1 minute, but every 5 minutes. The main query would remain the same.
It may be more efficient, because here you don't join the big table to itself and you don't make calculations on the datetime column, so the server should be able to use the index on it.
The example that I made assumes that for each minute there is at least one row in the big table. If it is possible that there are some minutes that don't have any data at all you'd need to add extra check in the WHERE clause to make sure that the found row is still within that minute.
select * from table where timestamp LIKE "%-%-% %:%:00" could work.
This is similar to this question: Stack Overflow Date SQL Query Question
Edit: This probably would work better:
`select , date_format(timestamp, '%Y-%m-%d %H:%i') as the_minute, count()
from table
group by the_minute
order by the_minute
Similar to this question here: mysql select date format
i'm not really sure, but you could try this:
SELECT MIN(timestamp) FROM table WHERE YEAR(timestamp)=2015 GROUP BY DATE(timestamp), HOUR(timestamp), MINUTE(timestamp)

mysql query to fetch the quarter month from table

Table name: activity
Field name: ProcessYM
I have mysql data like below.
ProcessYM
==========
201312
201311
201310
201309
201308
201307
201306
201305
201304
201303
201302
201301
201212
201211
201210
201209
201208
201207
201206
I want to fetch the result like below. I mean, the mysql query to fetch the every quarter of the year like 201312, 201309, 201306, 201303, 201212, 201209.. and so on.
Actual Output I expect
=======================
ProcessYM
201312
201309
201306
201303
201212
201209
201206
I have tried the below query, but it does not produce the expected result.
SELECT distinct `ActProcessYM` from `activity` where `ActProcessYM`%3=0 order by ActProcessYM desc
Output of above query
=====================
201312
201309
201306
201303
201210
201207
It is much appreciated for your smart reply.
You need to modulo of the month part only. Your query is implicitly casting your ProcessYM as an INT.
For example:
SELECT DISTINCT ProcessYM
FROM activity
WHERE RIGHT(ProcessYM,2)%3=0
ORDER BY ProcessYM DESC
fiddle
you should retrieve the last two digits from field value and do the logic as you are doing.
SELECT distinct `ActProcessYM` from `activity` where substring(ActProcessYM,5,2)%3=0 order by ActProcessYM desc
Here's a not-so-quick-and-dirty way of handing this date processing. I believe you're looking for a MySQL formula like this:
yyyymm = TRUNC_QUARTER(yyyymm)
That is, you are looking for a function that converts any yyyymm month notation into a notation that shows the month that ends the quarter in question.
Let's start with an expression that converts any particular DATETIME expression to the DATE of the beginning of the quarter.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
This takes a timestamp (e.g. '2011-04-20 11:15:01') and turns it into the date of the starting of the quarter. (e.g. '2011-04-01')
Having things in this date form is helpful because you can use them for date arithmetic. For example, you can get the last day of that quarter like this.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
+ INTERVAL 1 QUARTER - INTERVAL 1 DAY
Here's a writeup on all this: http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
I've found it helpful to try to stick to the date datatype when processing time series data.
You need to separate out the month value before doing the modulo 3 (% 3). Doing a modulo 100 first will do it:
(ProcessYM % 100) % 3) = 0
or
mod(mod(ProcessYM,100),3) = 0
Try this,
SELECT distinct `ProcessYM` from `activity` where SUBSTRING(`ProcessYM`,5,2)%3=0 order by ProcessYM desc