Msg 2627 Violation of PRIMARY KEY constraint - mysql

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.

Related

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

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)

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 );

Adding items in MySQL table

I was preparing to create a website using PHPMyAdmin and I bang into a problem : I don't understant why my code does things I don't want.
This is the code to create the tables and some random entries :
create table stud (
matrnr int primary key,
pname Varchar(30) not null
);
create table prof (
persnr int primary key,
pname Varchar(50) not null
);
create table vorl (
vorlnr int primary key,
titel varchar(50),
prof int references prof(persnr) on delete set null
);
create table prüfen (
stud int references stud(matrnr) on delete cascade,
vorl int references vorl(vorlnr),
prof int references prof(persnr) on delete set null,
note float,
primary key(Stud, vorl)
);
insert into stud values
(1, 'G'),
(2, 'F'),
(3, 'C');
insert into Prof values
(1, 'M'),
(2, 'L'),
(3, 'M');
insert into vorl values
(1, 'Info1', 'M'),
(1, 'Info2', 'L'),
(1, 'Info3', 'M');
insert into prüfen values
(1, 1, 1, 2.0),
(1, 2, 1, 1.7),
(2, 3, 2, 2.3);
At this position I tried
Insert into prüfen values (3, 1, 4, 2.0);
but the was still only 3 lines in the table prüfen.
Any help is wellcome.
Have a good week.
Your final insert failed because it references a professor with a prof ID of 4, which does not exist in the prof table.
If you look closely at your definition for the prüfen table, this will be more clear:
create table prüfen (
stud int references stud(matrnr) on delete cascade,
vorl int references vorl(vorlnr),
prof int references prof(persnr) on delete set null,
note float,
primary key(Stud, vorl)
);
The field prof is a foreign key into the prof table. MySQL will require that this field references a professor which actually exists. It does not in the case of your final insert. To get around this error, you could create such a professor, e.g.
insert into Prof values
(4, 'M');
You didn't report an error in your question, which seems off to me. Maybe you failed to mention it, or perhaps your error reporting is turned off for some reason.

mysql statement wont insert

