Only accept values based on another table ? (MySQL, PostgreSQL, Django) - mysql

I'm developing a School/University software and I got stucked in this situation:
Table Professor
id
name
1
Mr. Ward
2
Mr. Smith
Table Subject
id
name
1
Math
2
Physics
3
English
Table ProfessorsSubject
p_id
s_id
1
1
1
2
2
3
(Mr. Ward, Math), (Mr. Ward, Physics) and (Mr. Smith, English)
Table StudentClass:
id
name
Building
10
Tenth Grade
A
11
Eleventh Grade
A
Table A:
sclass_id
subj_id
prof_id
foo
bar
10
1
1
foo1
bar1
10
2
1
foo2
bar2
10
3
NULL
foo3
bar3
11
1
1
foo4
bar4
11
2
1
foo5
bar5
11
3
2
foo6
bar6
The pair(sclass_id, subj_id) must be UNIQUE.
prof_id might be NULL.
CREATE TABLE Professor (
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(100) NOT NULL
);
CREATE TABLE Subject (
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(100) NOT NULL
);
CREATE TABLE ProfessorsSubject (
prof_id int,
subj_id int,
PRIMARY KEY (prof_id, subj_id),
FOREIGN KEY (prof_id) REFERENCES Professor(id),
FOREIGN KEY (subj_id) REFERENCES Subject(id)
);
CREATE TABLE StudentClass (
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(100) NOT NULL,
building varchar(100)
);
CREATE TABLE A (
sclass_id int,
subj_id int,
prof_id int,
foo varchar(10),
bar varchar(10),
PRIMARY KEY (sclass_id, subj_id),
FOREIGN KEY (sclass_id) REFERENCES StudentClass (id),
FOREIGN KEY (subj_id ) REFERENCES ProfessorsSubject (subj_id),
FOREIGN KEY (prof_id ) REFERENCES ProfessorsSubject (prof_id)
);
/* ==================================================================== */
INSERT INTO Professor(id, name) VALUES (1, "Mr. Ward");
INSERT INTO Professor(id, name) VALUES (2, "Mr. Smith");
INSERT INTO Subject(id, name) VALUES (1, "Math");
INSERT INTO Subject(id, name) VALUES (2, "Physics");
INSERT INTO Subject(id, name) VALUES (3, "English");
INSERT INTO ProfessorsSubject (prof_id, subj_id) VALUES (1, 1);
INSERT INTO ProfessorsSubject (prof_id, subj_id) VALUES (1, 2);
INSERT INTO ProfessorsSubject (prof_id, subj_id) VALUES (2, 3);
INSERT INTO StudentClass(id, name, building) VALUES (10, "Tenth Grade", "A");
INSERT INTO StudentClass(id, name, building) VALUES (11, "Eleventh Grade", "A");
/* ==================================================================== */
INSERT INTO A (sclass_id, subj_id, prof_id, foo, bar) VALUES (10, 1, 1, "foo1", "bar1");
INSERT INTO A (sclass_id, subj_id, prof_id, foo, bar) VALUES (10, 2, 1, "foo2", "bar2");
INSERT INTO A (sclass_id, subj_id, prof_id, foo, bar) VALUES (10, 3, 1, "foo3", "bar3");
/* ==================================================================== */
Mr. Ward shouldn't be able to teach English to Tenth Grade, because this combination is not present in table ProfessorsSubject.
To avoid inconsitences in a database level, how to make sure the pair (prof_id, subj_id) in Table A respects what is in "SubjectOfProfessor" table before insert?
1.1) Is it necessary to use Procedures? Triggers ?
1.2) Is it possible to make this just using fields proprieties and/or constraints ?
What if I wanted to do this using Django ORM in a databased level ?
Reference: migrations.RunSQL('ALTER TABLE app_event ADD CONSTRAINT chronology CHECK (start_date > end_date);

You can use a combined foreign key in the table A as you did with the primary key in the table ProfessorsSubject. A corresponding index on the referenced table is required which actually is fulfilled by its primary key already.
FOREIGN KEY (subj_id, prof_id) REFERENCES ProfessorsSubject (subj_id, prof_id)

Related

Mysql How to SELECT information based other tables

I would like to get tokens. E.g if i would like to SELECT Gregor, Liza and if we look into committee it should retrive then their own tokens and also Matt, Bob tokens
Table structure:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);
INSERT INTO users (name)
VALUES ("Gregor"),
("Liza"),
("Matt"),
("Bob"),
("Tom");
CREATE TABLE committee(
user_id INT,
friend_id INT,
member_id INT,
PRIMARY KEY (`user_id`, `friend_id`, `member_id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`member_id`) REFERENCES `users` (`id`)
);
INSERT INTO committee (user_id, friend_id, member_id)
VALUES (1, 2, 3),
(1, 2, 4);
CREATE TABLE tokens(
user_id INT,
token VARCHAR(255)
);
INSERT INTO tokens (user_id, token)
VALUES (1, "lclasld2"),
(2, "xxkakdasd"),
(3, "123kdkfs"),
(4, "hjj32"),
(5, "zz3dja");
Current query i got:
SELECT token FROM tokens WHERE user_id IN (1, 2);
How it behave now:
user_id, token
1, lclasld2
2, xxkakdasd
What i expect, when i run the query:
user_id, token
1, lclasld2
2, xxkakdasd
3, 123kdkfs
4, hjj32
I think it's enough to use the query without where clause
SELECT * FROM tokens
Your database design could be better or the schema values that you have used for demo arent correct.
You can try this
SELECT token
FROM tokens
WHERE user_id IN (SELECT member_id
FROM committee
WHERE user_id IN ( 1, 2 ))
OR user_id IN ( 1, 2 );

Mysql SELECT get all columns in the table based on one WHERE condition

I would like to get tokens based on one WHERE condition. E.g if i would like to SELECT Gregor and if we look into committee it should retrive then the token for Liza, Matt
Table structure:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);
INSERT INTO users (name)
VALUES ("Gregor"),
("Liza"),
("Matt"),
("Bob");
CREATE TABLE committee(
user_id INT,
friend_id INT,
member_id INT,
PRIMARY KEY (`user_id`, `friend_id`, `member_id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`member_id`) REFERENCES `users` (`id`)
);
INSERT INTO committee (user_id, friend_id, member_id)
VALUES (1, 2, 3),
(1, 2, 4);
CREATE TABLE tokens(
user_id INT,
token VARCHAR(255)
);
INSERT INTO tokens (user_id, token)
VALUES (1, "lclasld2"),
(2, "xxkakdasd"),
(3, "123kdkfs"),
(4, "hjj32");
Current query i got:
SELECT token FROM tokens WHERE user_id = 1;
How it behave now:
user_id, token
1, lclasld2
What i expect, when i run the query:
user_id, token
2, xxkakdasd
3, 123kdkfs
4, hjj32
You can union the select friend _id and member_id for user_id 1
SELECT
user_id, token
FROM tokens
WHERE user_id IN (SELECT friend_id FROM committee WHERE user_id = 1
UNION SELECT member_id FROM committee WHERE user_id = 1)
user_id | token
------: | :--------
2 | xxkakdasd
3 | 123kdkfs
4 | hjj32
db<>fiddle here
Instead of trying to insert all of values in one line, trying adding an insert for each individual object like so: INSERT INTO TOKENS() VALUES(); INSERT INTO TOKENS() VALUES(), so on and so forth.

