mysql create table based on columns from another table and auto updated - mysql

I could have the wording 'wrong' here (new to mysql) but i hope i've explained what I'm trying to do well.
i have a table called submissions with 4 fields submitId, studentName, submitDate, status
status refers to whether they got admitted or not.
submitId is auto incremented
Now i wanted to create another table based on that, but only if the status is true, this new table would have the submitId, studentName, submitDate, plus additional fields.
this table would have a new auto increment studentId
how would i do that so it automatically updates any new entry to the first table on the second table, but not overwrite the additional content of table 2.
i thought of using a view, but u can't add new columns on the view, right?
do i have the logic wrong here or what are the options, could someone please point me in the right direction, thanks

You want to use a trigger. See:
http://dev.mysql.com/doc/refman/5.6/en/triggers.html
You can create the trigger so that when a row is inserted into submissions with status=true, it inserts a row into your new student table. It would look something like this:
delimiter //
CREATE TRIGGER sub_ins_check AFTER INSERT ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
INSERT INTO your_new_table (student_name, submit_date, submit_id) VALUES (NEW.student_name, NEW.submit_date, NEW.submit_id);
END IF;
END;//
delimiter ;
Then create another trigger so that when a row is updated in submissions, it updates the row with the same submit_id in your new table, like this:
delimiter //
CREATE TRIGGER sub_ins_check AFTER UPDATE ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
UPDATE your_new_table SET student_name = NEW.student_name, submit_date = NEW.submit_date, (etc..)) WHERE submit_id = NEW.submit_id;
END IF;
END;//
delimiter ;

I think your data model is wrong. Remember that student my have several submissions and there may be number of students with the same name. You must distinguish them.
Is there any reason you want to duplicate student data in both tables?
If you're new to SQL, read about table normalization first.
In you Student table you should store students data and in Submission table - guess what :)

