mysql - create indexed hour column from existing timestamp - php

I have a column 'updatetime' that is a timestamp ("2011-02-01 09:00:51"). For performance purposes I need to create an indexed column 'updatetime_hour' based on the hour of the timestamp.
So for example if 'updatetime' was "2011-02-01 09:00:51" then 'updatetime_hour' would be "9".
I'm trying to do this all in mysql though PHP is an option as well. 60k+ existing rows.
Thoughts?

UPDATE yourtable SET updatetime_hour=HOUR(updatetime);
Don't run this in peak hours, it will take a while. You could even run it in smaller batches - make updatetime_hour nullable and continue running this, until you get "0 rows affected":
UPDATE yourtable SET updatetime_hour=HOUR(updatetime)
WHERE updatetime_hour IS NULL LIMIT 1000;

To do this automatically each time you add or update a row, use triggers:
CREATE TRIGGER t1 BEFORE INSERT ON table
FOR EACH ROW BEGIN
SET NEW.updatetime_hour = HOUR(NEW.updatetime);
END
CREATE TRIGGER t2 BEFORE UPDATE ON table
FOR EACH ROW BEGIN
SET NEW.updatetime_hour = HOUR(NEW.updatetime);
END

Related

Trigger calculation, on insert of one table effect on other table

IDEA:
Having a table of item, user, assign now if I assign one item to user which the record will be save on table of assign,
table_item:
ID------INT
NAME----TEXT
COUNT---INT
table_user:
ID-------INT
NAME-----TEXT
table_assing:
ID------INT
USER----INT (user id)
ITEM----INT (item_id)
COUNT---INT (this is for subtractions from the column of COUNT table of item)
Here I want to set trigger on inserting to table (table_assing) the value of column COUNT should subtract from column of COUNT table of table_item
This is possible on PHP that I can set to query on once action but it will take lots of code if it's possible on MySQL that will be much better and fast and effective with accuracy
simple trigger after insert on table table_assign
UPDATE table_item
SET table_item.count = (table_item.count - NEW.table_assign.count)
WHERE table_item.id = table_assign.item
Something like this should work.
DELIMITER $$
USE database_name$$
CREATE TRIGGER trigger_name AFTER INSERT ON table_asign FOR EACH ROW
BEGIN
UPDATE table_item SET count=count+NEW.count WHERE id=NEW.id;
END;$$
The 'NEW.id' refers to the new row in the table 'table_asign'

How can i order by last update row

