Background
I have a MySQL db with around 16 million records. There are 2 columns created_at and updated_at which are presently in datetime format.
The Problem
I'd like to change this to UNIX Timestamp by converting all the values and updating the records with the new values.
I know how to do this with PHP in loops, but is there a way to perform this update by executing a single query in MySQL?
As it'll be a one time change; you can proceed this way:
Create new columns with INT datatypes and name them, say, created and updated.
ALTER TABLE `nameOfTable`
ADD COLUMN `created` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `created_at`,
ADD COLUMN `updated` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `updated_at`;
Update table:
UPDATE `nameOfTable`
SET `created` = UNIX_TIMESTAMP( `created_at` ),
`updated` = UNIX_TIMESTAMP( `updated_at` );
Remove the older columns and rename newer ones back to created_at and updated_at.
Alternative way:
Set the DATETIME columns to VARCHAR field.
Update using the query:
UPDATE `nameOfTable`
SET `created_at` = UNIX_TIMESTAMP( `created_at` ),
`updated_at` = UNIX_TIMESTAMP( `updated_at` );
Change the columns to INT.
hjpotter92's answer helped a lot.
But in my case it did not solve the problem right away, since the dates I had stored were in a format not accepted as an argument by UNIX_TIMESTAMP.
So I had to first convert it to an accepted format. After some research I got to the following query that made it:
UPDATE tableName set newFieldName = UNIX_TIMESTAMP(STR_TO_DATE(CAST(priorFieldName AS CHAR), '%m/%d/%y'));
Related
I tried running below code in sql command, but the code line start_date date DEFAULT CURRENT_DATE had issues, got no idea why. I needed only date.
But if I replace that with start_date datetime DEFAULT CURRENT_TIMESTAMP
the SQL will run but the idea is I only need to store date and not datetime.
How do I do it without using timestamp and latter converting to only date?
CREATE TABLE advertisement (
id int not null AUTO_INCREMENT,
PRIMARY KEY(id),
summary text DEFAULT null,
featured_image varchar(50) DEFAULT null,
start_date date DEFAULT CURRENT_DATE,
end_date date not null,
link text DEFAULT null,
added_date datetime DEFAULT CURRENT_TIMESTAMP,
updated_date datetime ON UPDATE CURRENT_TIMESTAMP
)
The documentation is quite clear that this works for datetime columns but not date columns:
This means, for example, that you cannot set the default for a date
column to be the value of a function such as NOW() or CURRENT_DATE.
The exception is that you can specify CURRENT_TIMESTAMP as the default
for TIMESTAMP and DATETIME columns.
If you really have your heart set on ignoring the time component, you will have to use a trigger to set the value, rather than a default constraint.
In this way I was able to use CURRENT_DATE function. This code is 100% tested. Note, date value of that instance of point when new row is added is saved.
I used following, SQL first:
CREATE TABLE advertisement (
id int(11) NOT NULL AUTO_INCREMENT,
summary text DEFAULT NULL,
featured_image varchar(50) DEFAULT NULL,
start_date date DEFAULT NULL,
end_date date NOT NULL,
link text DEFAULT NULL,
added_date datetime DEFAULT CURRENT_TIMESTAMP,
updated_date datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
)
and then during adding SQL I used query as
INSERT INTO `advertisement` SET
start_date=CURRENT_DATE(),
end_date='2018-04-02',
added_date='2018-03-01 00:10:33'
Thank you all for your suggestion.
as of MySQL8 this is now legal,
CREATE TABLE t (
d DATE DEFAULT (CURRENT_DATE)
);
note however that the "extra" parentheses is IMPORTANT, because, for unknown reasons, this is somehow illegal:
CREATE TABLE t (
d DATE DEFAULT CURRENT_DATE
);
I have a simple table like this:
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`username` varchar(16) DEFAULT NULL,
`password` varchar(16) DEFAULT NULL
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Whenever I insert a record, the created field should be automatically filled with the current timestamp. However, for some reason I keep seeing the inserted timestamp in a 12 hour format. When I do something like select created from users limit 1; I would get 2012-04-30 11:34:05
When I do something like select current_timestamp I would get the 24 hour format 2012-04-30 23:34:05
When I cast it to unix_time and ask php to convert it to PST time, it's correct. But I would like to have the column be displayed in 24 hour format without any time manipulation. Can anyone help?
As Mitch said in the comment above, it seems like just a matter of formatting the output on your SELECT. Try DATE_FORMAT:
SELECT DATE_FORMAT(created, '%Y-%c-%e %H:%i:%s') FROM users
I am working with a database that has a table called date, which contains a separate field for day, month, year. Clearly this is not ideal when I am trying to run comparisons, etc. I am wondering is it possible for me to add a DateTime field to each row of this table and insert a concatenated string into the new field from the existing day, month, year fields.
I am quite sure its possible, I'm just wondering if anyone might be able to point me in the right direction on how to achieve this?
Below is the current date table: (i know)
CREATE TABLE IF NOT EXISTS `date` (
`deposition_id` varchar(11) NOT NULL default '',
`day` int(2) default NULL,
`month` int(2) default NULL,
`year` int(4) default NULL,
PRIMARY KEY (`deposition_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
first use alter table query:
alter table date add column datetimefield datetime NOT Null
then
use update query with self join on date and update datetimefield with concat on date,month, year column values.
Try this (untested) -
UPDATE date d SET d.datetime = (SELECT CONCAT('-','year','month','day') from date d1 where d1.id = d.id);
What is the problem, I don't understand? Alter the table, add new DATE column and then populate it with a string "yyyy-mm-dd" using CONCAT mysql function or whatever.
This seems like a really simple one but I'm struggling to figure it out. I want a column in my database that lists when a record was first created and another column that says when it was updated. It's my understanding I should be able to do all this just using MySQL. All help is appreciated :)
This stinks still no answer, reasons I'm already starting to miss Ruby on Rails...
You will probably need to use a combination of the Datetime datatype and the Timestamp data type. I would set my created column as a DateTime with a DEFAULT NOW(), and my updated column as a Timestamp with DEFAULT CURRENT_TIMESTAMP and an ON UPDATE CURRENT_TIMESTAMP attribute.
Here are the docs for the Timestamp dt:
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways:
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, the column has the current timestamp for its default value, and is automatically updated.
With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
With a DEFAULT CURRENT_TIMESTAMP clause and no ON UPDATE clause, the column has the current timestamp for its default value but is not automatically updated.
With no DEFAULT clause and with an ON UPDATE CURRENT_TIMESTAMP clause, the column has a default of 0 and is automatically updated.
With a constant DEFAULT value, the column has the given default and is not automatically initialized to the current timestamp. If the column also has an ON UPDATE CURRENT_TIMESTAMP clause, it is automatically updated; otherwise, it has a constant default and is not automatically updated.
To fulfill your question and for others viewing this question, here is the answer. Note this was written for MySQL 5.x.
DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
`id` INT NULL AUTO_INCREMENT ,
`name` varchar(50) NOT NULL ,
`created` DATETIME ,
`updated` DATETIME ,
PRIMARY KEY (`id`),
INDEX (`name`)
);
DELIMITER $$
DROP TRIGGER IF EXISTS `test1_created`$$
CREATE TRIGGER `test1_created` BEFORE INSERT ON `test1`
FOR EACH ROW BEGIN
SET NEW.`created` = UTC_TIMESTAMP();
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DROP TRIGGER IF EXISTS `test1_updated`$$
CREATE TRIGGER `test1_updated` BEFORE UPDATE ON `test1`
FOR EACH ROW BEGIN
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DELIMITER ;
Note
You could use TIMESTAMP for the updated column which would have automatically updated the value thus not requiring the BEFORE UPDATE trigger, however TIMESTAMP has a range from 1970 to 2038 which is fast approaching and I like to think my applications will live forever :). Although TIMESTAMP is only 4bytes while DATETIME is 8bytes.
TIMESTAMP range '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
DATETIME range '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
From the MySQL 5.0 Certification Guide:
CREATE TABLE ts_test5 (
created TIMESTAMP DEFAULT 0,
updated TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
data CHAR(30)
);
To control the initialization and update behaviour of a TIMESTAMP column, you add either or both of the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes to the column defintion when creating the table with CREATE TABLE...
and
...if you do not specify either of the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes when creating a table, MySQL automatically assigns BOTH to the first TIMESTAMP column
Also
you cannot use DEFAULT CURRENT_TIMESTAMP with one column and ON UPDATE CURRENT_TIMESTAMP with another
If you can't use the timestamp fields with default attributes that Paul W has suggested, you can use AFTER INSERT and AFTER UPDATE triggers to populate the fields.
You will need two fields "Created" and
"Updated" with type datetime. When a
new entry is inserted then insert
"Created" with current time stamp.
When a update is happening insert
"Updated" with the current time stamp,
and let the "Created" field remain as
it is.
For current time stamp you can use
NOW() in your mysql query.
i have a table that looks like this:
Field: msg_sent_datetime
Type: datetime
yet when i use NOW() in a php mysql insert query it is staying as all zeros?
any idea why?
If you're using it only at the time of INSERT, you could make the field a TIMESTAMP and set a default of CURRENT_TIMESTAMP.
Without knowing more about the code it's difficult to suggest much else.
Example with CURRENT_TIMESTAMP
CREATE TABLE example (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
msg TEXT,
msg_sent_datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Also, if you want it to always update when there's a change to the row, you can add the ON UPDATE CURRENT_TIMESTAMP property to the table definition:
CREATE TABLE example (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
msg TEXT,
msg_sent_datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Of course, all of this is totally dependent on switching to TIMESTAMP which you may not want
I dont knw exactly why, but mysql has 2 datetime functions: now() and sysdate(). Perhaps you can substitute now() with sysdate() to help you troubleshoot.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_sysdate