How to achieve this in a database?

I am new to databases, but I am getting a problem:
Here AAA, BBB, TABLE-1, TABLE-2 and TABLE-3 table names(tables).
TABLE-1 (A, B) COMPOUND PRIMARY KEY(A,B) AND A IS REFER FROM *AAA(A)* AND B IS REFER FROM *BBB(B)*
1 1
1 2
2 1
TABLE-2 (D, A) D IS PRIME AND A IS REFER FROM *AAA(A)*
1 1
2 2
TABLE-3 (D, B) COMPOUND PRIMARY KEY(D,B) AND B IS REFER FROM *BBB(B)*
1 1
2 2
HERE MEANING OF TABLE-2 AND TABLE-3 IS
(D, A, B)
1 1 1
2 2 2
But the problem is in second row here A = 2, B=2 is not matching with TABLE-1.
How to achieve this?
Ex:
I have Airport, Caterer, Meal, Airport_caterer_map, Airport_Meal_Map
Airport (this main configuration table)
id Name
1 aaa
2 bbb
Caterer (this main configuration table)
id Name
1 mmm
2 nnn
Airport_caterer_map (this main configuration table)
airport_id caterer_id
1 1
1 2
2 1
Meal
id Name caterer_id
1 mmm 1
2 nnn 2
Airport_Meal_Map
mail_id airport_id
1 1
1 2
2 1
2 2 -- This row should be wrong.
why is,
1. meal 2 is available in airport 2
2. meal 2 is providing by caterer 2
3. But there is no mapping between caterer 2 and airport 2 in airport_caterer_map table.
Basically, your Airport_Meal_Map should actually be an Airport_Caterer_Meal_Map - if you want the database to help with the consistency checks:
CREATE TABLE Airport
(
id INT primary key,
name VARCHAR(30)
);
INSERT INTO Airport VALUES
(1, 'aaa'),
(2, 'bbb');
CREATE TABLE Caterer
(
id INT primary key,
name VARCHAR(30)
);
INSERT INTO Caterer VALUES
(1, 'mmm'),
(2, 'nnn');
CREATE TABLE Airport_Caterer_Map
(
airport_id INT,
caterer_id INT,
PRIMARY KEY (airport_id, caterer_id),
FOREIGN KEY (airport_id) REFERENCES Airport(id),
FOREIGN KEY (caterer_id) REFERENCES Caterer(id)
);
INSERT INTO Airport_Caterer_Map (airport_id, caterer_id) VALUES
(1, 1),
(1, 2),
(2, 1);
-- INSERT INTO Airport_Caterer_Map (airport_id, caterer_id) VALUES
-- (2, 2);
CREATE TABLE Meal
(
id INT,
name VARCHAR(30),
caterer_id INT,
PRIMARY KEY (id, caterer_id),
FOREIGN KEY (caterer_id) REFERENCES Caterer(id)
);
INSERT INTO Meal (id, name, caterer_id) VALUES
(1, 'mmm', 1),
(2, 'nnn', 2);
-- INSERT INTO Meal (id, name, caterer_id) VALUES
-- (1, 'mmm', 2);
-- INSERT INTO Meal (id, name, caterer_id) VALUES
-- (2, 'nnn', 1);
CREATE TABLE Airport_Meal_Map -- actually Airport_Caterer_Meal_Map
(
meal_id INT,
airport_id INT,
caterer_id INT,
PRIMARY KEY (meal_id, airport_id, caterer_id),
FOREIGN KEY (airport_id, caterer_id) REFERENCES Airport_Caterer_Map(airport_id, caterer_id),
FOREIGN KEY (meal_id, caterer_id) REFERENCES Meal(id, caterer_id)
);
INSERT INTO Airport_Meal_Map (meal_id, airport_id, caterer_id) VALUES
(1, 1, 1),
(1, 2, 1),
(2, 1, 2);
-- Fails as meal 1 is not prepared by caterer 2
-- INSERT INTO Airport_Meal_Map (meal_id, airport_id, caterer_id) VALUES
-- (1, 1, 2);
-- Fails as meal 2 is not prepared by caterer 1
-- INSERT INTO Airport_Meal_Map (meal_id, airport_id, caterer_id) VALUES
-- (2, 1, 1);
-- Fails as airport 2 is not served by caterer 2
-- INSERT INTO Airport_Meal_Map (meal_id, airport_id, caterer_id) VALUES
-- (2, 2, 2);
SQL Fiddle