I have one Sql Query to get all the informations from my table.
I created an list using an foreach.
And i want to order this list, by the last updated row.
Like this
$query - "SELECT * FROM table ORDER BY last_updated_row";
//call Query here
And when i updated a certain row, i want to put this row on the top of the list
I heard about time_stamp, can i use time_stamp for that?
how can i do that?
Thanks
Assuming your using MySQL your table needs to be like this
CREATE TABLE table (
last_updated_row TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
That will give the row a create time stamp and update it on each update statement which effects the row
http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
You can use just about any date/datetime/timestamp column in a table to sort by if needed. The only catch is you need to actually have it in the table.
Any of the above will allow sorts by ascending/descending order, but need to be maintained when inserting/updating a row.
Assuming you have the following structure:
table - someTable
id someVale updateTime
1 54634 ......
2 65138 ......
3 94141 ......
4 84351 ......
It doesn't matter what type of column updateTime is - whether it is a date, a datetime, a timestamp, a simple order by updateTime will work.
But you need to make sure that each insert/update you make to that row updates the column so that the sort will be true.

Preventing inserting same value twice in an oracle database

I have a number which is in this form : 2012-01 (2012 as current year) and 01 is just a the maximum value of a field in my database incremented by 1, and each year that number is reset to 0.
but if there are two users that try to do the same operation at the same time the value is the same for both and thus i get the same number inserted twice in my database .
I thought of creating a sequence but that requires a job that resets the sequence each year and i would prefer if there is a way to make a lock before i get the next number and
release it after an insert is done ?
Thanks.
CREATE UNIQUE INDEX index_name ON table_name (column_name);
or
ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (column_name);
You don't specify where you store the field that is used as the counter. But maybe it is possible to use a SELECT FOR UPDATE statement.
Before you increment the value of your counter field by 1 you can lock that record by using a SELECT FOR UPDATE. Then update the counter.
Something like this, assuming the table has only 1 record:
SELECT *
FROM CounterTable
FOR UPDATE;
UPDATE CounterTable
SET Counter = Counter + 1;
COMMIT;
If one session (user) has done the SELECT FOR UPDATE and not yet committed or rolled back, the other session (user) doing a SELECT FOR UPDATE will block waiting to be able to get a lock. This prevents two users from getting the same number.

how to delete duplicate values in mysql table

I have column in mysql table (my_sale_time) of type timestamp....infact the rows value look like this
2010-12-01 14:38:07
2010-12-01 17:14:18
...
so what i need mysql query to delete those value whose date is repeated multiple times in table.....as i mentioned in sample sale_time_value.....only date is repeated with same value but time is different....so i want to get all rows, date is repeated multiple times and delete duplicate dates
The basic principle of deleting duplicate rows:
CREATE TEMPORARY TABLE tmptbl AS SELECT DISTINCT * FROM my_sale_time;
DELETE FROM my_sale_time;
INSERT INTO my_sale_time SELECT * FROM tmptbl;
You may have to specify columns and WHERE clauses (I didn't really understand your criteria).
And of course you should test-run it on a development server and don't forget to run it as a single transaction with locked tables.
If you have an auto_increment field, use this:
DELETE FROM
`mytable`
WHERE
`my_auto_increment_field` NOT IN (
SELECT
MAX(`my_auto_increment_field`)
GROUP BY
`my_sale_time`
);

MySQL Timestamp when update a specific column with PHP

I want to put a timestamp when a specific column is updated.
For example:
column1: a value
dateColumn1: date column1 was updated
column2 : a value
dateColumn2: date column2 was updated
I use the function getTimestamp(), but it doesn't seem to work.
Can anyone advise me on how to do this in PHP and MYSQL?
Thanks.
If you want to do this only in the database, you could write a trigger that checks your conditions and updates specific timestamps if needed. But I'm assuming you don't want to fiddle around with triggers. Triggers have an advantage though: you can access the old and the new values of a row without having to write any php code.
Anyway, in case you need it here is some example code for a trigger (SQL, beware):
DELIMITER $$
DROP TRIGGER IF EXISTS Table1_UpdateTrigger $$
CREATE TRIGGER Table1_UpdateTrigger BEFORE UPDATE ON Table1
FOR EACH ROW BEGIN
IF OLD.column1 != NEW.column1 THEN
SET NEW.dateColumn1 = NOW();
END IF;
IF OLD.column2 != NEW.column2 THEN
SET NEW.dateColumn2 = NOW();
END IF;
END;
$$
DELIMITER ;
Substite Table1 with your real table names, column1, etc. with real column names.
The other way is to compare the old and the new values in php. E.g. do a query fetching the old data, compare the fields you want to check, and then do one update query per field that has changed to set the new timestamps.
UPDATE table
SET column1='new value', timestampcolumn=NOW()
WHERE ...
is one way. If you don't mind the timestamp changing anytime anything in the record is updated, then use the native "timestamp" field type, which'll update itself to "now" when the record's inserted or changed.
I prefer using the MySQL function NOW(), like so:
UPDATE table1 SET column2 = value, dateColumn2 = NOW() WHERE somethingsomething
Use a conditional statement. For example in the following trigger the 'password changed time' will be updated only when there is change in password column.
CREATE TRIGGER update_password
BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
IF OLD.password <> NEW.password THEN
SET NEW.password_changed_on = NOW();
END IF;
END //

Categories