Mysql: Round datetime to seconds - some issues 24h - mysql

i spend time to solve my issue on my own and also read through many posts in here but somehow i cannot find a working solution for me.
I'm collecting different values from my smarthome in an mysqldb. To run some analysis on the data i need to round a datetime value in one usecase. I must get rid of the seconds.
What I tried/found where different approaches (even via Unixtime) but nothing solved my issue. Within this forum i found an old thread with the following hint:
extract from my insert script:
CONVERT(
CONCAT(
date(`detailed-data-integration`.`timestamp`),
' ',
SEC_TO_TIME((ROUND(TIME_TO_SEC(`detailed-data-integration`.`timestamp`)/60)) * 60)
) , Datetime) AS `timestamp-rnd`
This looks fine and works on the first view, but:
Timestamp: 2018-02-03 23:59:56 leads to a NULL because of an invalid datetime value. The function wants to create: 2018-02-03 24:00:00 which is wrong.
Can somebody of you give me a hint how to handle / solve this issue?
Thx and KR

i identified a solution which will work for my requirements which i want to share with you:
CASE
when second(`detailed-data`.`timestamp`) >= 30 then DATE_FORMAT(`detailed-data`.`timestamp`, '%Y-%m-%d %H:%i:00') + interval 1 minute
when second(`detailed-data`.`timestamp`) < 30 then DATE_FORMAT(`detailed-data`.`timestamp`, '%Y-%m-%d %H:%i:00')
END as testcase

Why are you using time_to_sec()? You should be using to_seconds()
'0000-01-01' + interval round(to_seconds(`detailed-data-integration`.`timestamp`)/60)) * 60) second - interval 1 day as `timestamp-rnd`
In other words, don't separate the date from the time. Just handle the entire date/time as a single value.

Related

DATE type comparison in MySQL

Had a bit unintuitive case right now with MySQL:
the query contains where clause with comparison: WHERE t.date = '2016-12-31' (t.date-s datatype is DATE(!)).. And it returns no records on execution. But the query: WHERE t.date > '2016-12-31' - returns the records with date equals '2016-12-31' among other records! The record for 2016-12-31 also showed up in case I've used BETWEEN '20161231' AND '20170101'. Tried formattings, type changes - nothing helped. After some time spent on searching for cause I did the following: updated the record's date column manually, SETting it to '2016-12-31'. After this action WHERE t.date = '2016-12-31' started to work as expected.
Probably I'm missing something, wondering what can cause such behavior.
Update
date is DATE, not DATETIME
After doing manual update I can't reproduce the mentioned behavior again: now any type of comparison(=, DATE(..)=, STRCMP) - works as it should!
Update 2
For 2016-11-30 and 2016-09-30(end of months!) found the same behavior! Won't update the record manually for now to test the suggestions I get here.
Update 3
I've also run OPTIMIZE TABLE on the table with that date column to rebuild indexes for elimination any problems with corruption.
Update 4
Here is more:
if I check HEX values for the date field for incorrect fields(end of month) I get wrong values!
SELECT HEX(t.date) FROM table t WHERE t.date BETWEEN DATE('20160930') AND DATE('20161001');
Returns:
323031362D31302D3030
323031362D31302D3031
SELECT HEX(DATE('20160930'));
Returns:
323031362D30392D3330
And 323031362D30392D3330 != 323031362D31302D3030
SELECT X'323031362D31302D3030';
And it returns:
2016-10-00, NOT 2016-09-30!
For the value that I've updated manually - HEX is same.
But what can cause such difference?
Try forcing the format using
WHERE date(t.date) = '2016-12-31'
or
WHERE date(t.date) = str_to_date( '2016-12-31', '%Y-%m-%d')
or based on your test
WHERE date(t.date) = str_to_date( '20161231', '%Y%m%d')
After some investigation I've found the problem and its not related directly to the date comparison in MySQL. I'll post it here in case anyone is stuck at such case.
I've found that the problem was with selecting results in IDE (in my case DataGrip): the value for date field in database was 2016-10-00 and select was returning 2016-09-30! That was confusing.. But after the 00 DAY was found - it was relatively easy to find the cause of it: CURDATE() - 1 (in my case there should have been: CURDATE() - INTERVAL 1 DAY). Don't ever use date related functionality without specific functions like INTERVAL!!
Thanks to everyone who supported the question, sorry for confusion, I was confused too and found the answer only after several steps.

How to add extra 5 minutes in mysql using query

I'm new for mysql, Already value in time field, I want to update extra 5 minutes in time field using query. I tried so many things but not working.
Here my query:
UPDATE STUDENT SET START_TIME = ADDTIME(START_TIME, 500) WHERE ID = 1;
Above query working but one issue is there that is, If my field having 23:55:00.
I want result after executing query 00:00:00 but it updates 24:00:00.
Anyone help me!
Thanks in advance!!
This is bit tricky, because you only have the time, and you want it to wrap around to 0 after hitting 24 hours. My approach is to extract the number of seconds from START_DATE, add 5 minutes, then take the mod of this by 24 hours to wrap around to zero if it exceeds one day's worth of seconds.
UPDATE STUDENT
SET START_TIME = CAST(STR_TO_DATE(CAST(MOD((TIME_TO_SEC(START_TIME) + 300), 86400) AS CHAR(5)), '%s') AS TIME)
WHERE ID = 1
In the demo below, you can see the logic in action which correctly converts 23:55:00 with five minutes added to become 00:00:00.
SQLFiddle
However, the easiest solution in your case might be to just use a DATETIME and ignore the date component. Then the time should wrap automatically to a new day.
select addtime('23:55:00', '00:06:00');
output - 24:01:00 (Ideally it is right, because time datatype represents only time, if it converts to 00:01:00 then time component looses 24hr, which is wrong)
select addtime('2016-09-01 23:55:00', '00:06:00');
output - 2016-09-02 00:01:00 (In this case, 24hr gets added in date so time component is represented as 00:01:00)
If the requirement is to get it as 00:01:00 then here is the workaround -
SELECT TIME((ADDTIME(TIME('23:59:59'), TIME('02:00:00')))%(TIME('24:00:00')));
reference -
ADDTIME() return 24 hour time

