MYSQL time diff - mysql

I'm trying to calculate time diff between two time fields. Because the fields are just time with no date, I can't use timestampdiff, so I'm using timediff() or subtime(). The only problem with those is when the second time is less than the first time, it returns a negative timediff for me. I understand it's taking the times as the same day times, but is there any way to get a behavior where it always calculates the time forward? For example, I have 23:00:00 and 07:00:00.
timediff('07:00:00','23:00:00') will return a negative value, because 23:00 is greater than 07:00, but I want to get 8 hours as the return. Is there any way I can do that?

You can achieve that with an if statement:
select if(dateA > dateB,
timediff(dateA, dateB),
addtime(timediff(dateA, dateB), '24:00:00.000000'))
This way, if the first date is smaller than the second, you add 24 hours to the difference.

Related

How to calculate 20% change within one hour in Zabbix?

I have to compare two values changing in both directions (rising and falling) within an hour (items amount, for example). What formula may I use to calculate if the amount drops or rises on more than 20%? Does Zabbix calculated value support if conditions to support positive and negative change or it's possible to bypass it?
I'm trying to write something like this:
{api20prod:mysql.get_active_offers.count(0)}/{api20prod:mysql.get_active_offers.count(,,,1h)}*100 > 20
but what if mysql.get_active_offers.count(0) more than mysql.get_active_offers.count(,,,1h) ?
You cannot use a "Simple Change" preprocessor because:
If the current value is smaller than the previous value, Zabbix
discards that difference (stores nothing) and waits for another value.
If you set the item with a 1h check interval (or with scheduled intervals at a specific minute of every hour), you can do the trick with the last() function.
Let's say that at 12:00 your item equals 25 and at 13:00 it equals 38:
At 13:00 invoking last() without parameters will return 38
At 13:00 invoking last(#2) will return 25
You can calculate the hourly readings delta % with:
100 * ({api20prod:mysql.get_active_offers.last()} - {api20prod:mysql.get_active_offers.last(#2)}) / {api20prod:mysql.get_active_offers.last(#2)}
This syntax should work either in a trigger or in a calculated item, choose the one that suits you better: I suggest a calculated item.
Of course, your trigger will have a double condition: you need to match "> 20" OR "< -20"
If you don't want to change the item's check interval you can use the avg() function, see the documentation.

TIMESTAMPDIFF giving unexpected result

Why is
TIMESTAMPDIFF(MONTH, '2015-12-25', '2016-02-24')
giving me 1? I would expect 2016-01-25 to be 1.
My guess is that it is actually returning something like 1.999 months and it is being simply rounded down.
How can I work around this? Or is there another function to use.
I tried PERIOD_DIFF but it does not take into account days
PERIOD_DIFF(DATE_FORMAT('2016-02-24','%Y%m'),DATE_FORMAT('2015-12-25','%Y%m'))
According to the documentation, the unit for the result is an integer, in your case it will return the whole number of months between the two dates, which is one (as the second month is not yet completed).

How can I tell how many minutes have passed between Now() and 7am that day?

Basically I just need to know how much time has passed from a certain time that day till Now() this will be run on a timer throughout the day and used to determine when something should be run (this might seem odd but there is logic behind it).
The issue with the code below is that it gives me a very high negative number. I can only assume that this is caused from the TimeSerial not actually containing a date and only the time so it throws everything off.
Can anyone point me in the direction of a way to do what I want? I am certain that the answer is something super simple that I am missing but I haven't been able to find it.
DateDiff("n",Now(),TimeSerial(07,0,0))
You want the number of minutes from 7 AM until now. Your DateDiff had those two swapped around and that's why you got a negative value.
The reason the magnitude of that number was so large is you were asking for the difference between 07:00 on Dec 30 1899 and today. This is what that TimeSerial expression gives you ...
? Format(TimeSerial(07,0,0), "mmm d yyyy, hh:nn:ss")
Dec 30 1899, 07:00:00
I think this is what you want instead ...
DateDiff("n", Date + #07:00#, Now)

Get the next xx:30 time (the next half-past hour) after a specified time

I'm trying to find a MySQL query which will obtain the time that is the next half-past-the-hour from a specified datetime. I explicitly mean the next half-past-the-hour, not the next half-hourly point.
So for instance:
If the datetime was "2009-10-27
08:15:24", the answer would be
"2009-10-27 08:30:00"
If the
datetime was "2009-10-27 08:49:02",
the answer would be "2009-10-27
09:30:00".
I came across this page which refers to SQL Server, and towards the end of that thread there is a similar sort of problem. But it's not quite the same, and it relies on a function that MySQL doesn't have.
Here is a fuller list of examples and expected return values:
2009-10-27 08:15:24 should return 2009-10-27 08:30:00
2009-10-27 08:49:02 should return 2009-10-27 09:30:00
2009-10-27 23:49:10 should return 2009-10-28 00:30:00
2009-10-27 10:30:00(.000001) should return 2009-10-27 11:30:00
(Note how, in the fourth example, because the exact half-past (10:30:00.0000000) has already gone, the next half-past-the-hour point is found.)
I tried using this kind of thing:
SELECT IF( (MINUTE(NOW()) < 30), HOUR(NOW()), (HOUR(NOW()) + 1) )
(after which addition of a CONCATed string would take place), but it would fail because of the changeover to another day, and it feels inherently 'hacky'.
Can anyone suggest a suitable sort of algorithm? I wouldn't expect a full answer (though that would be nice!), but suggestions as to the kind of algorithm would be helpful. I've been drawing over bits of paper for two hours now! I have a hunch that using modulo might be useful but I'm not sufficiently familiar with using it.
The answer will be fed to a PHP class later, but I'd rather implement this at SQL level if possible, as the rest of query also performs other date comparison functions efficiently.
This is a little messy, but works:
select from_unixtime( floor((unix_timestamp(MY_DATE)+(30*60))/(60*60))*(60*60) + (30*60) )
It pushes the time forward 30 minutes, then truncates to the top of the hour, then adds 30 minutes to it. Because it's working unix timestamps (seconds since 1970), you don't have to worry about the boundaries of days, months, years, etc.
I can't help but notice that this would be much easier at the PHP level :-) That said, here's what you can do:
Add 30 minutes to your datetime using DATE_ADD(); this will move to the next hour if it's already past half-hour
Create a new datetime value by extracting date / hour and hard coding minutes / seconds. CONVERT(), ADDTIME() and MAKETIME() all help.
The end result is:
select ADDTIME(
CONVERT(DATE(DATE_ADD(yourDateTime, INTERVAL 30 MINUTE)), DATETIME), # date part
MAKETIME(HOUR(DATE_ADD(yourDateTime, INTERVAL 30 MINUTE)), 30, 0) # hour + :30:00
) from ...
Use the MAKETIME(hour,minute,second) function to construct the desired value.

timediff is greater than 2 minutes

I am trying to write a query where I can eliminate a timediff of less than 2 minutes. I have tried variations on the following which returns no results
timediff(sessions.producer_on,sessions.producer_off)>'00:02:00'
the timediff without the > works fine and returns all results - I am having difficulty with the >00:02:00 condition. Can anyone help - many thanks
You need to extract the minute from the time then compare it.
minute(timediff(sessions.producer_on,sessions.producer_off)) > 2 AND
hour(timediff(sessions.producer_on,sessions.producer_off)) = 0
Also it may be necessary to make sure that the hour is 0 since only when the hour is zero does the minute actually matter.
This is probably the "old way" but it eliminates the need to check hours, days, etc.
UNIX_TIMESTAMP(fieldOne) - UNIX_TIMESTAMP(fieldTwo) < 120
You can also use NOW() in place of a field name.
Change it to
timediff(sessions.producer_on,sessions.producer_off) > TIME('00:02:00')
and it should work.
SELECT * FROM e_email_otp WHERE TIMEDIFF('2019-01-11 10-46-19',`2019-01-11 10-45-19`) <'00:02:00.000000'