My DB in UTC timezone and data inserting in UTC time. I want to sum all values and group by hourly for IST time data. like below,
id data_id value serverTime
1 2 100 2016-05-02 18:30:54
2 2 100 2016-05-02 18:45:54
4 2 200 2016-05-02 19:00:54
5 2 100 2016-05-02 19:15:54
6 2 100 2016-05-02 19:30:54
7 2 100 2016-05-02 19:40:54
Query
select sum(value) as value, serverTime as date
from Data_table
where data_id=2
and serverTime between CONVERT_TZ('2016-05-03 00:00:01','+00:00', '-05:30')
and CONVERT_TZ('2016-05-03 10:45:24','+00:00', '-05:30')
group by year(date),month(date),week(date),day(date),hour(date);
above query giving result is :
200
500
But Expecting output :
600
100
because IST 12 AM = UTC- 05:30 which means 18:30 to 19:30 but here my query calculating only 18:30 to 19:00, 19:00 to 20:00, 20:00 to 21:00 which is not accuracy value.
I want to calculate value for 18:30 to 19:30 and 19:30 to 20:30 for accuracy value for IST time data.
How to solve this?
By IST, I assume you mean India Standard Time, which is 5 hours and 30 minutes ahead of UTC. As a fixed offset, that would be +05:30, not -05:30. You're results are incorrect because you have the sign inverted.
The CONVERT_TZ function accepts any of:
'SYSTEM' for the local system time zone
Fixed offsets in standard ISO 8601 format, which have positive offsets East of UTC, such as '+05:30' for India, or '-10:00' for Hawaii.
Named time zones, using standard IANA/Olson TZDB identifiers, assuming the time zone tables are populated. India's is 'Asia/Kolkata', US Eastern time is 'America/New_York', etc. Using this option requires the mysql time zone tables to be populated, per the documentation.
In general, named time zones are preferred because they accommodate changes in offset due to daylight saving time and historical changes. However, India has been fixed at +05:30 since 1942 and isn't likely to change in the near future, so it's reasonable to use the fixed offset approach if this is the only time zone you need to deal with.
Also note that "IST", like many time zone abbreviations, is ambiguous. It can mean India Standard Time (+05:30), Ireland Standard Time (+01:00) or Israel Standard Time (+02:00). Also note that Ireland Standard Time is actually a daylight time zone offset, despite having the name "Standard" in it. To avoid confusion, please specify your particular location when referring to IST in the future, and don't ever expect a computer to be able to distinguish them.
You should convert also date in group by
select sum(value) as value , hour(CONVERT_TZ(serverTime, '+00:00', '-05:30')) as hour
from Data_table
where data_id=2
and serverTime between CONVERT_TZ('2016-05-03 00:00:01','+00:00', '-05:30')
and CONVERT_TZ('2016-05-03 10:45:24','+00:00', '-05:30')
group hour(CONVERT_TZ(serverTime, '+00:00', '-05:30'));
Test for between condition
select CONVERT_TZ('2016-05-03 00:00:01','+00:00', '-05:30') ,
CONVERT_TZ('2016-05-03 10:45:24','+00:00', '-05:30') from dual;
select CONVERT_TZ('2016-05-03 00:00:01','+00:00', '-05:30') ,
CONVERT_TZ('2016-06-03 01:00:24','+00:00', '-05:30') from dual;
Related
How do I query between two time range using MySQL?
it is similar to this question provided in the above link but the match_time was divided into two columns, i.e. match_start_time and match_end_time,
match_start_time <= CAST('10:00:00' AS time) AND match_end_time >= (CAST('12:00:00' AS time))
This was the query through which i tried but was not getting the correct result.
example
consider match start and end time being:-
01:30 - 03:30, 05:00 - 06:30, 03:00 - 21:30, 14:00 - 09:00
then if i pass 00:00 - 10:00 as min and max, then i get
01:30 - 03:30, 05:00 - 06:30, 14:00 - 09:00
but not sure whether 14:00 - 09:00 should be included.
Also if they pass 18:00 - 09:00
Then how to get the result if user provided min time is greater than max time
Sorry for bad English, please help
The question is bit ambiguous. You can convert the times to datetime and determine into which date the times belong to:
select time_range, cast(time_to_match as time)
from (
select
concat(m.match_start_time,'-',m.match_end_time) as 'time_range',
addtime(cast(concat('2020-01-', if(m.match_start_time<=m.match_end_time or m.match_start_time<t.match_time, '01', '02')) as datetime),t.match_time) as 'time_to_match',
addtime(cast('2020-01-01' as datetime), m.match_start_time) as 'start_time',
addtime(cast(concat('2020-01-', if(m.match_start_time<=m.match_end_time, '01', '02')) as datetime), m.match_end_time) as 'end_time'
from times t
join match_times m on 1=1
) as q
where time_to_match between start_time and end_time
order by 1,2;
See db-fiddle.
We've got a big database which registers positions of tracked vehicles. So, every second, we have thousands of positions coming.
The aim is to filter the SQL request, because we have too many datas. If I do a simple "select time from positions", i'll get a lot of position times. But i'm not interested in all of them.
So my idea was to create an interval. I want the database to give me the position time every 5 minutes.
The database uses STR_TO_DATE function to get position time.
My data is like this :
2019-06-05 00:00:00
2019-06-05 00:01:00
2019-06-05 00:01:00
2019-06-05 00:02:00
And i want this :
2019-06-05 00:00:00
2019-06-05 00:05:00
2019-06-05 00:10:00
2019-06-05 00:15:00
As you see here, the position times "01" "02" .. have disappeared. Because i don't want them. I want the position time in 00:05:00 , then in 00:10:00 , BUT I don't want the position time between these intervalls.
select
distinct time
from
positions
where
time>STR_TO_DATE('05/06/2019 00:00', '%d/%m/%Y %H:%i')
and time<STR_TO_DATE('06/06/2019 00:00', '%d/%m/%Y %H:%i')
limit 1000;
How can I do this in my case please? How can I change my code ?
I'm using Mysql workbench version 6.3.
Supposing the time is of type DATETIME or TIMESTAMP and that you want only the records where the seconds within the time equal 0 and the minutes within that time are a multiple of 5, you may try the following:
WHERE MOD(UNIX_TIMESTAMP(time), 300) = 0
I'm not sure whether this is correct since I don't know how this function behaves with respect to leap seconds. I cannot test this in my environment.
In order to resolve this, you may try this:
WHERE MOD(EXTRACT(MINUTE FROM time), 5) = 0
AND EXTRACT(SECOND FROM time) = 0 -- if relevant
AND EXTRACT(MICROSECOND FROM time) = 0
I'm trying to write a sql query that gives me the average time.
I have 5 columns and multiple entries.
the five columns are taxi-number start-date end-date start-time end-time.
I need to find the average time, times given are in 24 hour format but I also need to account for the difference in start-date and end-date if its there,and i need to group it by taxi number.
input
Taxi-Number Start-Date Start-Time End-Date End-Time
4412 8/8/2015 18:06:00 8/9/2015 14:00:00
2223 4/18/2013 19:33:00 4/19/2013 0:40:00
1112 10/20/2013 11:23:00 10/22/2013 8:33:00
5553 5/18/2015 21:43:00 5/19/2015 9:15:00
2222 4/9/2014 0:00:00 4/10/2014 0:16:00
output
taxi 4412, average time 20 hours 6 minutes or in any format that accounts for this
Thanks.
Not an answer. Too long for a comment...
Start here:
Taxi_Number Start_Date End_Date
4412 2015-08-08 18:06:00 2015-08-09 14:00:00
Once you have that as your structure, see Why should I provide an MCVE for what seems to me to be a very simple SQL query? ... and then get back to us.
So let's say that I want to keep track of my CPU temperature, with simple columns 'date' and 'temperature'. I'd like to see what period saw the highest temperatures on average in the last week. I capture the data every 10 minutes, so I want each 10 minute block averaged with the same block from the other days of the week.
So for example:
2018-01-08 02:00:00 78.3
2018-01-08 03:00:00 81.2
2018-01-09 02:00:00 74.1
2018-01-09 03:00:00 75.9
I would want the averages of each day # 02:00:00, each day # 03:00:00, and so on. (except the real data is every 10 minutes) The exact datetime varies - it's not always 02:00:02, sometimes it could be 02:00:07, etc., so I can't just do an exact conditional.
Any idea how I'd go about making this data? I assume there's some way I can use GROUP BY for this, but I'm lost as to how.
Format just the hour and minute, and group by that.
SELECT DATE_FORMAT(date, '%H:%i') AS time, AVG(temperature) AS temp
FROM yourTable
GROUP BY time
This assumes that the readings are never delayed by more than a minute from the expected 10-minute periods -- if the reading for 02:10 happens at 02:11:01 it will not be put in the group.
When saving TIME values into the MySQL database, our server automatically converts these dates to be formatted in UTC time, because of this we've stored our user's timezone offset in our database. Considering we had a simple database like composed of three fields, how would we go about getting the time within the allotted minute range with the appropriate hour.
id | offset | alertTime
---|--------|----------
1 | 360 | 4:22:38
2 | 420 | 3:28:41
In this table, user 1 has a 6 hour offset (CST) and user 2 has a 5 hours offset and a 7 hour offset (MDT) I need to find both of these user's (and any other users) that are all within the same hour after timezone calculation.
The conversion to these user's time is nearly the same, both users have an alert scheduled for 10PM 22Minuts nad 10PM 28 minutes, although different times are entered into the database due to UTC conversion.
Let's say I wanted to get all users who have an alert set for 10PM, between 10:16 and 10:29 CST regardless of their timezone.
Just to clarify, user's who set their alertTime in their own timezone, should be returned if their timezone converts to 10:16 - 10:29 CST. So, 9:16-9:29 MDT would also be returned in these results.
Hope that wasn't too confusing.
--
I'm using MariaDB through NodeJS if that matters.
Don't store them into a TIMESTAMP column; store them as DATETIME. That way, there is no offset during the insert, nor the select.
If you also need UTC, maybe you need two columns, one of each type?