Hey guys I've searched for answers through the forums but to no avail so I'm using MySql and I'm trying to insert statements for certain tables and they aren't going into the tables and I'm getting errors like "Msg 8152, Level 16, State 14, Line 1
String or binary data would be truncated. The statement has been terminated."
These are the statements I'm having problems with.`INSERT INTO Course VALUES
INSERT INTO Course VALUES (12345, 'DatabaseManagement', '2015-2-1', '2014-5-9');
INSERT INTO Course VALUES (12346, 'Calculus', '2015-1-12', '2015-5-9');
INSERT INTO Course VALUES (12347, 'Biology', '2015-1-3', '2015-5-9');
INSERT INTO Course VALUES (12348, 'Chemistry', '2015-1-2', '2015-5-9');
INSERT INTO Grade VALUES (10, 12345, 012, 'A');
INSERT INTO Grade VALUES (11, 12346, 013, 'B');
INSERT INTO Grade VALUES (12, 12347, 014, 'C');
INSERT INTO Grade VALUES (13, 12348, 015, 'D');
INSERT INTO Grade VALUES (14, 12345, 016, 'B');
INSERT INTO Student VALUES (54321, 'Rachel', 'Cotterel', '2013-4-15', '2016-3-4');
INSERT INTO Student VALUES (54320, 'John', 'Smith', '2012-1-23', NULL);
INSERT INTO Student VALUES (54319, 'Johny', 'Depp', '2010-5-12', '2012-10-10');
INSERT INTO Student VALUES (54318, 'Orlando', 'Bloom', '2014-6-24', NULL);
INSERT INTO Student VALUES (54317, 'Linda', 'Jacob', '2015-4-4', '2019-8-6');
I didn't get any error for insert into Course statements. I got error for INSERT INTO Grade statements. Its because there is no reference available for StudentID 012,013 etc in Student table. And you are trying to add them in grade table.
Try using this:
INSERT INTO table1 (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
These are the field types:
CREATE TABLE Course
(
CourseID int,
Description varchar(20) NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
CONSTRAINT [PK_CourseID] PRIMARY KEY (CourseID)
);
CREATE TABLE Grade
(
GradeID integer(10) NOT NULL,
CourseID integer(10) NOT NULL,
StudentID integer(10) NOT NULL,
Grade varchar (10) NULL,
CONSTRAINT [PK_GradeID] PRIMARY KEY (GradeID),
CONSTRAINT [FK_CourseID] FOREIGN KEY (CourseID) REFERENCES Course(CourseID),
CONSTRAINT [FK_StudentID] FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);
CREATE TABLE Student
(
StudentID integer(10) NOT NULL,
FirstName varchar(45) NOT NULL,
LastName varchar(45) NOT NULL,
RegistrationDate varchar (45) NOT NULL,
GraduationDate DATE NULL,
CONSTRAINT [PK_StudentlID] PRIMARY KEY (StudentID)
);
String or binary data would be truncated
The reason that you get this message should be that you are trying to insert some value to some field to which you haven't assigned enough size to hold the value.
Can you send what the exact error message you get?
I tried to do it myself.But the error I got was from you insertion query to Grade table foreign key fails which refer Student table because you are trying to insert Student_IDs which are not there in you Student table

Aggregate Query depending on several tables

I want to create a database with information of employees, their jobs, salaries and projects
I want to keep information of the cost of a project (real value of project and the days a employee invested)
For employee and project each Employee has one role on the Project through the PK constraint, and allows for the addition of a new role type ("Tertiary" perhaps) in the future.
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Sex CHAR(1) NOT NULL,
Address VARCHAR(80) NOT NULL,
Security VARCHAR(15) NOT NULL,
DeptID INTEGER NOT NULL,
JobID INTEGER NOT NULL
);
CREATE TABLE Departments (
DeptID INTEGER NOT NULL PRIMARY KEY,
DeptName VARCHAR(30) NOT NULL
);
CREATE TABLE Jobs (
JobID INTEGER NOT NULL PRIMARY KEY,
JobName VARCHAR(30) NOT NULL,
JobSalary DOUBLE(15,3) NOT NULL default '0.000',
JobSalaryperDay DOUBLE(15,3) NOT NULL default '0.000',
DeptID INTEGER NOT NULL
);
CREATE TABLE Project(
ProjectID INTEGER NOT NULL PRIMARY KEY,
ProjectDesc VARCHAR(200) NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
DaysOfWork INTEGER NOT NULL,
NoEmployees INTEGER NOT NULL,
EstimatedCost DOUBLE(15,3) NOT NULL default '0.000',
RealCost DOUBLE(15,3) NOT NULL default '0.000'
);
CREATE TABLE `Project-Employee`(
ProjectID INTEGER NOT NULL,
EmployeeID INTEGER NOT NULL,
Note VARCHAR(200),
DaysWork INTEGER NOT NULL,
CONSTRAINT fk_ProjectID FOREIGN KEY (ProjectID) REFERENCES Project(ProjectID),
CONSTRAINT fk_EmployeeID FOREIGN KEY (EmployeeID) REFERENCES Employee(EmployeeID)
);
INSERT INTO `Departments` VALUES (1, 'Outsourcing');
INSERT INTO `Departments` VALUES (2, 'Technician');
INSERT INTO `Departments` VALUES (3, 'Administrative');
INSERT INTO `Jobs` VALUES (1, 'welder' ,500.550,16.7 ,2);
INSERT INTO `Jobs` VALUES (2, 'turner' ,500.100,16.67,2);
INSERT INTO `Jobs` VALUES (3, 'assistant' ,650.100,21.67,2);
INSERT INTO `Jobs` VALUES (4, 'supervisor',800.909,26.70,3);
INSERT INTO `Jobs` VALUES (5, 'manager' ,920.345,30.68,3);
INSERT INTO `Jobs` VALUES (6, 'counter' ,520.324,17.35,1);
INSERT INTO `Employee` VALUES (10, 'Joe', 'M', 'Anywhere', '927318344', 1, 3);
INSERT INTO `Employee` VALUES (20, 'Moe', 'M', 'Anywhere', '827318322', 2, 3);
INSERT INTO `Employee` VALUES (30, 'Jack', 'M', 'Anywhere', '927418343', 3, 4);
INSERT INTO `Employee` VALUES (40, 'Marge','F', 'Evererre', '127347645', 1, 6);
INSERT INTO `Employee` VALUES (50, 'Greg' ,'M', 'Portland', '134547633', 3, 5);
INSERT INTO `Project` VALUES (1, 'The very first', '2008-7-04' , '2008-7-24' , 20, 5, 3000.50, 2500.00);
INSERT INTO `Project` VALUES (2, 'Second one pro', '2008-8-01' , '2008-8-30' , 30, 5, 6000.40, 6100.40);
INSERT INTO `Project-Employee` VALUES (1, 10, 'Worked all days' , 20);
INSERT INTO `Project-Employee` VALUES (1, 20, 'Worked just in defs', 11);
INSERT INTO `Project-Employee` VALUES (1, 30, 'Worked just in defs', 17);
INSERT INTO `Project-Employee` VALUES (1, 40, 'Contability ' , 8);
INSERT INTO `Project-Employee` VALUES (1, 50, 'Managed the project', 8);
So to get the total amount of the cost of a project and have it for future Work quote I would just sum the working days of each job for each employee in an aggregate query.
What would be the query to sum all working days knowing the employees involved in a particular project to know the cost generated for their work, Is it possible to know this with this design?
So lets suppose I know that in project 1, 5 employees were involved, and I know by other table "jobs" the salary I would pay each one of them per day
I am doing some queries here with sqlfiddle
UPDATE
CREATE TABLE `Sexes` (
Sex char(1) primary key
);
INSERT INTO Sexes values ('M');
INSERT INTO Sexes values ('F');
CREATE TABLE `Employee`(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(130) NOT NULL,
Sex CHAR(1) NOT NULL,
Address VARCHAR(380) NOT NULL,
Security VARCHAR(15) NOT NULL,
FOREIGN KEY (Sex) references Sexes (Sex),
CONSTRAINT `uc_EmployeeInfo` UNIQUE (`EmployeeID`,`Name`,`Security`)
);
CREATE TABLE `Department` (
DeptID INTEGER NOT NULL PRIMARY KEY,
DeptName VARCHAR(30) NOT NULL,
CONSTRAINT `uc_DeptName` UNIQUE (`DeptID`,`DeptName`)
);
CREATE TABLE `Dept-Employee`(
EmployeeID INTEGER NOT NULL,
DeptID INTEGER NOT NULL,
CONSTRAINT fk_DeptID FOREIGN KEY (DeptID) REFERENCES `Department`(DeptID),
CONSTRAINT fk_EmployeeID FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);
CREATE TABLE `Dept-Manager`(
EmployeeID INTEGER NOT NULL,
DeptID INTEGER NOT NULL,
CONSTRAINT fk_DeptIDs FOREIGN KEY (DeptID) REFERENCES `Department`(DeptID),
CONSTRAINT fk_EmployeeIDs FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);
CREATE TABLE `Jobs` (
JobID INTEGER NOT NULL PRIMARY KEY,
JobName VARCHAR(30) NOT NULL,
JobSalary DECIMAL(7,3) NOT NULL default '0000.000',
JobSalaryperDay DECIMAL(7,3) NOT NULL default '0000.000',
CONSTRAINT `uc_jobs` UNIQUE (`JobID`,`JobName`)
);
CREATE TABLE `Jobs-Employee`(
EmployeeID INTEGER NOT NULL,
JobID INTEGER NOT NULL,
CONSTRAINT fk_JobIDs FOREIGN KEY (JobID) REFERENCES `Jobs`(JobID),
CONSTRAINT fk_EmployeeIDss FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);
CREATE TABLE `Project`(
ProjectID INTEGER NOT NULL PRIMARY KEY,
ProjectName VARCHAR(200) NOT NULL,
StartDate DATE NOT NULL,
DaysOfWork INTEGER NOT NULL,
NoEmployees INTEGER NOT NULL,
EstimatedCost DECIMAL(9,3) NOT NULL default '000000.000',
RealCost DECIMAL(9,3) NOT NULL default '000000.000',
CONSTRAINT `uc_project` UNIQUE (`ProjectID`,`ProjectName`)
);
CREATE TABLE `Project-Employee`(
ProjectID INTEGER NOT NULL,
EmployeeID INTEGER NOT NULL,
Note VARCHAR(200),
DaysWork INTEGER NOT NULL,
CONSTRAINT fk_ProjectIDsss FOREIGN KEY (ProjectID) REFERENCES `Project`(ProjectID),
CONSTRAINT fk_EmployeeIDsss FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);
INSERT INTO `Department` VALUES (1, 'Outsourcing');
INSERT INTO `Department` VALUES (2, 'Technician');
INSERT INTO `Department` VALUES (3, 'Administrative');
INSERT INTO `Jobs` VALUES (1, 'welder' ,500.550, 16.7 );
INSERT INTO `Jobs` VALUES (2, 'turner' ,500.100, 16.67);
INSERT INTO `Jobs` VALUES (3, 'assistant' ,650.100, 21.67);
INSERT INTO `Jobs` VALUES (4, 'supervisor',800.909, 26.70);
INSERT INTO `Jobs` VALUES (5, 'manager' ,920.345, 30.68);
INSERT INTO `Jobs` VALUES (6, 'counter' ,520.324, 17.35);
INSERT INTO `Employee` VALUES (10, 'Joe', 'M', 'Joewhere', '927318344');
INSERT INTO `Employee` VALUES (20, 'Moe', 'M', 'Moewhere', '827318322');
INSERT INTO `Employee` VALUES (30, 'Jack', 'M', 'Jaswhere', '927418343');
INSERT INTO `Employee` VALUES (40, 'Marge','F', 'Evererre', '127347645');
INSERT INTO `Employee` VALUES (50, 'Greg' ,'M', 'Portland', '134547633');
INSERT INTO `Dept-Employee` VALUES (10,1);
INSERT INTO `Dept-Employee` VALUES (20,2);
INSERT INTO `Dept-Employee` VALUES (30,3);
INSERT INTO `Dept-Employee` VALUES (40,1);
INSERT INTO `Dept-Employee` VALUES (50,3);
INSERT INTO `Jobs-Employee` VALUES (10,3);
INSERT INTO `Jobs-Employee` VALUES (20,3);
INSERT INTO `Jobs-Employee` VALUES (30,4);
INSERT INTO `Jobs-Employee` VALUES (40,6);
INSERT INTO `Jobs-Employee` VALUES (50,5);
INSERT INTO `Project` VALUES (1, 'The very first', '2008-7-04' , 20, 5, 3000.50, 2500.00);
INSERT INTO `Project` VALUES (2, 'Second one pro', '2008-8-01' , 30, 5, 6000.40, 6100.40);
INSERT INTO `Project-Employee` VALUES (1, 10, 'Worked all days' , 20);
INSERT INTO `Project-Employee` VALUES (1, 20, 'Worked just in defs', 11);
INSERT INTO `Project-Employee` VALUES (1, 30, 'Worked just in defs', 17);
INSERT INTO `Project-Employee` VALUES (1, 40, 'Contability ' , 8);
INSERT INTO `Project-Employee` VALUES (1, 50, 'Managed the project', 8);
To the new structure I did this
CREATE VIEW `Emp-Job` as
SELECT e.*,j.jobID
FROM Employee e,`Jobs-Employee` j
WHERE e.EmployeeID = j.EmployeeID;
CREATE VIEW `employee_pay` as
select e.*, j.jobname, j.jobsalary, j.jobsalaryperday
from `Emp-Job` e
inner join `Jobs` j
on e.JobID = j.JobID;
create view project_pay as
select pe.projectid, pe.employeeid, pe.dayswork,
e.jobsalaryperday, (e.jobsalaryperday * dayswork) as total_salary
from `Project-Employee` pe
inner join `employee_pay` e
on e.employeeid = pe.employeeid
The data at the end of your question doesn't seem to match the data in your INSERT statements.
Have you ever heard of "divide and conquer"? This is a good time to use it. Here's what I'd do.
create view employee_pay as
select e.*, j.jobname, j.jobsalary, j.jobsalaryperday
from employee e
inner join jobs j on e.jobid = j.jobid
create view project_pay as
select pe.projectid, pe.employeeid, pe.dayswork,
e.jobsalaryperday, (e.jobsalaryperday * dayswork) as total_salary
from project_employee pe
inner join employee_pay e
on e.employeeid = pe.employeeid
I'd do that, because I expect those views to be generally useful. (Especially for debugging.) Having created those views, the total for a project is dead simple.
select projectid, sum(total_salary) as total_salaries
from project_pay
group by projectid
projectid total_salaries
--
1 1509.91
You really don't want to use DOUBLE for money. Use DECIMAL instead.
Use this query to sort out why my sum doesn't match yours.
select p.*, e.name
from project_pay p
inner join employee e on e.employeeid = p.employeeid;
projectid employeeid dayswork jobsalaryperday total_salary name
1 10 20 21.67 433.4 Joe
1 20 11 21.67 238.37 Moe
1 30 17 26.7 453.9 Jack
1 40 8 17.35 138.8 Marge
1 50 8 30.68 245.44 Greg
Anti-patterns
Broken identity
Whenever you see a table like this one
CREATE TABLE Departments (
DeptID INTEGER NOT NULL PRIMARY KEY,
DeptName VARCHAR(30) NOT NULL
);
you should assume its structure is wrong, and dig deeper. (It's presumed guilty until proven innocent.) The anti-pattern you look for
integer as an artificial primary key, along with
no other unique constraints.
A table like this allows the real data to be duplicated, eliminating the usefulness of an artificial key.
DeptID DeptName
--
1 Wibble
2 Wibble
...
175 Wibble
A table like this will allow multiple foreign key references, too. That means some of the foreign keys might reference Wibble (DeptID = 1), some might reference Wibble (DeptID = 175), and so on.
To fix that, add a UNIQUE constraint on DeptName.
Missing foreign key references
Whenever you see a table like this one
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
...
DeptID INTEGER NOT NULL,
JobID INTEGER NOT NULL
);
you should assume its structure is wrong, and dig deeper. (Again, it's presumed guilty until proven innocent.) The anti-pattern you look for
ID numbers from other tables, along with
no foreign key constraints referencing those tables.
To fix that, add foreign key constraints for DeptID and JobID. On MySQL, make sure you're using the INNODB engine, too. (As of MySQL 5.6, MyISAM still won't enforce foreign key constraints, but it won't give you an error or warning if you write them. They're parsed and ignored.)
If you come to MySQL from another dbms, you'll be surprised to find that MySQL doesn't support inline foreign key reference syntax. That means you can't write this.
DeptID integer not null references Departments (DeptID)
Instead, you have to write a separate foreign key clause in the CREATE TABLE statement. (Or use a separate ALTER TABLE statement to declare the FK reference.)
DeptID integer not null,
foreign key (DeptID) references Departments (DeptID)
Search this page for "inline ref", but read the whole thing.
Missing CHECK() constraints
MySQL doesn't enforce CHECK() constraints, so for columns that beg for a CHECK() constraint, you need a table and a foreign key reference. When you see a structure like this
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Sex CHAR(1) NOT NULL,
the column "Sex" begs for a CHECK() constraint.
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Sex CHAR(1) NOT NULL CHECK( Sex IN ('M', 'F')),
But MySQL doesn't enforce CHECK() constraints, so you need another table and a foreign key reference.
create table sexes (
sex char(1) primary key
);
insert into sexes values ('M');
insert into sexes values ('F');
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Sex CHAR(1) NOT NULL,
...
foreign key (Sex) references Sexes (Sex)
I'd consider CHECK() constraints for most of these columns. Some can be implemented as tables with foreign key references.
Employee.Security
Jobs.JobSalary
Jobs.JobSalaryperDay
Project.DaysOfWork
Project.NoEmployees
Project.EstimatedCost
Project.RealCost
Project_Employee.DaysWork
Using floating-point data types for money
Don't do that. Floating-point numbers are useful approximations, but they're still approximations. Use DECIMAL instead.