In my MySql table there's a column called _time of type varchar. The values it holds are in the format: year month day hour minute without the whitespaces: 201409201945 I want to convert it to datetime so I'm doing this:
ALTER TABLE `my_table` CHANGE COLUMN `_time` `date_time` DATETIME NOT NULL;
And it throws this error for some reason:
Error Code: 1292. Incorrect datetime value: '201409201945' for column '_date_time' at row 1 0.036 sec
The three steps #Arkain mentioned would be with the help of the function STR_TO_DATE
-- add the new column
ALTER TABLE `my_table` ADD COLUMN `date_time` DATETIME;
-- update the new column with the help of the function STR_TO_DATE
UPDATE `my_table` SET `date_time` = STR_TO_DATE(`_time`, '%Y%m%d%H%i');
-- drop the old column
ALTER TABLE `my_table` DROP COLUMN `_time`;
The complete list of specifiers for STR_TO_DATE can be found at DATE_FORMAT, here an excerpt with those I used:
%d Day of the month, numeric (00..31)
%H Hour (00..23)
%i Minutes, numeric (00..59)
%m Month, numeric (00..12)
%Y Year, numeric, four digits
Demo of the UPDATE
If the new column should have the attribute NOT NOLL, one way could be to set the sql mode before the operation to '' and reset the sql_mode later on:
SET #old_mode = ##sql_mode;
SET ##sql_mode = ''; -- permits zero values in DATETIME columns
ALTER TABLE `my_table` ADD COLUMN `date_time` DATETIME NOT NULL;
UPDATE `my_table` SET `date_time` = STR_TO_DATE(`_time`, '%Y%m%d%H%i');
ALTER TABLE `my_table` DROP COLUMN `_time`;
SET ##sql_mode = #old_mode;
Updated Demo
If your varchar data were formatted like this '2014-09-20 19:45' altering your column's data type would work. Why? that's the character representation used by DATETIME and other time-oriented data types.
But it isn't. So, what choices do you have?
One is to use these four steps:
alter the table to add a new DATETIME column with a temporary name
do an UPDATE with no WHERE clause to fill in the values of that column
alter the table to drop the previous column
alter the table to rename your new column to have the same name as the column you just dropped.
Here's how that would go.
ALTER TABLE my_table ADD COLUMN tempstamp DATETIME
UPDATE my_table SET tempstamp = STR_TO_DATE(_time, '%Y%m%d%H%i')
ALTER TABLE my_table DROP COLUMN _time
ALTER TABLE my_table CHANGE tempstamp _time DATETIME NOT NULL
Another approach: Change the strings in your _time to valid datetime values, then alter your column. If your varchars() are wide enough to hold a few extra characters, try this.
UPDATE my_table SET `_time`=STR_TO_DATE(`_time`, '%Y%m%d%H%i')
ALTER TABLE my_table CHANGE `_time` `_time` DATETIME NOT NULL
This works because STR_TO_DATE() makes DATETIME values of your strings, and then MySQL casts them back to strings to store back into your varchar column. Then you can change the datatype to DATETIME.
You probably noticed I threw in NOT NULL. If you're going to put an index on that column, NOT NULL is a good thing to have. But, if some of your time values are missing, it won't work.
Because the database doesn't know what to do with 201409201945, it's not a valid DateTime format, therefore it can't change it
You can delete the data that is in it already, and then try changing it
Related
Seeing the question you might find it as duplicate. But I have researched and its not.
The problem is I have a column in my table with "TIME" data-type. Now I want to convert the column to "TIMESTAMP".
I have tried using Modify too.
The query
ALTER TABLE `mydb`.`temp_table` MODIFY COLUMN `time` TIMESTAMP
But this doesn't work. The Error I got
Error Code: 1292. Incorrect datetime value: '20:00:00' for column 'time' at row 1
Alter table change column too doesn't work. Is there any way which I can convert the column TIMESTAMP.
The last option that I can see is convert the column to VARCHAR then update appending a date and then convert to timestamp.
UPDATE:
Tried coverting Time to DATETIME. Which gave no error but the data is not correct. After changing the column the time "20:00:00" changed to "2020-00-00 00:00:00"
I think you should add another "TIMESTAMP" column to your table and transfer data from you "TIME" column to new "TIMESTAMP" column. Then you could drop original "TIME" column and rename new column to "TIME".
ALTER TABLE `mydb`.`temp_table` ADD COLUMN `time_stamp` TIMESTAMP;
UPDATE table SET time_stamp = TIMESTAMP(CURDATE(), `time`);
ALTER TABLE `mydb`.`temp_table`
DROP COLUMN `time`;
ALTER TABLE `mydb`.`temp_table`
CHANGE COLUMN `time_stamp` `time` TIMESTAMP;
Try this:
create table test(`time` time);
insert into test values('10:00:00'), ('20:00:00');
alter table test add ts timestamp null;
update test set ts=`time`;
alter table test drop `time`;
alter table test change ts `time` timestamp not null;
I got confused about the alter.
I have an existing table, register and I want to add a this_date column with default value of current date. is it possible by alter? well it has already have data.
It should be okay.
ALTER TABLE ADD COLUMN this_date DATE DEFAULT CURRENT_DATE;
As long as the new column is nullable and/or has a default value, there shouldn't be a problem.
You can also choose where to put the column, use the keyword after:
ALTER TABLE MyTable ADD `MyColumn` DATETIME AFTER `LastColumn`
This wasn't possible for me on MySQL 5.7. It gives me an error every time.
I can do it with a DATETIME field and NOW() as default, but not with CURRENT_DATE.
ALTER TABLE "TableName" ADD "New_Column_Name" TIMESTAMP DEFAULT now();
On MySQL 5.7, I didn't find a way to use CURRENT_DATE or its synonyms as default.
If your application will always provide values in INSERT statements and you only need a way to add a non-null column to existing data and then set values for existing row, you can work around this by providing a fixed default for the non-null date column
ALTER TABLE MyTable ADD COLUMN MyColumn DATE DEFAULT '2020-01-01'
and then update it to CURRENT_DATE
UPDATE MyTable SET MyColumn = CURRENT_DATE
need an advice, how to auto-store datetime value for my historyActivity table in select insert mysql query. This is an example:
INSERT INTO history_sequence(CODE, LAST_MOUNTH, LAST_VALUE) SELECT CODE, MOUNTH, VALUE FROM seq WHERE CODE = CODEVALUE
i just want to add datetime to see time when the data inserted. Need help please
You can do this in the MySQL table definition:
ALTER TABLE history_sequence ADD inserted TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
When records are inserted into the table table, the inserted column gets automatically populated with the current timestamp.
I have 2 columns startdate and enddate of type int. These columns are used to store timestamp data.
Now I have to extract the date component from this timestamp, convert it back to timestamp an store it in another column startdate1 of type int
But on doing this, I get a warning 'Data truncated for column startDate1 at row'.
The sql queries are:-
ALTER TABLE `ServiceRule` ADD COLUMN `startDate1` INT(11) NULL DEFAULT NULL AFTER `endDate` , ADD COLUMN `endDate1` INT(11) NULL DEFAULT NULL AFTER `startDate1`;
update `ServiceRule` set `startDate1`= TIMESTAMP(DATE(from_unixtime(`startDate`)));
update `ServiceRule` set `endDate1`= TIMESTAMP(DATE(from_unixtime(`endDate`)));
Now if i change the datatype of startDate1 and endDate1 to TIMESTAMP, the first update query of startDate1 runs successfully.
But the endDate1 update query shows the warning 'Out of range value for column 'endDate1' at row'.
After browsing for solution, i got know that this occurs if the input value is greater than the column datatype range.
Can anybody please try to help me out?
Thanks in Advance. :)
I think what you want is UNIX_TIMESTAMP instead of TIMESTAMP.
UNIX_TIMESTAMP is the inverse function of FROM_UNIXTIME.
What means that one of the rows contains a value that cannot be converted to int because indeed it is either too more or too less than expected.
Can't you just convert the columns to timestamp and do the extraction from there? Try to query per set of 100 for example and narrow down the faulting row.
When the field startDate is of type int, then alter table statement used is not correct to achieve what you wanted.
Change it as below:
-- keeping the added fields as is, execute the following
ALTER TABLE `ServiceRule` MODIFY COLUMN `startDate1` DATETIME DEFAULT NULL;
ALTER TABLE `ServiceRule` MODIFY COLUMN `endDate1` DATETIME DEFAULT NULL;
update `ServiceRule` set `startDate1`= TIMESTAMP(DATE(from_unixtime(`startDate`)));
update `ServiceRule` set `endDate1`= TIMESTAMP(DATE(from_unixtime(`endDate`)));
I've imported a CSV file into mysql with dates in format dd/mm/yyyy.
I now need a query to convert it from text to date format yyy-mm-dd.
You could use the STR_TO_DATE(str, format) MySQL function.
Example switching out my_date_col for a converted one:
BEGIN;
ALTER TABLE `date_test`
ADD COLUMN `my_date_col_converted` DATE;
UPDATE `date_test`
SET `my_date_col_converted` = STR_TO_DATE(`my_date_col`, '%d/%c/%Y');
ALTER TABLE `date_test`
DROP COLUMN `my_date_col`;
ALTER TABLE `date_test`
CHANGE COLUMN `my_date_col_converted` `my_date_col` DATE;
COMMIT;
You can use STR_TO_DATE() in the following way to convert your text in to a DATE:
STR_TO_DATE( datefield , "%d/%m/%Y" )
If you need this DATE in a specific format, you can use DATE_FORMAT().
This probably isn't necessary in your case, but here's an example for completeness:
DATE_FORMAT( STR_TO_DATE( datefield , "%d/%m/%Y" ) , "%Y/%m/%d" )
So, you could do this over the whole table with a single UPDATE to replace the current data with the reformatted data (while keeping the datatype the same):
UPDATE tableName
SET originalDate = DATE_FORMAT(STR_TO_DATE(originalDate,"%d/%m/%Y" ),"%Y/%m/%d" );
Or, if you want to convert the datatype of the column DATE you could alter the table to create a new DATE formatted column, use the above update to fill that column, remove the original column, and then (optionally) rename the new column to the old name.
ALTER tableName
ADD modifiedDate DATE;
UPDATE tableName
SET modifiedDate = DATE_FORMAT( STR_TO_DATE( originalDate ,"%d/%m/%Y" ) ,"%Y/%m/%d" );
ALTER tableName
DROP COLUMN originalDate;
ALTER tableName
CHANGE COLUMN modifiedDate originalDate;
This should work but it doesn't:
BEGIN;
ALTER TABLE `date_test`
ADD COLUMN `my_date_col_converted` DATE;
UPDATE `date_test`
SET `my_date_col_converted` = STR_TO_DATE(`my_date_col`, '%d/%c/%Y');
ALTER TABLE `date_test`
DROP COLUMN `my_date_col`;
ALTER TABLE `date_test`
CHANGE COLUMN `my_date_col_converted` `my_date_col` DATE;
COMMIT;
Also this should work: Doesn't Work
UPDATE db_test SET anticipated_court_date = DATE_FORMAT(STR_TO_DATE(anticipated_court_date,"%d/%m/%Y" ),"%Y-%m-%d" );
Server version: 5.0.95-community-log MySQL Community Edition (GPL)
However this works:
SELECT STR_TO_DATE('8/31/12', '%m/%d/%Y'); // WORKS
Using MySQL - I couldn't find any solution that worked reliably. Even the same exact date wasn't converted successfully.
The solution I've found is this: PHP
$user_date = "8/31/12"; // WORKS
$mysql_date = date('Y-m-d H:i:s', strtotime($user_date));
The above were helpful, but the following worked for me on Mysql.
ALTER TABLE `tablename` ADD `newcolumn` DATE NOT NULL ;
UPDATE `tablename` SET `newcolumn`=STR_TO_DATE(`oldcolumn`, '%d/%c/%Y')
Now delete the oldcolumn (if you wish).