MySql - Calculating distance in time using 2 values from 1 column (Poor design workaround)

I was granted access to a legacy database in order to do some statistics work.
I've so far gotten everything I need out of it, except I am trying to calculate a distance in time, using 5 values, stored in 4 columns (ARGGGHHH)
Above is a subsection of the database.
As you can see, I have start and stop date and time.
I would like to calculate the distance in time from str_date + str_time to stp_date + stp_time
The issue I have is, the calculation should be performed differently depending on the second value in stp_time.
IFF second value = "DUR".... THen I can just take the first value "01:04:51" in this scenario
IFF second value = anything else. stp_time represents a timecode and not a duration. This must then calculate stp_time - str_time (accounting for date if not same date)
All data is 24 hour format. I have done work with conditional aggregation, but I have not figured this one out, and I have never worked with a malformed column like this before.
Any and all advice is welcome.
Thanks for reading
SELECT
CASE WHEN RIGHT(stp_time,3)="DUR"
THEN
TIMEDIFF(LEFT(stp_time,8), '00:00:00')
ELSE
TIMEDIFF(
STR_TO_DATE(CONCAT(stp_date," ",LEFT(stp_time,8)), '%d/%b/%Y %H:%i:%s'),
STR_TO_DATE(CONCAT(str_date," ",LEFT(str_time,8)), '%d/%b/%Y %H:%i:%s')
)
END AS diff
FROM so33289063
Try this out, you might want a where condition for the subquery
With left and right:
SELECT IF(dur,stp,timediff(str,stp)) FROM(
SELECT STR_TO_DATE(CONCAT(str_date," ",LEFT(str_time,8)), 'd%/%b/%Y %H:%i:%s') as str,
STR_TO_DATE(CONCAT(stp_date," ",LEFT(stp_time,8)), 'd%/%b/%Y %H:%i:%s') as stp,
if(RIGHT(stp_time,3)="DUR",1,0) as dur
FROM my_table
) AS times

What instead of CONVERT(TIME, x) Datepart?

I have complicated query over very big table.
Long story short, when I use convert time to select period of day (let's say 12-13h, converting it from datetime row) query takes few minutes, instead of few seconds without convert!
So, I tried datepart, and it works well, almost instant, but, problem is, how to point to hours and minutes in same time?
Any other fast solution is more than welcome.
Thanks.
Meanwhile I came up with this:
DATEPART(HOUR, datetimecolumn)*100 + DATEPART(MINUTE, datetimecolumn)) between 1210 and 1540
You can use datePart if you are willing to do a bit of math, as shown below:
12:10 = 12 * 60 + 10 = 730 minutes
15:40 = 15 * 60 + 40 = 940 minutes
select * .....
where datepart(mi, datefield) between (12*60+10) and (15*60+40)
If you have a constant periods - i.e. - always hourly and no any floating periods - you may introduce something like "ordinal number of period" calculated field, index on it and query of it with precalculated period value
OR
is there are no any constant periods - try to calculate proper begin and end values prior to SELECT statement and use them in the query.
Keep in mind that using functions in where clause of query - sometimes is a bad idea. Using functions in ORDER BY clause - always bad
You can get GETTIME from following Function
alter function GetTimeOnly(#_DateTime DateTime)
returns datetime
as
begin
return dateadd(day, -datediff(day, 0, #_datetime), #_datetime)
end
go
OR YOU CAN HAVE THE TIME FROM CONVERT FUNCTION.
SELECT
CONVERT(VARCHAR(8),GETDATE(),108) AS HourMinuteSecond,
CONVERT(VARCHAR(8),GETDATE(),101) AS DateOnly

Select data based on timestamp and interval from mysql

In joomla, it has jos_session table in which time is stored as unixtimestamp in 'time' column.
I want to select the records which are older then a week or two days, basically any interval.
Not much hands on DB, but i did tried with date_sub, but it seems taking date as an argument. So I also tried using FROM_UNIXTIME to convert, but nothing seems to be working.
The last query I tried was
SELECT username FROM jos_session WHERE DATE_SUB(FROM_UNIXTIME(time,'Y-m-d'), INTERVAL 2 DAY );
But it seems to giving empty set and many warnings!
Can anyone please help!
Thanks in advance,
Tanmay
Try this. It should work:
SELECT
username
FROM
jos_session
WHERE
TO_DAYS(FROM_UNIXTIME(CAST(timeAS UNSIGNED))) < TO_DAYS(FROM_UNIXTIME(UNIX_TIMESTAMP()))-2