Difference between NOW(), SYSDATE() & CURRENT_DATE() in MySQL - mysql

What difference between NOW() , SYSDATE() , CURRENT_DATE() in MySQL and where it can be used in real scenario .
I tried NOW(),SYSDATE(),Current_Date() when I insert data into a table and column datatype is TIMESTAMP all are given same date and time.

Current_date() will only give you the date.
now() give you the datetime when the statement,procedure etc... started.
sysdate() give you the current datetime.
Look at the seconds after waiting 5 seconds between now()1 sysdate()1 with the following query (scroll to the right):
select now(),sysdate(),current_date(),sleep(5),now(),sysdate();
-- will give
-- now() sysdate() current_date() sleep(5) now()1 sysdate()1
-- 6/10/2014 2:50:04 AM 6/10/2014 2:50:04 AM 6/10/2014 12:00:00 AM 0 6/10/2014 2:50:04 AM 6/10/2014 2:50:09 AM

NOW() returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger, NOW() returns the time at which the function or triggering statement began to execute.) This differs from the behavior for SYSDATE(), which returns the exact time at which it executes.
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+

Current_date returns the time stamp of the client while sysdate returns the time stamp of the server. If both server and the client are on the same machine, then, the result of both commands are the same. But in case that your sever is for example in USA and your clients are in China, then, these two functions return completely different results.
I don't know about thew now(), sorry :-)

One of the major differences between sysdate() and now() recently bit me in the behind. It was the difference in the point-in-time and frequency of their execution. sysdate() is evaluated every time within the same statement--ie, in every row to which it applies. But now() will only be evaluated only once, which is at the start of query execution.
This difference isn't noticeable when there are only a few rows. But it's very significant when there are millions of rows. In RHEL7, for example, sysdate() apparently makes a costly system call, so that when there are millions of rows, using sysdate() took more than an hour, but using now() in the exact same statement took only several seconds!
This is on top of precision issues, because sysdate() will return a different value, for example, between time t and time t+50 millis.
With regard to curdate(), I was also wondering how it's different from either now() or sysdate(). The MySQL Reference says that, with regard to when and how many times it's executed, curdate() behaves like now().
Reference: MySQL 5.7 Reference - Date and Time Functions -- All of the above is described in this page. However, it's scattered on the page, so you'll have to read through the overview section as well as the reference for each function.

CURRENT_DATE() is a synonym for many other similar functions all of which provide only the date.
There is a subtle difference between NOW() and SYSDATE() which you can read up more on this official MySQL website page.

CURRENT_DATE is static and works better with date indexes.
NOW() seems dynamic and does not benefit from index. (I would love to hear a comment on the subject with more detail on the MySQL internals here!)
Here's a real-world example using NOW():
explain SELECT DISTINCT e.manager_id, m.manager_name FROM events e JOIN manager m ON m.manager_id = e.manager_id
WHERE m.manager_name != '' AND e.event_when > NOW() - INTERVAL 1 YEAR;
+---------+----------+------------------------------+
| rows | filtered | Extra |
+---------+----------+------------------------------+
| 1333648 | 29.06 | Using where; Using temporary |
| 1 | 90.59 | Using where |
+---------+----------+------------------------------+
You can see the number of rows are reduced substantially using CURRENT_DATE (or CURRENT_TIMESTAMP):
explain SELECT DISTINCT e.manager_id, m.manager_name FROM events e JOIN manager m ON m.manager_id = e.manager_id
WHERE m.manager_name != '' AND e.event_when > CURRENT_DATE - INTERVAL 1 YEAR;
+--------+----------+----------------------------------------+
| rows | filtered | Extra |
+--------+----------+----------------------------------------+
| 361470 | 100.00 | Using index condition; Using temporary |
| 1 | 90.59 | Using where |
+--------+----------+----------------------------------------+

NOW() returns a constant time that indicate's the time at which the statement began to exicute whereas SYSDATE () returns the time at which it exicute... OR in other words NOW ()shows query exicution time and SYSDATE() shows self exicution time..

Related

What happens if you add an integer to a datetime in mysql?