Msg 2627 Violation of PRIMARY KEY constraint

trying to make a database for teams in a tv show here.
but when I try and insert data into tblShowteam
the following error made its appearance.
Msg 2627, Level 14, State 1, Line 2
Violation of PRIMARY KEY constraint 'PK__tblShowt__F693078C03317E3D'. Cannot insert duplicate key in object 'dbo.tblShowteam'.
tables
-- tabbellen aanmaken
create table tblShow(
setId int,
Datum date,
teams int
primary key (setId));
create table tblShowteam(
SetId int,
datum date,
teams int,
primary key (teams));
create table tblTeam(
TeamId int,
Coach varchar(35),
CoachId int,
teams int
primary key (CoachId));
-- participant table
create table tblDeelnemer(
DeelnemerId int identity(1, 1),
DeelnemerV varchar(35),
deelnemerT_V varchar(10),
DeelnemerA varchar(35),
CoachId int,
datum_optreden date
primary key (DeelnemerId));
--table for the public viewers
create table tblKijker(
Kijkerv varchar(35),
KijkerT_V varchar(10),
KijkerA varchar(35),
Stoelnummer int identity(1,3),
ShowId int Not null,
Email varchar(35)
primary key (Email));
my inserts would look like this:
insert into tblShowteam values (1, '2014-06-28', 1)
insert into tblShowteam values (2, '2014-06-05', 1)
insert into tblShowteam values (3, '2014-06-12', 1)
insert into tblShowteam values (4, '2014-06-19', 1)
insert into tblShowteam values (5, '2014-06-26', 1)
all other inserts (in diffrent tables) work like normal.
what am i doing wrong here?
your problem is here
primary key (teams));
i guess you have to do it like that
primary key (setId));
like that:
create table tblShowteam(
SetId int,
datum date,
teams int,
primary key (setId));
because you are inserting same teams 1 while you are using teams as primary key which means no duplicates.
your inserts:
insert into tblShowteam values (1, '2014-06-28', 1)
insert into tblShowteam values (2, '2014-06-05', 1)
...
DB translate it like this:
insert into tblShowteam (SetId, datum, teams) values (1, '2014-06-28', 1);
cause the third column is your primary key, you got this error.