The first thing you need to do is step back and consider the problem from the perspective of logical entities.
You've identified two entities that I can see - student and submission. "Student" is an obvious entity which you may choose NOT to store in your database, but it may be better that you do. "Submission" is a more obvious one, but what is not so obvious is what a "submission" actually is. Let's assume it is some sort of transaction.
You've mentioned a "second table" without a clear indication of its role in the solution. The best I could infer is that it is meant to be some sort of historical trail on activity against a submission. If true, then I could envision a physical schema sketched out as follows:
Student table. One row per student; contains information about a student (name, id, etc.). Primary key would probably be an auto-incremented number.
Submission table. One row per submission; includes a foreign key to the student table (referencing the primary key); has its own primary key, also an auto-incremented integer. Also has triggers defined for INSERT and UPDATE. INSERT trigger causes INSERT into submission_log table; UPDATE trigger also causes INSERT into submission_log table.
Submission_log table. One row per event against the submission table. Includes all the fields of submission plus its own primary key (submission's primary key is a foreign key here), and includes an indicator field for whether it represents an insert or update on submission.
The purpose of the above is not to supply a solution, or even the framework of a solution, but rather to get you to think in terms of the logical entities you want to model in your solution, and their relationships to each other. When you have a clear picture of the logical model, it will be much easier to determine what tables are required, what their roles are, and how they will be used and how they will relate to each other.

Related

How to make one column mirror another in mysql

I have two tables one called users and another called profiles. Each of these tables has a column named user_id. What I want to do is when I insert a new user into the users table, I want to automatically copy over their new user_id in the users table to the profiles table. I don't want to use the UPDATE clause because then I would have to call that every time I add a new user. I thought that relations would achieve what I am trying to do so I made the user_id from profiles reference the user_id from users and it still doesn't update automatically. What should I do? And what is the point of relations in the first place if they don't update your columns automatically?
This is probably a design error. If rows in these two tables always exist with the same IDs, they should probably be a single table.
The foreign key you've created only guarantees that every row that exists in profiles must have the same ID as a row in users. It does not cause those rows to be created -- it just means that if you try to create a row with an ID that doesn't match, the database will throw an error.
That all being said, it's possible to create a trigger to do what you're describing:
CREATE TRIGGER user_insert_creates_profile
AFTER INSERT ON users
FOR EACH ROW
INSERT INTO profile (user_id) VALUES (NEW.user_id);
But it's probably better to reconsider your design, or to do the insert in your application. Triggers are best avoided.

Inserting values in Mysql table if all the columns have different values

I am working on a blogging site but problem which I am facing is that, I want to allow user to create a blog if and only if his/her combination of email address, Blog Name and Blog Title is different from any other rows in the table. For example let us consider this table:-
Email BlogName BlogTitle
abc#gmail.com Coder's world What is coding?
abc#gmail.com Sql world What is sql?
Now if a user tries to enter a values('abc#gmail.com','Coder's Worlds' ,'What is coding?') in the table again then he/she will not be allowed to do so. But if the user tries to insert different combination of email, BlogName and BlogTitle then he/she will be allowed to do so.
As I am pretty new to Mysql, I don't know how to do this, so please help me to do this.
My Table structure :-
You can add a unique constraint on the combination of the three columns:
ALTER TABLE `blog_table` ADD UNIQUE `unique_index`(`Email`(100), `BlogName`(100), `BlogTitle`(100));
This will also remove any duplicates which might already exist in your blog table.
Note that this constraint uses only the first 100 characters from each of the three columns to avoid the #1071-Specified key was too long error.
Make those 3 Columns unique.
Here is a example of Making multiple fields composite
ALTER TABLE table ADD UNIQUE ('field_1','field_2', 'field_3');
IF (SELECT 1 = 1 FROM Table WHERE Email=#email and BlogName=#blogname and BlogTitle=#blogtitle) THEN
BEGIN
#return error message do not insert
END;
ELSE
BEGIN
#insert logic here
END;
END IF;
Check if matching record exists in table before inserting using above code

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 cascading tables

(My website is built using PHP and MySQL.)
My DB structure for users is mainly composed of 2 tables: "doctors" and "clients".
However, in order to integrate a chat system, I need to create a third table, namely 'chat_users', which combines both doctors and clients: fields of 'chat_users' table are
userid (unique integer),
username,
type (0:client, 1:doctor),
refid (id of the user in the associated clients or doctors table)
But I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted. I heard about cascading table some time ago...
What would be the best way performance-wise to do so? How can I achieve it?
I'm not sure you'll consider this an "answer", but may I comment on your database architecture?
You will be much happier in the long run having the following tables:
user_account: (ua_id, ua_email, ua_username, ua_password, etc.)
doctor: (d_id, ua_id, etc.)
customer: (c_id, ua_id, etc.)
In other words, have your relation going the other way. Then if you would like to be able to delete a doctor or customer by simply deleting the user_account, you can add the following relational constraint:
ALTER TABLE `doctor`
ADD CONSTRAINT `doctor_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `customer`
ADD CONSTRAINT `customer_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
What you need is an AFTER INSERT Trigger. This would allow you to create new users. In case if you want it to be updated on update and deleted on delete of the original record then you need those triggers as well.
CREATE TRIGGER `chat_users_insert` AFTER INSERT ON `doctors`
FOR EACH ROW BEGIN
INSERT INTO `chat_users` SET user_id= NEW.id;
END;
The above would insert a record and set the value of id. http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html can give you exact syntax. Let me know if you need any specific clarifications.
I know, this is not exactly an answer to your question but what about using an old fashioned view instead? This would save you from storing redundant data altogether.
CREATE VIEW chat_users AS
SELECT drid uid, drid userid, drname username, 0 FROM doctors
UNION ALL
SELECT clid+100000, clid, clname, 1 FROM clients
This view will have unique uids only if you don't have more than 100000 doctors in your table (otherwise choose a higher offset). The advantage of this approach would be that there is no dependent table data to maintain.
"I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted."
Why are you fretting about this? Just do it. You have application requirements that mandate it, so unless you can figure out how to unify your client and doctor tables, you will need a third that relates to your chat function.
The difficulty of adding this in an application framework is almost zero, it's just the case of creating an additional record when a client or doctor is created, and removing it when their respective record is deleted.
The other answers here propose using views or triggers to obscure what's really happening. This is generally a bad idea, it means your application isn't in charge of its own data, basically handing over control of certain application logic functions to the database itself.
The best solution is often the most obvious, as that leads to fewer surprises in the future.

Update table on condition from another table Trigger

I have a two tables
MovieStar (
name: char(15),
address:varchar(40),
gender:char(1),
birthdate: date,
rating:float
)
StarsIn (
movieTitle:char(25),
movieYear:int,
starname:char(15),
role:varchar(15)
)
starName is foreign key which is related to name of MovieStar.
I want to increment rating by one when Starsin record is inserted and role of the new record is 'main'
What it would do is;
on insert to starsin, check whether role = 'main'
if so, what is starname
increment rating of moviestar name = starname
I would not store the value rating in your table as it can be derived from the other table's data when it is required. And why are you using float for the count?
Create a VIEW which counts the rows in Starsin, based on your condition role = 'main' and then you have no need for the trigger and the count will always be up to date when new rows are added or removed.
With the trigger solution you also have to take account of row deletion to decrement the count.
EDIT: From the comment you made, here's a sample trigger (although the syntax may be wrong as I mainly work with SQL Server). I'm assuming the name field in the MovieStar table is a primary key and therefore unique.
CREATE TRIGGER UpdateRating AFTER INSERT ON StarsIn
FOR EACH ROW
BEGIN
UPDATE MovieStar SET rating =
(SELECT rating FROM MovieStar WHERE name = NEW.starname) + 1
FROM MovieStar INNER JOIN NEW ON MoveStar.name = NEW.starname
WHERE NEW.role = 'main'
END
I'm not familiar with MySQL, I work with SQL Server, where triggers need to be set based. I'm guessing the FOR EACH ROW part of the trigger means the statements are executed for each row inserted, but I may be wrong about that.
You need to create a trigger on insert and do the intended update.