So here it is guys,
I have four tables.
My first one :
CREATE TABLE IF NOT EXISTS `Users` (
`Id_User` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`Firstname` varchar(20) NOT NULL,
`Lastname` varchar(20) NOT NULL,
PRIMARY KEY (`Id_User`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1002 ;
It contains the people's data.
My second one :
CREATE TABLE IF NOT EXISTS `Subject` (
`PrimaryKey_Subject` varchar(4) NOT NULL,
`Subject_Name` int(5) NOT NULL,
PRIMARY KEY (`PrimaryKey_Subject`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
It contains the subject name : mathematic, science, biology, etc...
My third one :
CREATE TABLE IF NOT EXISTS `Register` (
`ForeignKey_User` smallint(5) unsigned NOT NULL,
`ForeignKey_Lesson` varchar(4) NOT NULL,
PRIMARY KEY (`ForeignKey_User`,`ForeignKey_Lesson`),
KEY `ForeignKey_User_I` (`ForeignKey_User`),
KEY `ForeignKey_Lesson` (`ForeignKey_Lesson`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This one allows a user to register to a lesson.
My fourth one :
CREATE TABLE IF NOT EXISTS `Subject_Annex` (
`PrimaryKey_Subject` varchar(4) NOT NULL,
`Number_Registered` int(5) NOT NULL,
PRIMARY KEY (`PrimaryKey_Subject`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And here it is,
How can I set a trigger that increment the Number_Registered each time someone register to a lesson?
For instance,
I create a user : John Doe --> Users Table.
Then afterwards, I have my Subject Table which contains all the courses: mathematics, science, biology, etc...
I can now, register, through the Register Table my freshly created user to a subject : let's say science
Then now we have the Subject_Annex Table, which through a trigger, and once my user, (John Doe), is linked to a subject, (Science), is supposed to be able to show the amount of users that registered to the subject from, (here Science),and also increase by 1 their number for each time someone register to this subject.
So to make it short,
How can I set a trigger that increments the registered number of user each time someone register to a subject ?
For example :
Primary Key Subject : Science
Number of registered : 1
(Someone else register)
Primary Key Subject : Science
Number of registered : 2
(Someone else register)
Primary Key Subject : Science
Number of registered : 2
Primary Key Subject : Mathematic
Number of registered : 1
Etc...
I managed to solved the problem by myself :
DELIMITER |
create trigger before_insert_subject_annexe
before INSERT
on Register
for each row
BEGIN
INSERT INTO Subject_Annex (PrimaryKey_Subject, Number_Registered)
VALUES (NEW.ForeignKey_Lesson, + 1)
ON DUPLICATE KEY UPDATE
Number_Registered=Number_Registered+1;
END;
DELIMITER |
Then on my Subjet_Annex Table :
CREATE TABLE IF NOT EXISTS `Subject_Annex` (
`PrimaryKey_Subject` varchar(4) NOT NULL,
`Number_Registered` int(5) NOT NULL,
PRIMARY KEY (`PrimaryKey_Subject`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I added an unique key on Number_Registered
Related
I wanted to use the value on student_lastname in table tbl_student as a default value of sis_password in
table tbl_sis_account but I am out of idea on how to do it. I tried putting "Select query" after the "Default" but it doesn'nt work, anyway here's the sql:
DROP TABLE IF EXISTS tbl_sis_account;
CREATE TABLE `tbl_sis_account`(
sis_account_id INT(15) NOT NULL AUTO_INCREMENT,
sis_username INT(15) NOT NULL,
sis_password VARCHAR(8) DEFAULT '====>Value of attribute student_lastname<====',
PRIMARY KEY(`sis_account_id`),
CONSTRAINT `sis_username_student_fk` FOREIGN KEY (`sis_username`) REFERENCES `tbl_student`
(`student_id`) ON UPDATE CASCADE
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
SELECT * FROM tbl_sis_account;
DROP TABLE IF EXISTS tbl_student;
CREATE TABLE `tbl_student` (
`student_id` INTEGER(15) NOT NULL AUTO_INCREMENT,
`student_firstname` VARCHAR(50) NOT NULL,
`student_midname` VARCHAR(50) NOT NULL,
`student_lastname` VARCHAR(50) NOT NULL,
PRIMARY KEY(`student_id`)
)ENGINE=INNODB AUTO_INCREMENT=20201 DEFAULT CHARSET=utf8mb4;
SELECT * FROM tbl_student;
No you can't do that, but you can query the tbl_student table at the time of insertion in the tbl_sis_account table to retrieve student_lastname from `student_id' via a nested sql query or a trigger.
I've figured the solution for this problem, for a while now. Forgot to post the answer though, coz I am no longer using this method. But here's what I did.
On the tbl_student I created a "After Insert trigger"
BEGIN
INSERT INTO tbl_sis_account (student_id,sis_password) values (new.student_id, concat(new.student,new.student_lastname));
END
so the inserted result on tbl_sis_account is
student_id | sis_password
20200001 | 202000001Doe
I want to create a table name Users where I should have have columns User, cookieID, sessionID, Geo and then I want to first three columns to have some random unique value assigned automatically. I tried to make all three columns AUTO_INCREMENT with User column PRIMARY and 'cookieIDandsessionIDcolumnUNIQUE`. The SQL code is:
CREATE TABLE `users` ( `User` VARCHAR(20) NOT NULL AUTO_INCREMENT ,
`cookieID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`sessionID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`Geo` VARCHAR(30) NULL DEFAULT NULL ,
PRIMARY KEY (`User`), UNIQUE (`cookieID`), UNIQUE (`sessionID`), UNIQUE (`Geo`));
But, it did not work because only one column can be declared as AUTO_INCREMENT which must be PRIMARY.
What is the another approach to do this?
Since the auto-increment cannot be applied to multiple to rows and there no option for sequence in MySQL. You can use triggers for the unique update of the row with datetime.
Change to table creation to be of single auto-increment row.
CREATE TABLE `users` ( `User` VARCHAR(20) NOT NULL,
`cookieID` INT(20) NULL DEFAULT NULL,
`sessionID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`Geo` VARCHAR(30) NULL DEFAULT NULL,
PRIMARY KEY (`User`), UNIQUE (`cookieID`), UNIQUE (`sessionID`), UNIQUE (`Geo`));
Create a trigger on the same table as below. You can set the unique values under the SET for as many column as you want.
CREATE DEFINER=`root`#`localhost` TRIGGER `users_BEFORE_INSERT` BEFORE INSERT ON `users` FOR EACH ROW BEGIN
SET
NEW.cookieID = (SELECT curdate()+curtime());
END
Now when you insert into the table as below.
insert into `users`(`User`) values("test");
You table looks like this.
User cookieID sessionID Geo
test 20315169 0 NULL
If the value which are auto incrementing, you wanna keep both values the same. Then copy the value of one column to another during insertion time of new value.
I create the MySql table by the following sql statement:
CREATE TABLE IF NOT EXISTS `mytable` (
`agent` varchar(64) NOT NULL,
`name` varchar(40) NOT NULL,
`app` varchar(64) NOT NULL,
PRIMARY KEY (`app`,`agent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As you see, the field 'app' and 'agent' is the primary key. But unfortunately it doesn't work when I insert the following data, it always show the duplicated key in 'app' field:
app agent name
-------------------------
MyApp ios cde
MyApp android abc
Can anybody tell me anything wrong? Thanks
In your primary key app and agent are a primary key together, not two individual keys.
You'll be able to add many rows with app = 'MyApp' as long as agent differs. And the other way around.
If you wan't to disallow multiple rows with the same app and multiple rows with the same agent add normal unique indexes.
CREATE TABLE IF NOT EXISTS `mytable` (
`agent` varchar(64) NOT NULL,
`name` varchar(40) NOT NULL,
`app` varchar(64) NOT NULL,
UNIQUE app_index (`app`),
UNIQUE agent_index (`agent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The set of primary keys in MySQL does not check for individual unique values, it will give duplicate error when you will try to insert same set of values in multiple records, but both the columns will not accept NULL values
Eg.
app agent name
-------------------------
MyApp ios cde
MyApp ios abc - it will give you error as "Duplicate entry 'MyApp-ios' for key 'PRIMARY'"
may this will help you
I would like to create some tables in MySQL. One table would be for users, one for topics, one for comments, and so on.
I need each table to have its own ID column in the following format:
USERS table: ID column
Values:
USR00001
USR00002
USR00003
..
..
USR99999
where as topics table would have IDs like:
TPC00001
TPC00002
TPC00003
similarly, the comments table would have the following IDs:
CMT00001
CMT00002
I tried to use UNIQUE key but did not work: (inspired by this answer)
CREATE TABLE `users` (
`ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT ,
`firstname` VARCHAR(100) NOT NULL ,
`lastname` VARCHAR(100) NOT NULL ,
`email` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`ID`)
UNIQUE KEY ( 'USR' + `ID`)
);
Can it be done using triggers (Before Insert) maybe?
Please note that I don't want to handle the insertion of the primary keys on the application level. I would prefer the database engine to handle all the work for that.
I'm creating a page where I want users to be able to book a seat for an event.
1 user can only book 1 seat
users have no seat selected upon login, first after buying into a spot
Need to able to clear seats table, without loosing anything from user-table (except of course the assigned seats.)
I've created two tables, and since I'm pretty new to mySQL, I wanted to check if this was done correctly:
members-table:
user_id int(8) Not null auto_increment
user_name varchar(30) Not null
user_pass varchar(255) Not null
seat_ID smallint(6) Yes NULL
seats-table
seat_ID smallint(6) No auto_increment
user_id smallint(6) Yes NULL
seat_status tinyint(4) Yes NULL
seat_status tinyint(4) Yes NULL
I've created 2 FK-refs:
ALTER TABLE seats
ADD CONSTRAINT FK_seats
FOREIGN KEY (user_id) REFERENCES members(user_id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE seats
ADD CONSTRAINT FK_seats
FOREIGN KEY (seat_ID) REFERENCES members(seat_ID)
ON UPDATE CASCADE
ON DELETE CASCADE;
Am I on the right track? Will I be able to progress to a decent final product with this setup? suggestions/improvements? I don't want to start all over in a couple of weeks because the database structure is of poor quality.
First of all I don't see why you're using a second table if any user can only hold one seat at any given time, secondly user_id in seats-table should be the same size as user_id in members table namely int(8), otherwise you won't be able to seat users after a while, third issue is the duplication of seat_status, I suppose that was a mistake or you had another name for it.
In my opinion a better idea is to use a single table if it's a 1->1 mapping and define it as
CREATE TABLE `members-table` (
user_id int(8) not null auto_increment,
user_name varchar(30) not null,
user_pass varchar(255) not null,
seat -- your type choice, should be nullable if not seated
);
Clearing the seats with this config would be as simple as
UPDATE `members-table` SET `seat` = NULL;
CREATE TABLE `seats` (
id int(4) unsigned not null auto_increment primary key,
row int(2) unsigned not null,
col int(2) unsigned not null,
UNIQUE(row, col)
) ENGINE InnoDB;
CREATE TABLE `members` (
user_id int(8) not null auto_increment primary key,
user_name varchar(30) not null,
user_pass varchar(255) not null,
seat int(4) unsigned null,
FOREIGN KEY(seat) references seats(id) on delete set null on update restrict,
UNIQUE(seat)
) ENGINE InnoDB;
You will have to populate the seats database with all available rows and columns, use null on id when inserting to use the auto_increment feature!
Check if a seat is taken
SELECT COUNT(*) AS occupied FROM members WHERE seat = (SELECT id FROM seats WHERE row = :ROW AND col = :COL);
Alternatively use SELECT (1 - COUNT(*)) AS vacant in the query above if it's more conveninent for you.
Find first free seat
SELECT MIN(id) FROM seats WHERE NOT EXISTS( SELECT seat FROM members WHERE seat = seats.id);
Unassign all taken seats
UPDATE members SET seat = NULL;