How can I insert a new row, but if the combination of 2 values already exist update the row?

my table looks like this
CREATE TABLE sample
(
id int auto_increment primary key,
W_ID varchar(20),
TC_ID varchar(20),
foo varchar(20),
bar varchar(20)
);
I want to insert a new row into this table, but if the combination of W_ID and TC_ID already exists, i want to update the row with the new values of 'foo' and 'bar'
I know there are a lot of similar questions on here, but i can't figure it out....
made a sample in sqlfiddle.com
i am using 5.6.11-MySQL - Apache/2.2.22 (Win32) PHP/5.3.25
you can create a unique key of the combination of W_ID and TC_ID then perform your upsert on it as follows:
CREATE TABLE sample
(
id int auto_increment primary key,
W_ID varchar(20),
TC_ID varchar(20),
foo varchar(20),
bar varchar(20)
);
alter table sample add constraint UNIQUE (W_ID, TC_ID);
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('1', '2','123','123');
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('2', '2','123','123');
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('3', '2','123','123');
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('1', '4','123','123');
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('2', '3','123','123');
INSERT INTO sample
(W_ID, TC_ID,foo,bar)
VALUES ('1', '2','123','123')
ON DUPLICATE KEY UPDATE
`foo` = 'newFoo';
your results would look like:
ID W_ID TC_ID FOO BAR
1 1 2 newFoo 123
2 2 2 123 123
3 3 2 123 123
4 1 4 123 123
5 2 3 123 123
If you add unique constraint on the two columns you'll be able to use on duplicate key update syntax.
Adding an unique constrain should be something like that:
alter table table_name add unique index index_name(col1, col2);
You'll find more details here