Automatic Update for database rows based on changes in another table - mysql

I have a scenario that requires a value in a row of a table to be updated automatically whenever a row has been added or deleted in another table. I'm not sure how to do it.BTW I'm using phpmyadmin in order to manage my database. Thanks in advance.
pages Table
------------
page_no
no_of_choices
choices Table
-------------
page_no
choice_no
When I add a choice with choice number 1 and page_no, then the table page which has the row, page_no=1 should be updated with no_of_choices=no_of_choices+1

You can use triggers.
For example:
CREATE TRIGGER `test1`
AFTER INSERT ON `tbl1`
FOR EACH ROW SET NEW.upd_fld = new_value
Similarly could be done for delete.
You can also create triggers from phpMyAdmin

TABLE A: page_no, no_of_choices
TABLE B: page_no, choice_no...
With a relational database you very rarely want to have duplicate data. If something breaks at some point, you won't know which to trust - the rows in Table B, or the no_of_choices in Table A. A better solution is to do one of the following (depending on which table you are querying):
SELECT COUNT(no_of_choices) FROM B WHERE page_no = 1
or
SELECT A.*, COUNT(choice_no) AS choice_no FROM A LEFT JOIN B USING(page_no)
You get the same result, but now you have one record to go off of, so you won't have inconsistent data.

Related

How to merge two db with same structure but different data

I'm working with phpmyadmin and I have to merge two db with same structure but different data.
The db have relation between tables (foreign key).
The data in two db may have same id, and so their foreign key.
I would like to know if it's possible merge the two db keeping all data, so, if a row already "exist", insert it with new id and update its foreign key.
thanks a lot
No easy way unfortunately. If you have TableA as a foreign key to TableB, you will need to
1) Insert data from source tableA to target tableA
2) create a (temp) table to store the mapping between source tableA ids and target tableA ids
3) Use this mapping table when inserting data from tableB to convert the tableA ids to the new ones in the target db
... and so on. It can get quite hairy if you have a deep hierarchy of tables, but hopefully you get the idea. Take backups before you start.
Another idea that you might want to consider is using a cursor:
Assume table A is the one that you want to keep and table B is the one you want to remove.
Declare a cursor for table B and select all the records.
Loop each record selected from the cursor and check.
Case 1: If the ID is exists on table A, insert the record to table A with same details.
Case 2: If the ID is exists on table B, insert the record and modify the ID and foreign key.
Once all the records have been checked, drop table B.
Sorry, I just can give an idea at the moment.

Inserting records from one table to another, but on a 'dynamic' table

Let's assume that I have a table 'A' which holds the client's orders - so it is updated within every second - and I want to copy every record of it and put it in a new table 'B'.
How would you manage to do that knowing that every moment new records are added/updated and you cant just simply 'copy + paste' it (cause in that moment new records will be added/updated) ? Do you know any way to do that ?
Please try:
CREATE TRIGGER trigger_INSERTItemDetails ON TABLEA
FOR INSERT AS
BEGIN
INSERT INTO
tableB
(
colB1,
colB2,
colB3
)
SELECT
colA1,
colA2,
colA3
FROM
INSERTED
END
and make sure that you are inserting a NOT NULL value to column Primary column of table.
Similarly you created for UPDATE and DELETE actions, so you don't need to copy separately because all actions which happen in TableA it will affect TableB also.

Adding column from one table to the other table in mysql

How to add or insert specific column from one table to other ? I tried writing like this
ALTER TABLE info_apie_zaideja
ADD SELECT info_apie_match.Rank AFTER 'Nick'
FROM info_apie_match;
or this
UPDATE info_apie_zaideja
ADD COLUMN SELECT info_apie_match.Rank AFTER 'Nick'
FROM info_apie_match;
but that did not work. Oh, and the table where I want to insert column is view table if that helps somehow. All answers will be appreciated.
You need to do this in two steps. First alter the table to add the new column:
ALTER TABLE info_apie_zaideja
ADD COLUMN Rank INT AFTER Nick;
Then fill it in by copying from corresponding rows in the other table:
UPDATE info_apie_zaideja AS z
JOIN info_apie_match AS m ON z.id = m.zaideja_id
SET z.Rank = m.Rank
I had to guess at the column that relates the two tables. Correct the ON clause to match your actual table relations.
Also, consider whether you really need the column in both tables. With this redundancy, you'll need to make sure that whenever you update one table, the other one is updated as well. Instead, you could just use a JOIN whenever you need the value from the other table.

enter data into 2 tables with foriegn key relation based on one attribute of primary table

I have a table 'project' that has attributes:name, UID(PK), section(distinguisher)... and 3 tables A,B,C based on section with specific properties of each section.i want to be able to enter data into project and the section specific data into A/B/C TABLE based on entry in section attribute of project table of that row. all tables have Foreign key with UID as UID_A, UID_B, UID_C...any ideas on how i can do it? all help appreciated as i am quite a novice...thanks! I am working with Mysql workbench.
Well, create a trigger on the table project:
CREATE TRIGGER `fill_abc` AFTER INSERT ON `project`
FOR EACH ROW BEGIN
INSERT INTO A <some specific data...>;
INSERT INTO B <some specific data...>;
INSERT INTO C <some specific data...>;
END;
Probably, you want to handle not only inserts into this table, but updates and deletes as well - it is nearly the same idea. See trigger definition here and examples here

mysql divide a table into 2 with different column names

