I have a table with a column containing unix time. I wish to create a new column that contains the day of the week for this time. For example, 1436160600 would be a Monday in this column.
I have created a new column, entitled "day_of_week"
alter table master add column test varchar(20);
I now wish to update this new column with the appropriate values.
I found the MySQL Unixtimestamp() function (http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_unix-timestamp)
I then attempted the following
update master set day_of_week = _sent_time_stamp(from_unixtime(unix_timestamp, %W));
where _sent_time_stamp is the column containing the Unix time values
But this results in an Error 1064.
Can anyone advise?
Solution. Convert epoch to date time
alter table master add column test_date datetime ;
update master set test_date = from_unixtime(_sent_time_stamp) ;
convert datetime to day of week using dayname function
alter table master add column test_day varchar(20) ;
update master set test_day = dayname(test_date) ;
I know this post is old, but the accepted answer is sadly wasteful, and I hope that future people seeking this answer may be more enlightened.
No need to add a new column to the table just for some temporary value. To achieve what you requested, you can simply do this:
UPDATE master
SET test_day = dayname(from_unixtime(_sent_time_stamp)) ;
However, even the goal is a wasteful in that we're simply storing two representations of the same data. What you can do instead, is to create a view:
CREATE VIEW master_vw AS
(SELECT mstr.*, DAYNAME(FROM_UNIXTIME(mstr._sent_time_stamp)) AS test_day
FROM master mstr) ;
Now, you can SELECT from this view anytime you like, and the value of test_day will always be in sync with the value of _sent_time_stamp. And no new column to maintain and whatnot.
There is a use case for actually storing the test_day column - execution of the view will take a miniscule amount of additional processing versus selecting from a table. And you cannot index over the virtual test_day column like you could in a table. So if you have millions of rows and you need to quickly get one that's (say) 'Saturday' then perhaps the table approach is more ideal.
But in cases where the column is just a convenience, or where it is simply a different representation of data that already exists, you'll do well to consider the View approach.
Related
I have one field in a table that has a time as a value.
table name: sessions
column: time
For example
time
-----
09:00:00 (this should be the correct time)
12:00:00:00:00
09:00:00:00
11:00:00:00:00:00:00
16:00:00:00:00
This table got messed up and I would like to clean it and keep only the 8 first characters of each row and delete everything that is after that.
Is there a way i can do this with a mysql command?
Thanks
All you need is to update the table:
update sessions
set time = left(time, 8)
Use string functions:
update mytable set mytime = substring(mytime, 1, 8)
I would also recommend changing the datatype of your column to time, so the database will properly enforce data integrity for you in the future. If your data can be implicitely converted to the target format (which should be the case once after executing the above query), you can just do:
alter table mytable modify mytime time;
Note that time is not a wise choice for a column name, since it conflicts with a MySQL datatype. I used mytime instead in the queries.
I am having`a whole mysql table of approx 40,000 rows with a column named 'epoch_time' and there is epoch time in it and I want to convert that whole table's 'epoch_time' to a equivalent 'date' together in a single sql query and I'm doing this is in php_my_admin . Thanks in advance.
I guess by epochtime you mean UNIX-style timestamps, that is, number of seconds since 1970-01-01T00:00Z. If my guess is wrong, so is the rest of my answer.
First you add a new column to the table.
ALTER TABLE mytable ADD COLUMN datestamp DATETIME AFTER epochtime;
This names the new column datestamp and puts it right after epochtime in the list of columns.
Then you update the whole table to populate the new column from the old using FROM_UNIXTIME(). Omitting the WHERE clause makes the update work on the whole table (careful!).
UPDATE mytable SET datestamp = FROM_UNIXTIME(epochtime);
Finally, if you wish you can drop the old column.
UPDATE TABLE mytable DROP COLUMN epochtime;
If I were you I'd try all this on a copy of your database to ensure it is correct before doing it on your production database.
If your epochtime values already have the TIMESTAMP data type, they are already stored internally as UTC (f/k/a GMT) times. The update operation I suggested will convert them to local time according to the settings on your server.
If your application has users in multiple time zones, you may wish to keep using the TIMESTAMP datatype: it honors time zone settings. If your epoch times are stored in an INT column, you can create your new column with the TIMESTAMP rather than DATETIME type by substituting this line for the first one in my instructions above.
ALTER TABLE mytable ADD COLUMN datestamp TIMESTAMP AFTER epochtime;
I am dealing with a legacy application that is using MariaDB to emulate a queue. One of the key things missing is that the original design doesn't insert the time the messages in the queue were inserted meaning that the order the messages are processed is not guaranteed.
So far the messages appear to be processed in order as we're only using a single MariaDB instance but I would like to add a created_on column to ensure this continues.
My question is that I need to backfill the created_on column and i was wondering if MariaDB stored the time a given row was inserted into the database?
I realise that unless it is in the schema it is unlikely but occasionally databases will have non-standard extensions that capture this sort of thing. Oracle for example has similar functionality to this.
MariaDB does not have a hidden timestamp. If the table has an AUTO_INCREMENT, that might suffice since you are asking for order, not specifically time.
My opinion of queuing via MySQL/MariaDB: "Don't queue it, just do it". The effort of queuing and dequeuing can become a burden, especially in end cases.
Yes you can, if you were to create a field make sure when you create the field you have the following:
create table test_created_on_table(
created_on timestamp default now() on update now()
);
If you already have a field just take off the "CURRENT_TIMESTAMP" flag on the created field. Whenever you create a new record in the table, just use "NOW()" for a value.
Or.
On the contrary, remove the 'ON UPDATE CURRENT_TIMESTAMP' flag and send the NOW() for that field. That way actually makes more sense.
This would track when row is inserted or updated.
There's another way of doing it by db trigger:
Adding a ModifiedTime
Adding a modified timestamp to a table is the most straight forward. All your have to do is create the field of type TIMESTAMP, and by default, MySQL will automatically update the field when the row is modified.
There are a couple of things to be aware of:
While you can have multiple TIMESTAMP fields in a row, only one of
these can be automatically updated with the current time on update.
If your UPDATE query contains a value for your ModifiedTime field,
this value will be used.
So, to add your modified timestamp field to an existing table, all you need is:
ALTER TABLE my_table ADD ModifiedTime TIMESTAMP;
Adding a CreatedTime
Adding a CreateTime value is a little more involved.
On the latest versions of MySQL it is apparently possible to create a DateTime field with a default value of CURRENT_TIMESTAMP. This wasn’t an option for me as I was having to support a somewhat older version, besides, even on the newer versions of MySQL it is not possible to have more than one field using CURRENT_TIMESTAMP, which of course we are in order to get ModifiedTime working.
So, in order to get a created timestamp, firstly we must add a DATETIME field to the table.
ALTER TABLE my_table ADD CreatedTime datetime NOT NULL;
Note, that this must be created as NOT NULL in order for the next part to work (this is because setting NOT NULL forces an automatic all zeros default).
Next, we must create a trigger, which will automatically be fired when we insert a value into our table and set the created timestamp.
DELIMITER //
DROP TRIGGER IF EXISTS my_table_insert_trigger//
CREATE TRIGGER my_table_insert_trigger
BEFORE INSERT ON my_table
FOR EACH ROW
BEGIN
IF NEW.CreatedTime = '0000-00-00 00:00:00' THEN
SET NEW.CreatedTime = NOW();
END IF;
END;//
DELIMITER ;
Now, when you insert a value into the table, this trigger will fire and, if you’ve not provided a CreatedTime field in your insert query, it will be set to the current time stamp.
I am working on a mysql query for a report. The idea is to have a simple table say 'reportTable' with the values being fetched from various places. I could then use the reportTable more easily without remembering lots of joins etc and also share this table for other projects.
Should I break down the inner insert part of the query so it does
chunks at a time I will be adding probably tens of thousands of rows?
INSERT INTO reportTable
(
-- long query grabbing results from various places
SELECT var1 FROM schema1.table1
SELECT var2 FROM schema2.table1
SELECT var2 FROM schema2.table1
etc
)
This addresses your concerns that inserting data takes too long and so on. I understood it like you rebuild your table each time. So, instead of doing so, just fetch the data that is new and not already in your table. Since looking up if the data is already present in your report table might be expensive, too, just get the delta. Here's how:
Make sure that in every table you need a column like this is present:
ALTER TABLE yourTable ADD COLUMN created timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
The ON UPDATE clause is of course optionally, don't know if you need to keep track of changes. If so, give me a comment and I can provide you with a solution with which you can keep a history of your data.
Now you need a small table that holds some meta information.
CREATE TABLE deltameta (tablename varchar(50), LSET timestamp, CET timestamp);
LSET is short for Last Successful Extraction Time, CET for Current Extraction Time.
When you get your data it works like this:
UPDATE deltameta SET CET = CURRENT_TIMESTAMP WHERE tablename = 'theTableFromWhichYouGetData';
SELECT #varLSET := LSET, #varCET := CET FROM deltameta WHERE tablename = 'theTableFromWhichYouGetData';
INSERT INTO yourReportTable (
SELECT whatever FROM aTable WHERE created >= #varLSET AND created < #varCET
);
UPDATE deltameta SET LSET = CET WHERE tablename = 'theTableFromWhichYouGetData';
When anything goes wrong during inserting your script stops and you get the same data the next time you run it. Additionally you can work with transactions here, if you need to roll back. Again, write a comment if you need help with this.
I may be wrong, but you seem to be talking about a basic view. You can read an introduction to views here: http://techotopia.com/index.php/An_Introduction_to_MySQL_Views, and here are the mysql view docs: http://dev.mysql.com/doc/refman/5.0/en/create-view.html
I have some office records. Database is already created and filled with lots of data. I have to create search functionality on it. But the problem is database have date field which is in var char form and is in the form "DD-MM-YYYY" eg :"18-11-2011"
I want to convert the date column in date format without losing this data. I tried doing it on test table and everything turned to zero. eg: 0000-00-00
What can be done for the same ?
To expand on flesk's answer add a new column
ALTER TABLE foo ADD newdate DATE;
Update the table to fill this new column (like flesk did)
UPDATE foo SET newdate=str_to_date(olddate, '%d-%m-%Y');
Then you can even test if the conversion is correct.
SELECT * FROM foo WHERE olddate <> DATE_FORMAT(newdate, '%d-%m-%Y');
Then you can either drop old column and rename new one. Or just leave it as it is.