I need to display number of users created from last login to current login in my ELGG application, but there is no field in the ElggUser to record the date & time of users created (ElggUser Table Structure).
So is there any way to get DATETIME of rows already inserted into Table?
Thank You
Database schema of Elgg does contain this information. ElggUser extends ElggEntity that has attributes time_created, time_updated, last_action containing Unix timestamps representation of entity creation/modification/last action by this entity or on related content.
These attributes are stored in {DB_PREFIX}entities table and are availible as properties of all ElggEntity subclasses.
You have to add a field for recording date and time. For instance my table name is my_table and for date time using created_date then create a trigger as:
DELIMITER ;;
CREATE TRIGGER `my_table_bi` BEFORE INSERT ON `my_table` FOR EACH ROW
BEGIN
SET NEW.created_date = NOW();
END;;
DELIMITER ;
Every time for added record the trigger will hit recording the date and time of entry
Don't know, if you can alter your table, but you could add a created column like this:
ALTER TABLE yourTable ADD COLUMN created timestamp DEFAULT CURRENT_TIMESTAMP;
The column created would then always have the time when a row gets inserted without further ado.
Related
Given the following table:
id | value
--------------
1 6
2 70
Is there a way to add a column that is automatically calculated based on another column in the same table? Like a VIEW, but part of the same table. As an example, calculated would be half of value. Calculated should be automatically updated when value changes, just like a VIEW would be.
The result would be:
id | value | calculated
-----------------------
1 6 3
2 70 35
Generated Column is one of the good approach for MySql version which is 5.7.6 and above.
There are two kinds of Generated Columns:
Virtual (default) - column will be calculated on the fly when a
record is read from a table
Stored - column will be calculated when a
new record is written/updated in the table
Both types can have NOT NULL restrictions, but only a stored Generated Column can be a part of an index.
For current case, we are going to use stored generated column. To implement I have considered that both of the values required for calculation are present in table
CREATE TABLE order_details (price DOUBLE, quantity INT, amount DOUBLE AS (price * quantity));
INSERT INTO order_details (price, quantity) VALUES(100,1),(300,4),(60,8);
amount will automatically pop up in table and you can access it directly, also please note that whenever you will update any of the columns, amount will also get updated.
If it is a selection, you can do it as:
SELECT id, value, (value/2) AS calculated FROM mytable
Else, you can also first alter the table to add the missing column and then do an UPDATE query to compute the values for the new column as:
UPDATE mytable SET calculated = value/2;
If it must be automatic, and your MySQL version allows it, you can try with triggers
MySQL 5.7 supports computed columns. They call it "Generated Columns" and the syntax is a little weird, but it supports the same options I see in other databases.
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-generated-columns
#krtek's answer is in the right direction, but has a couple of issues.
The bad news is that using UPDATE in a trigger on the same table won't work. The good news is that it's not necessary; there is a NEW object that you can operate on before the table is even touched.
The trigger becomes:
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
Note also that the BEGIN...END; syntax has to be parsed with a different delimiter in effect. The whole shebang becomes:
DELIMITER |
CREATE TRIGGER halfcolumn_insert BEFORE INSERT ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
DELIMITER ;
You can use generated columns from MYSQL 5.7.
Example Usage:
ALTER TABLE tbl_test
ADD COLUMN calc_val INT
GENERATED ALWAYS AS (((`column1` - 1) * 16) + `column2`) STORED;
VIRTUAL / STORED
Virtual: calculated on the fly when a record is read from a table (default)
Stored: calculated when a new record is inserted/updated within the
table
If you want to add a column to your table which is automatically updated to half of some other column, you can do that with a trigger.
But I think the already proposed answer are a better way to do this.
Dry coded trigger :
CREATE TRIGGER halfcolumn_insert AFTER INSERT ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
END;
CREATE TRIGGER halfcolumn_update AFTER UPDATE ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
END;
I don't think you can make only one trigger, since the event we must respond to are different.
I hope this still helps someone as many people might get to this article. If you need a computed column, why not just expose your desired columns in a view ? Don't just save data or overload the performance with triggers... simply expose the data you need already formatted/calculated in a view.
Hope this helps...
I need to record the date each event happens. I have this table.
Click here to view the table
NULL spaces are available to save a new date.
The X represents the date that the event occurred.
The problem is I do not know how to update the date each event occurs
I need to know the best option if you use INSERT or UPDATE querys.
Thank you for your help
If you just want to update a column in a table with the current time:
UPDATE `yourtable` SET `yourcolumn` = NOW() WHERE `ID` = yourid
Assuming your columns are DATETIME() columns.
As an aside, it's best to have event-related information in another relationship table. This way you can link multiple events for each row in your main table. This provides a more accurate data-trail for accounting purposes (or in other words, you can see each and every update without overwriting anything).
If you are seeking to have a 'last_modified' column on your table to help you keep track of changes made on your records, you should do this:
ALTER TABLE my_table
ADD last_modified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Basically what it does is to add a 'last_modified' column, Set it to be a timestamp and make it to be updated with the current timestamp when there is an update on the record.
Is there a way in MySQL to get insert date/time for rows if there was no insert_date field. I have a database which I configured to store insert_date but can I populate the field before that change ( month ago ). Is that even possible?
Pull that insert date/time from log or something else?
Nope. If that date wasn't stored before, it's impossible to find out when a row was inserted. The best you can do is just pick a date, or maybe make a rough estimate if you have information to base that on (for instance, the create date of a customer might be related to the date of their first invoice)..
By the way, you can add timestamp columns and specify the clause DEFAULT CURRENT_TIMESTAMP to set a timestamp as soon as you insert the row. That way, you don't need a trigger to update the row.
You can even add a clause ON UPDATE CURRENT_TIMESTAMP so the column (or a different column) is updated automatically too.
See Timestamp initialization for more information about this subject.
This doesn't change the fact, though, that you cannot get those values for rows that already exist.
I'm quiet new in the SQL field. Thus I have a way of working question.
Every week, I will send data from an Excel spreadsheet on my MySQL DB through a pHp code. This is already working. Thus I have a table which I can update.
Actually I'm sending price of a specific underlying on my DB. What is the best way to archive my data as following.
On my DB, I have the below structure :
tabe t_index
Label = VARCHAR(255)
Price = float
Date = date()
Let's say I sent my data on my db last week, thus I stored :
Stock A
102.85
2013-03-18
Today, I want to send new price for the same Stock A which is 103.54, but I would like to archive and keep the 102.85 price to be able to make some return or whatever between the two prices.
How should I proceed ?
I hope my question is not too messy...
Thank you for your help
One way of doing this is, create a UPDATE trigger which inserts old value in another table. So when you update an existing entry, old data will be copied/archived to another table.
CREATE TABLE t_index_archive (
Label VARCHAR(255),
Price float,
Date datetime);
Now create a trigger on your existing table
DROP TRIGGER IF EXISTS archive_t_index;
DELIMITER $$
CREATE DEFINER = CURRENT_USER TRIGGER archive_t_index BEFORE UPDATE ON t_index
FOR EACH ROW BEGIN
INSERT INTO t_index_archive VALUES (OLD.Label, OLD.Price, OLD.Date);
END;
$$
DELIMITER ;
You can add another column named like is_active ENUM type with value active,inactive
By default is_active's value will be 'active'
and when you enter new entry in database just update old entry's is_active with 'inactive' and then add new entry
Fetch new data using query using where clause WHERE is_active='active'
I need to know the time since a table in my MySQL database was edited. Is there any way to do this in PHP? The only way I can think of is to get the update time, and compare it to the current time (which will be a little bothersome).
SELECT TIMEDIFF(CURRENT_TIME, UPDATE_TIME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'my_table'
One solution would be to add a timestamp field, that is automatically updated whenever a row is changed.
Then you can find the last change time by selecting the last update value:
# Add a timestamp column:
ALTER TABLE [TABLENAME] add column `ts_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP;
# Get the last update value:
SELECT MAX(ts_update) from [TABLENAME];
It's a bit of a pain since SHOW TABLE STATUS doesn't seem to return a standard result set. Every way I tried to use it as a subquery failed. It seems like you'll need to figure it out programmatically.
SHOW TABLE STATUS
WHERE name = 'target_table';
And if you're concerned about the timezone just do a separate SELECT NOW() to get the time the mysql server has.
Note: This will only show you the time at which the table schema was updated. If you want to know when the last time a row was inserted/edited you'll have to add a timestamp column like Amirshk suggested.