I know that the code is incorrect and that the ADDDATE function should be used, but I'm trying to find out if a specific behaviour is caused by this bug.
So, does anyone know what exactly happens if I have the statement
SELECT * FROM MyTable WHERE TheTimestamp > (NOW()-86400);
when TheTimestamp is of the datetime data type?
It's not a bug. You're just expecting a datetime cast to a number to be something it's not.
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-literals.html says:
MySQL recognizes DATETIME and TIMESTAMP values in these formats:
...
As a number in either YYYYMMDDhhmmss or YYMMDDhhmmss format, provided that the number makes sense as a date. For example, 19830905132800 and 830905132800 are interpreted as '1983-09-05 13:28:00'.
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-types.html says:
MySQL automatically converts a date or time value to a number if the value is used in numeric context and vice versa.
So using NOW() in an arithmetic expression converts it to a number:
mysql> SELECT now(), now() + 0;
+---------------------+----------------+
| now() | now() + 0 |
+---------------------+----------------+
| 2022-10-19 14:13:14 | 20221019141314 |
+---------------------+----------------+
You can see this converts '2022-10-19 14:13:14' (the date and time I test this query) into an integer simply by removing the punctuation and whitespace. This isn't a number you can add or subtract with, because the values 60-99 aren't used for seconds or minutes, and likewise the values 24-99 for hours, 32-99 for days, 13-99 for months, etc.
The expression you showed doesn't produce a number that is valid as a timestamp:
mysql> SELECT now(), now() - 86400;
+---------------------+----------------+
| now() | now() - 86400 |
+---------------------+----------------+
| 2022-10-19 14:20:09 | 20221019055609 |
+---------------------+----------------+
^^ there is no time with 56 minutes
^^^^ yesterday's date should be 10/18
To do arithmetic on the datetime, you should either convert to a integer measure of seconds, then use that value in integer expressions:
mysql> SELECT now(), unix_timestamp(now());
+---------------------+-----------------------+
| now() | unix_timestamp(now()) |
+---------------------+-----------------------+
| 2022-10-19 14:16:57 | 1666214217 |
+---------------------+-----------------------+
Or else use MySQL's support for temporal INTERVAL expressions. See https://dev.mysql.com/doc/refman/8.0/en/expressions.html#temporal-intervals
mysql> select now(), now() - interval 86400 second;
+---------------------+-------------------------------+
| now() | now() - interval 86400 second |
+---------------------+-------------------------------+
| 2022-10-19 14:24:01 | 2022-10-18 14:24:01 |
+---------------------+-------------------------------+
DATETIME and TIMESTAMP values are implicitly integer values of 5 and 4 bytes in length respectively (with optional additional bytes for fractional seconds precision). Mathematical operators, as well as conditional operators, will work accordingly. However, this will not account for all the implicit conversions like when you use ADDTIME().
This operation specifically looks for any records created later than 1 day ago, since the DATETIME value has to be greater than (later in time) the current time - 86400 seconds (1 day/24 hours) ago.

Select a record based on timestamp

