Below is the CREATE TABLE statement used to create my table:
CREATE TABLE IF NOT EXISTS `data_received` (
`id` int(10) unsigned NOT NULL,
`edit_time` datetime NOT NULL}
Below is how data is saved in table if 'edit_time' value is not provided:
id edit_time
1 0000-00-00 00:00:00
Now, if I execute the following statement:
SELECT TIMESTAMPDIFF( HOUR , edit_time, NOW( ) ) AS diff_in_hours
FROM data_received;
I get result: NULL
Can someone please help me understand what is happening?
That is because 0000-00-00 00:00:00 is not a valid DATETIME expression accepted by the function.
Please check documentation.
Use this method to keep edit-time in mysql
`edit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Auto-update time'
Mysql tends to insert rubbish in an attempt to be "helpful". Best to tell it not to do that by settings mysql to STRICT mode so it behaves more like a database should.
SET sql_mode='STRICT_ALL_TABLES'
For details please read the manual.
0000-00-00 00:00:00 will probably interpreted as null. And comparing null in a TIMESTAMPDIFF will lead to null result.
MySQL doc says
In MySQL, the zero date is defined as '0000-00-00', even though this date is itself considered invalid.
There is no zeroth of zero in year zero, so you cannot calculate the time since then:
SELECT TIMESTAMPDIFF(HOUR, '0000-00-00 00:00:00', NOW())
NULL
Apparently MySQL does not have a problem with year 0 itself, as this returns a result:
SELECT TIMESTAMPDIFF(HOUR, '0000-01-01 00:00:00', NOW())
17643758
Related
Here is my table "tb_posts":
I want to select only those rows where datetime field i.e. post_date_published is not equal to 0000-00-00 00:00:00. I am using following query but it doesn't work:
SELECT * FROM `tb_posts` WHERE `post_date_published` IS NOT NULL
I am getting the same output as shown in the above picture.
Why IS NOT NULL is not working?
As per the MYSQL documentation it saves invalid dates as '0000-00-00 00:00:00'. It will not be considered as NULL.
Try comparing with the date '0000-00-00 00:00:00':
SELECT * FROM tb_posts where post_date_published != '0000-00-00 00:00:00'
A method I use with this sort of thing is
SELECT `columns` FROM `tb_posts` WHERE UNIX_TIMESTAMP(`post_date_published`) > 0
From the MySQL Documentation:
The valid range of argument values is the same as for the TIMESTAMP
data type: '1970-01-01 00:00:01.000000' UTC to '2038-01-19
03:14:07.999999' UTC. If you pass an out-of-range date to
UNIX_TIMESTAMP(), it returns 0.
The UNIX_TIMESTAMP function forces the result to be an integer so it's much easier to work with in these quick comparisons. It is also vital for working with MySQL 5.7 where "empty" (ie zero value) date/time columns are not allowed.
(I had a lot of grief trying to convert various date columns to NULL because MySQL 5.7+ didn't recognise 0000-00-00 00:00:00 as a valid comparison -- so I converted it to a unix timestamp so as to compare the timestamp rather than the actual [invalid] date.)
In mysql Timestamp, I want to convert 0000-00-00 00:00:00 to null.
first I use, set sql_safe_updates = 0;
second I do, UPDATE TABLE SET FILED = NULL WHERE FILED = '0000-00-00 00:00:00';
but it also converts the current time like this: 2018-07-31 13:46:00
what's the problem?
First, change your field definition to allow NULL values. Use the following:
ALTER TABLE <tablename> MODIFY <columnname> TIMESTAMP NULL DEFAULT NULL;
I am trying to use COALESCE() to get the lowest non NULL date with a default to NOW() from the following table:
date1 (timestamp) | date2 (date) | date3 (timestamp)
<null> <null> 2015-02-04 21:29:05
The query I have tried is:
SELECT coalesce(date1, timestamp(date2), date3, now()) as edited
FROM backupDB
#Barmar - No, I cannot reproduce the error in SQLFiddle, the schema and values I truly have breaks their Java.
Solved
I had to dig deeper into how the table was built and find the right schema. This is what I truly have in the DB (though PHPStorm shows "0000-00-00" as a NULL):
CREATE TABLE backupDB (
date1 TIMESTAMP NULL,
date2 DATE DEFAULT '0000-00-00',
date3 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);
INSERT INTO backupDB (date1, date2, date3) VALUES
(NULL, '0000-00-00', '2015-02-04 21:29:05');
So the necessary query looks more like this: (feel free to criticize and improve)
SELECT
coalesce(date1, if(date2= '0000-00-00', null, timestamp(date2)), date3, now()) as edited
FROM backupDB
Is it a better practice to use default date '0000-00-00 00:00:00' or NULL on a MySQL database?
I have read best to use default date '0000-00-00 00:00:00' for the reason of calculations
i.e. >than a date less than a date.
Also on time best to store 00:00 or NULL if time is not known.
MySQL 5.7 defaults to disallowing 0000-00-00 00:00:00 as default value, unless you set sql_mode = ''. It seems MySQL wants you to use NULL as default value.
You should use NULL because 0000-00-00 00:00:00 is not a valid date. If you use libraries such as moment.js or Carbon to manage date, they both know how to deal with NULL dates.
The MySQL configuration should always be set to:
SET sql_mode = 'NO_ZERO_DATE';
unless you have to deal with an old database.
That said, according to MySQL Documentation:
MySQL permits you to store a “zero” value of '0000-00-00' as a “dummy date.” This is in some cases more convenient than using NULL values, and uses less data and index space. To disallow '0000-00-00', enable the NO_ZERO_DATE mode.
If you are on Windows:
“Zero” date or time values used through Connector/ODBC are converted automatically to NULL because ODBC cannot handle such values.
An additional point to consider is: what is the true meaning of a zero date?
Does '0000-00-00' < '2018-12-12'?
Does '0000-00-00' means 'unknown'?
Does '0000-00-00' means 'null'?
Unless your answer is the first one and you need to do comparisons with null dates, using a NULL value is always less confusing.
a default value should be NOT NULL inorder to support all date time operations.
i also uses "0000-00-00 00:00:00" as default value.
I cant seem to get this to work, It returns Null
SELECT sdt, timeFor, DATE_ADD(TIMESTAMP(sdt), INTERVAL timeFor MINUTE) FROM tbl_day
The return keeps returning
sdt, timeFor, DATE_ADD(TIMESTAMP(sdt), INTERVAL timeFor MINUTE)
'0000-00-00 01:00:00', 15, ''
Columns Type
sdt DATETIME
timeFor BIGINT(20)
Any ideas
MySQL usually returns NULL on date/time operations when column value is incomplete datetime. Something like 2010-00-05 11:22:33, etc. Also using timestamp function on sdt column might not be a good idea. I'd suggest providing normal datetime value.