I have a mysql table which I need to split into two. Currently the table contains info about two loosely related entities.
For example the entities can be Employee of a firm and the firm's laptop he is tagged to.
The following table explains my example. I have a table employee which has the following columns
employee_id,employee_name,employee_detail,join_date,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make.
I need to split this table into 2 as shown below.
employee table without the laptop columns
employee_id,employee_name,employee_detail,join_date.
A new laptop table with employee_id as the key.
employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make
The below statements are true for the current database design
The employee table is heavily used by the back end code. The back
end code is written in java and php.
employee table cannot be renamed.Implies I do not want to create 2
new tables.I want to retain the employee table, but remove all the
laptop info from it.
New rows are added/existing rows are updated on a daily basis.
My question is
Is there a design approach which I can follow for a smooth
transition from the current design of a single table to the newly
suggested design?
Are there any best practices to follow to ensure a smooth
transition.
Could you suggest/re-direct me the steps to complete this task.
Backup your existing database:
mysqldump my_db > backup.sql
Create a new, empty table laptop (I'm not defining indexes or foreign key constraints in my example below, but you should do whatever is appropriate to your data structure):
CREATE TABLE laptop
SELECT employee_id,
laptop_id,
laptop_type,
laptop_tagged_date,
laptop_details,
laptop_make
FROM employee
WHERE FALSE;
Define triggers on the original table to forward each type of write operation (insert/update/delete) to the new table:
CREATE TRIGGER employee_insert AFTER INSERT ON employee FOR EACH ROW
INSERT INTO laptop VALUES (
NEW.employee_id,
NEW.laptop_id,
NEW.laptop_type,
NEW.laptop_tagged_date,
NEW.laptop_details,
NEW.laptop_make
);
CREATE TRIGGER employee_update AFTER UPDATE ON employee FOR EACH ROW
UPDATE laptop SET
employee_id = NEW.employee_id,
laptop_id = NEW.laptop_id,
laptop_type = NEW.laptop_type,
laptop_tagged_date = NEW.laptop_tagged_date,
laptop_details = NEW.laptop_details,
laptop_make = NEW.laptop_make
WHERE
employee_id <=> OLD.employee_id,
laptop_id <=> OLD.laptop_id,
laptop_type <=> OLD.laptop_type,
laptop_tagged_date <=> OLD.laptop_tagged_date,
laptop_details <=> OLD.laptop_details,
laptop_make <=> OLD.laptop_make;
CREATE TRIGGER employee_delete AFTER DELETE ON employee FOR EACH ROW
DELETE FROM laptop WHERE
employee_id <=> OLD.employee_id,
laptop_id <=> OLD.laptop_id,
laptop_type <=> OLD.laptop_type,
laptop_tagged_date <=> OLD.laptop_tagged_date,
laptop_details <=> OLD.laptop_details,
laptop_make <=> OLD.laptop_make;
Empty the new table (of anything the trigger has since inserted) and then, within the same transaction, use INSERT ... SELECT to copy into it all incumbent data from the original table:
START TRANSACTION;
DELETE FROM laptop;
INSERT INTO laptop
SELECT employee_id,
laptop_id,
laptop_type,
laptop_tagged_date,
laptop_details,
laptop_make
FROM employee;
COMMIT;
Thoroughly search your codebase (including database-stored programs) for all operations that access the laptop columns in the original table. Note whether each operation:
only reads from those columns;
only writes to those columns; or
both reads from and writes to those columns (e.g. UPDATE employee SET laptop_tagged_date = laptop_tagged_date + INTERVAL 1 WEEK WHERE ...).
Modify read operations to use the new table, splitting operations that both read and write into separate steps (e.g. UPDATE employee JOIN laptop ON ... SET employee.laptop_tagged_date = laptop.laptop_tagged_date + INTERVAL 1 WEEK WHERE ...).
This change does not need to be effected atomically, as the original and new tables will be kept in sync by the triggers: some parts of your application can therefore read from the new table whilst others continue using the original table.
Do not proceed to the next step until you are satisfied that this step has been completed, as the next step will result in the tables becoming desynchronised. You could even use MySQL user permissions to prevent writing to the new table (except by the triggers) until you are satisfied that this step is complete.
Modify write operations to use the new table.
This change does not need to be effected atomically, as any writes to the original table will be forwarded to the new one by the triggers: some parts of your application can therefore write to the new table whilst others continue writing to the original table.
Drop the columns from the original table:
ALTER TABLE employee
DROP COLUMN laptop_id,
DROP COLUMN laptop_type,
DROP COLUMN laptop_tagged_date,
DROP COLUMN laptop_details,
DROP COLUMN laptop_make;
if you want to have 2 physical different tables you can adapt Sebastien M. answer as such :
create a laptop table with corresponding data to externalize them
CREATE TABLE laptop AS
SELECT DISTINCT employee_id,laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make
FROM employee
WHERE ...
provide a employee_laptop view to imitate the behaviour of employee and get backward compatibility
create view employee_laptop as
select employee_id, e.employee_name,e.employee_detail,e.join_date,
l.laptop_id,l.laptop_type,l.laptop_tagged_date,l.laptop_details,l.laptop_make
from employee e join laptop l using(employee_id);
then you have all the latitude to drop the unnecessary columns from the employee table
I can suggest you a possible way , when you are creating laptop table use the following query type :-
create table laptop select employee_id,laptop_id,laptop_type,
laptop_tagged_date,laptop_details,laptop_make from
employee;
After creating the laptop table in this above process, you can remove the specified columns from employee table for getting your new employee table with relevant fields.
Delete column from employee table.
alter table employee
drop column laptop_id,laptop_type,laptop_tagged_date,laptop_details,laptop_make;
Now the new employee table has following fields :
employee_id,employee_name,employee_detail,join_date
Now the laptop table has following fields :
mployee_id,laptop_id,laptop_type,
laptop_tagged_date,laptop_details,laptop_make
Hope it will help you.