I have a table that has a column row filled with a Javascript's, Date.now() function.
The column name is update_time, and its sample value is 1571152209099.
How can I make a Select for all rows that have todays date (taking into account only year, month and a day)?
I have tried something like this, but it get's me nowhere.
Select *
from program_end
where workout_rate between 0 and 1
AND FROM_UNIXTIME(update_time, '%YYYY-%MM-%DD') = CURDATE()
I also tried changing the time format:
Select *
from program_end
where FROM_UNIXTIME(update_time, '%Y-%m-%d') = CURDATE()
But no result whatsoever.
Any insight is appreciated.
For insight, consider:
SELECT '1970-01-01' + INTERVAL ( 1571152209099 /1000) SECOND
returns:
_dt
--------------------------
2019-10-15 15:10:09.099000
We recognize that the 1571152209099 value from JavaScipt Date.now() is integer milliseconds from the beginning of the era (Jan 1, 1970 midnight UTC).
Also consider:
SELECT TIMESTAMPDIFF(SECOND,'1970-01-01 00:00','2019-10-15 00:00')*1000 AS _dt_1
, TIMESTAMPDIFF(SECOND,'1970-01-01 00:00','2019-10-16 00:00')*1000 AS _dt_2
returns:
_dt_1 _dt_2
------------- --------------
1571097600000 1571184000000
The TIMESTAMPDIFF function is returning a difference in seconds; we multiply by 1000 to get milliseconds.
We recognize that any JavaScript Date.now() milliseconds value that is greater than or equal to _dt_1 and is less than _dt_2 occurs sometime "on" the date '2109-10-15'
So, given update_time is milliseconds since the beginning of the era...
In a query, I would compare the bare update_time column to two literal values:
WHERE update_time >= 1571097600000
AND update_time < 1571184000000
Referencing the bare column has the advantage that MySQL can make use of an efficient range scan operation, with a suitable index available.
To derive those millisecond values from a given date value, we can do a calculation in an expression, like this:
WHERE update_time >= TIMESTAMPDIFF(SECOND,'1970-01-01', '2019-10-15' )*1000
AND update_time < TIMESTAMPDIFF(SECOND,'1970-01-01', '2019-10-15' + INTERVAL 1 DAY)*1000
^^^^^^^^^^
Those expressions on the right side get evaluated just one time at the start of the statement execution.
Note that if we wrap update_time in a function, then that function has to be evaluated for every value of update_time, for every row in the table (that isn't filtered out by some other predicate.)
If you don't have dates in the future, you can simply do:
WHERE update_time >= UNIX_TIMESTAMP(CURDATE())
This will happily use an existing index on update_time.
If you have dates in the future that you need to exclude from the resultset, then:
WHERE
update_time >= UNIX_TIMESTAMP(CURDATE())
AND update_time < UNIX_TIMESTAMP(CURDATE() + INTERVAL 1 DAY)
Javascript's Date.now is giving you milliseconds, whereas MySQL's FROM_UNIXTIME expects seconds.
Unable to understand the epoch timestamp in milliseconds, FROM_UNIXTIME is returning NULL, which is of course failing to match the current date.
mysql> SELECT FROM_UNIXTIME(1571152209099);
+------------------------------+
| FROM_UNIXTIME(1571152209099) |
+------------------------------+
| NULL | -- THIS IS YOUR PROBLEM
+------------------------------+
1 row in set (0.00 sec)
mysql> SELECT FROM_UNIXTIME(1571152209099/1000);
+-----------------------------------+
| FROM_UNIXTIME(1571152209099/1000) |
+-----------------------------------+
| 2019-10-15 10:10:09.0990 |
+-----------------------------------+
1 row in set (0.00 sec)
Try this:
FROM_UNIXTIME(FLOOR(update_time/1000), format...)

mysql between 2 dates does not working with 2 different months

Hello i need expert advice for my mysql query
I'm trying to filter values between 2 months
If start day lower then end day of different months all working well
But if i try higher day value on start return none
this is working code
SELECT id, teslim_tarihi AS tarih, toplam, marka, model, malzeme
FROM ariza
WHERE durum = '7' AND (teslim_tarihi BETWEEN '01-02-2018 00:00' AND '01-03-2018 23:59')
ORDER BY tarih DESC
Not working at all
SELECT id,teslim_tarihi as tarih ,toplam,marka,model,malzeme
FROM ariza
WHERE durum = '7' AND (teslim_tarihi BETWEEN '14-02-2018 00:00' AND '01-03-2018 23:59')
ORDER BY tarih DESC
date format dd-mm-yyyy H:i
As has been suggested by #stackFan, it really does make considerable sense to stick with mysql's default date and time formats. However, for whatever reason, you seem to be stuck with a different format so I'll attempt to work with that.
Your current query isn't working in your second example because mysql doesn't recognise these as dates and a strings starting '14-02-2018' is greater than another string starting '01-03-2018'. e.g.
SELECT '14-02-2018' > '01-03-2018';
+-----------------------------+
| '14-02-2018' > '01-03-2018' |
+-----------------------------+
| 1 |
+-----------------------------+
The values when using BETWEEN ... AND have to have the min value first and the max value Documentation, so in your second example the comparison is the wrong way round because '14-02-2018' is greater than '01-03-2018', hence no rows returned.
You didn't answer the query about the data type of your column teslim_tarihi which would have made answering your query simpler. I'll assume it is a DATETIME or TIMESTAMP. Your comparison should be made against something that mysql knows to be a date or recognises as a date and that means getting the dates into YYYY-MM-DD or YY-MM-DD format. Mysql will helpfully cast values to the appropriate type if the format is one it recognises. e.g.
SELECT DATE '2018-02-14' < '2018-03-01';
+-----------------------------------+
| DATE '2018-02-14' < '2018-03-01' |
+-----------------------------------+
| 1 |
+-----------------------------------+
You should be able to get the query working by turning your strings into dates in the following manner.
SELECT DATE '2018-03-01'
BETWEEN STR_TO_DATE('14-02-2018 00:00', '%d-%m-%Y %H:%i')
AND STR_TO_DATE('01-04-2018 23:59','%d-%m-%Y %H:%i') 'between dates';
+---------------+
| between dates |
+---------------+
| 1 |
+---------------+
If your column teslim_tarihi is a VARCHAR, then convert that in the same manner to get the query to work.
As per the documentation the default format of date in MySQL is YYYY-MM-DD. Can you try using this query instead?
SELECT id,teslim_tarihi as tarih ,toplam,marka,model,malzeme
FROM ariza
WHERE durum = '7' AND (teslim_tarihi BETWEEN '2018-02-14 00:00:00' AND '2018-03-01 23:59:59')
ORDER BY tarih DESC

Possibly Mysql 5.6.20 bug. Date - now()?

date_newOrd, now(), date_newOrd-now() AS `time`
this is my query. date_newOrd is type date. I try to calculate the time remaining for next arrival of order. I better show you the screenshot:
the result is doesn't make any sense. What am i supposed to do>
You cannot subtract dates like that:
mysql> select '2015-06-01 18:20:03' - now();
+-------------------------------+
| '2015-06-01 18:20:03' - now() |
+-------------------------------+
| -20150602073525 |
+-------------------------------+
While that may look (vaguely) like a date, it's really an integer, and can't be used for further date math without extra processing.
You have to use datediff() or timediff():
mysql> select timediff('2015-06-01 18:20:03', now()) as td, datediff('2015-06-01 18:20:03', now()) as dd;
+-----------+------+
| td | dd |
+-----------+------+
| -13:37:47 | -1 |
+-----------+------+
note that datediff deals only with DATES, and timediff deals with datetime values.
When you do a subtraction, MySQL is going to evaluate NOW() in a numeric context, it returns a numeric value.
SELECT NOW()+0
20150602135210.000000
So, your statement is doing a subtraction of numbers, not doing a DATE calculation.
Some possibilities:
You could convert the datetime values into unix_timestamp values, (UNIX_TIMESTMAP() function) and then do a subtraction of those to get a difference in integer seconds.
The DATEDIFF() function would get you a difference in integer days. (That operates only on the date portion, it ignores the time... so that probably doesn't give you the resolution you are looking for.)
The TIMESTAMPDIFF() and TIMEDIFF() functions are also available. (The TIMEDIFF functions returns a TIME datatype value; the maximum value of that datatype is 838:59:59, so that's limited to just under 35 days elapsed).
For example:
SELECT UNIX_TIMESTAMP('2015-06-03') - UNIX_TIMESTAMP(NOW()) AS secs
secs
-------
35856

DATETIME comparisons?

I'm trying to switch from using UNIX timestamps to DATETIME columns in MySQL and am having a little trouble finding the correct way to make comparisons between dates.
I tried using the + and - operators to compare two DATETIMEs and the results don't make any sense to me.
For example:
1.
SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() - INTERVAL 1 HOUR
Outputs
2014-07-06 19:19:13 | 2014-07-06 18:19:13
These
SELECT UTC_TIMESTAMP() - DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 HOUR)
SELECT UTC_TIMESTAMP() - (UTC_TIMESTAMP() - INTERVAL 1 HOUR)
Both output 10000. This number doesn't make sense to me, but then it gets more confusing as this:
SELECT UTC_TIMESTAMP()-DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 SECOND)
Outputs 1. Why is that? What does that number represent?
2.
The manual page for date and time functions shows DATE_ADD() and DATE_SUB() can be used to add and subtract intervals from dates, but I don't see any functions in the manual that correspond to the great than and less than operators, so how would I check to see if the current date is greater than some other date?
I tried using the < and > operators and they seem to work, but I can't seem to find anything on this in the manual and want to make sure it's OK to use these operators like this:
SELECT UTC_TIMESTAMP() > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 HOUR)
Can anyone demystify DATETIME comparisons in MySQL?
To quote the documentation about UTC_TIMESTAMP():
Returns the current UTC date and time as a value in 'YYYY-MM-DD
HH:MM:SS' or YYYYMMDDHHMMSS format, depending on whether the function
is used in a string or numeric context.
Because the value is being used in the context of a number, it is treated as a number, which is the behavior that you see.
I've just found this out myself, but here's a quick example that shows you how it works.
#GordonLinoff's answer is neither here nor there, because your question isn't really about the format returned from utc_timestamp(). What you're really asking is what format does MySQL return when you use numeric operands + and - on timestamps.
I tend to agree with you that the documentation is a bit fuzzy on the topic. But this is what I found. You can build this view yourself to see the example in simpler terms.
create view cbhview as
select utc_timestamp() as nowtime,
utc_timestamp() - interval 1 hour as thentime,
date_sub(utc_timestamp(),INTERVAL 1 HOUR) as thentime2,
date_sub(utc_timestamp(),INTERVAL 1 SECOND) as justthentime;
select nowtime, thentime, thentime2, justthentime,
nowtime-thentime,
nowtime-justthentime,
thentime-thentime2
from cbhview;
+---------------------+---------------------+---------------------+---------------------+------------------+----------------------+--------------------+
| nowtime | thentime | thentime2 | justthentime | nowtime-thentime | nowtime-justthentime | thentime-thentime2 |
+---------------------+---------------------+---------------------+---------------------+------------------+----------------------+--------------------+
| 2014-07-06 20:22:58 | 2014-07-06 19:22:58 | 2014-07-06 19:22:58 | 2014-07-06 20:22:57 | 10000 | 1 | 0 |
+---------------------+---------------------+---------------------+---------------------+------------------+----------------------+--------------------+
1 row in set (0.00 sec)
100000 represents 1h 00min 00second
1 represents 1second
0 represents no difference between the two
In short, unless you know exactly what you're doing and exactly what you're trying to achieve, don't use numeric operands on date and timestamp datatypes. Keep to the functions that have been designed for the purpose date_add() and date_sub().