How to insert in MYSQL with foreign key errors - mysql

I have created a table but when i try to insert values I get an error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (classicmodels.complaints, CONSTRAINT complaints_ibfk_1 FOREIGN KEY (employeeHandling) REFERENCES customers (customerNumber))
I'm not entirely sure what this means so an explanation would be very helpful! Thank you!
CREATE TABLE `complaints` (
`complaintNumber` INT UNIQUE AUTO_INCREMENT,
`customerNumber` INT NOT NULL,
`orderNumber` INT,
`employeeHandling` INT NOT NULL,
`startDate` DATE NOT NULL,
`closeDate` DATE,
`complaintType` VARCHAR(250) NOT NULL,
`details` TEXT,
`resolution` TEXT,
`status` VARCHAR(250) NOT NULL,
PRIMARY KEY (`complaintNumber`),
FOREIGN KEY (`employeeHandling`) REFERENCES customers (`customerNumber`),
FOREIGN KEY (`customerNumber`) REFERENCES employees (`employeeNumber`),
FOREIGN KEY (`orderNumber`) REFERENCES orders (`orderNumber`)
);
INSERT INTO complaints
VALUES
(NULL, 173, NULL, 1323, '2005-03-27', NULL, 'Late Shipment', 'Customer claims shipment came in 2 weeks late. Requests discount/partial refund.', NULL, 'New'),
(NULL, 260, 10283, 1323, '2004-09-18', '2004-09-22', 'Damaged Shipment', 'Motorcycle had broken axle. Requests replacement, partial refund.', 'Axle sent and installed. Customer took $1000 refund', 'Closed'),
(NULL, 385, 10108, 1621, '2003-04-22', '2003-04-23', 'Missing Item', 'Customer claims item not included in shipment. Requests shipment.', 'Customer miscounted shipment stock. No action required.', 'Closed'),
(NULL, 471, 10265, 1611, '2004-07-10', '2004-08-10', 'Unclear', 'Customer disatisfied with shipment quality(?), though inventory not damaged. Requests refund.', 'Customer failed to provide specific reasons. Complaint ticket closed after 1 month of idle time.', 'Closed');

Related

sql integrity constraint parent key not found

I am trying to do something so simple creating and insert 4 tables with their data. I have spent hours on the web researching integrity constraints and tried several IDE's in case there's a bug but nothing seems to work. Code is shows below (excuted in order).
I can insert the data for the first two tables i.e vod_actor and vod_classification but when trying to add third/fourth table data I get the following error:
ORA-02291: integrity constraint (SYSTEM.VOD_FILM_CLASS_FK) violated - parent
I don't understand why because the FK for vod_film is the PK for vod_classification which already has its data populated.
Any help would be greatly appreciated. I am a beginner please bear that in mind. Thanks
CREATE TABLE vod_actor (
dbActorId CHAR(4) NOT NULL,
dbFirstname VARCHAR2(50) NOT NULL,
dbLastname VARCHAR2(50) NOT NULL,
dbDateOfBirth DATE,
dbNationality VARCHAR2(30),
dbBiography CLOB,
CONSTRAINT vod_actor_PK PRIMARY KEY (dbActorId)
);
CREATE TABLE vod_classification (
dbClassId CHAR(4) NOT NULL,
dbDescription VARCHAR(250) NOT NULL,
CONSTRAINT vod_classification_PK PRIMARY KEY (dbClassId)
);
CREATE TABLE vod_film (
dbFilmId CHAR(4) NOT NULL,
dbTitle VARCHAR2(100) NOT NULL,
dbDirector_firstname VARCHAR2(50) NOT NULL,
dbDirector_lastname VARCHAR2(50) NOT NULL,
dbGenre VARCHAR2(20),
dbUK_release_date DATE,
dbFilename VARCHAR2(50),
dbRuntime NUMBER(4),
dbClass CHAR(3),
CONSTRAINT vod_film_PK PRIMARY KEY (dbFIlmId),
CONSTRAINT vod_film_class_FK FOREIGN KEY (dbClass) REFERENCES
vod_classification (dbClassId) ON DELETE SET NULL
);
CREATE TABLE vod_role (
dbFilmId Char(4) NOT NULL,
dbActorId CHAR(4) NOT NULL,
dbCharacterName VARCHAR2(25) NOT NULL,
dbFirstAppearance NUMBER(6),
dbDescription CLOB,
CONSTRAINT vod_role_PK PRIMARY KEY (dbFilmId, dbActorId, dbCharacterName),
CONSTRAINT vod_role_film_FK FOREIGN KEY (dbFilmId) REFERENCES vod_film (dbFilmId)
ON DELETE CASCADE,
CONSTRAINT vod_role_actor_FK FOREIGN KEY (dbActorId) REFERENCES vod_actor (dbActorId)
ON DELETE CASCADE
);
//Insert into vod_actor & vod_classification works fine
Executing code below gives the error:
INSERT INTO vod_film VALUES ('1', 'Toy Story 3', 'Lee', 'Unkrich', 'Comedy', '19-JUL-2010', 'ToyStory3.mpg', '103', 'U');
INSERT INTO vod_film VALUES ('2', 'Lord of the Rings: Fellowship of the ring', 'Peter', 'Jackson', 'Fantasy', '19-DEC-2001', 'Fellowship.mpg', '178', '12');
INSERT INTO vod_film VALUES ('3', 'Lord of the Rings: Two Towers', 'Peter', 'Jackson', 'Fantasy', '18-DEC-2002', 'TwoTowers.mpg', '179', '12');
INSERT INTO vod_film VALUES ('4', 'Lord of the Rings: Return of the King', 'Peter', 'Jackson', 'Fantasy', '17-DEC-2003', 'KingReturns.mpg', '201', '12');
INSERT INTO vod_film VALUES ('5', 'Face/Off', 'John', 'Woo', 'Action', '7-NOV-1997', 'FaceOff.mpg', '138', '18');
INSERT INTO vod_film VALUES ('6', 'The Nutty Professor', 'Tom', 'Shadyac', 'Comedy', '4-OCT-1996', 'NuttyProf.mpg', '95', '12');
So in this case different character lengths for the PK FK fields I think is the issue.
CREATE TABLE vod_classification (
dbClassId CHAR(4) NOT NULL,
....
CREATE TABLE vod_film (
...
dbClass CHAR(3),
Given constraint
CONSTRAINT vod_film_class_FK FOREIGN KEY (dbClass) REFERENCES
vod_classification (dbClassId)
Appear to be the issue. char(3) <> char(4) make them both the same. likely the 3 to 4.
If I remember right char pads spaces to the end so 'U ' will never equal 'U ' U w/ 2 spaces for 3 characters vs U with 3 spaces for 4 characters. One of the reasons I prefer varchar no padding of spaces. Why was char chosen here?

MySQL 5.6 Foreign Key Error Message

I am getting this error when I try to run this bit of code in SQLFiddle. It is using MySQL 5.6.
Cannot add or update a child row: a foreign key constraint fails (db_9_f9acae.order_items, CONSTRAINT order_items_ibfk_1 FOREIGN KEY (Donut_Order_ID) REFERENCES custorder (Donut_Order_ID))
My code looks like this:
CREATE TABLE Customer (
Customer_ID INTEGER PRIMARY KEY AUTO_INCREMENT,
CustFirstName VARCHAR(50) NOT NULL,
CustLastName VARCHAR(50) NOT NULL,
Address VARCHAR(50) NOT NULL,
AptNum VARCHAR(50),
City VARCHAR(50) NOT NULL,
State VARCHAR(13) NOT NULL,
Zip VARCHAR(15) NOT NULL,
HomePhn VARCHAR(20),
MobPhn VARCHAR(20),
OthPhn VARCHAR(20)
);
CREATE TABLE Donut (
Donut_ID INTEGER PRIMARY KEY,
Donut_Name VARCHAR(255) NOT NULL,
Donut_Description VARCHAR(255) NOT NULL,
Donut_Price FLOAT NOT NULL
);
CREATE TABLE CustOrder (
Donut_Order_ID INTEGER PRIMARY KEY,
Date DATE NOT NULL,
Notes VARCHAR(255) NOT NULL,
Customer_ID INTEGER,
FOREIGN KEY (Customer_ID) REFERENCES Customer (Customer_ID)
);
CREATE TABLE Order_Items (
Donut_Order_ID INTEGER NOT NULL,
Donut_ID INTEGER NOT NULL,
Qty INTEGER NOT NULL,
PRIMARY KEY (Donut_Order_ID, Donut_ID),
FOREIGN KEY (Donut_Order_ID) REFERENCES CustOrder (Donut_Order_ID),
FOREIGN KEY (Donut_ID) REFERENCES Donut (Donut_ID)
);
CREATE VIEW CustInfo AS
SELECT CONCAT(CustFirstName,' ', CustLastName) AS CustFullName,
Customer_ID,
Address,
AptNum,
City,
State,
Zip,
HomePhn,
MobPhn,
OthPhn
FROM Customer;
CREATE INDEX DonutIndex ON Donut (Donut_Name);
INSERT INTO Customer VALUES
(1, "John", "Glenn", 1, NULL, "Kennedy Space Center", "FL", "32899", "(321) 867-5000", NULL, NULL),
(2, "Theodore", "Von Karman", "4800 Oak Dr", "Jet Propulsion Laboratory", "Pasadena", "CA", "91109", "(818) 354-4321", NULL, NULL),
(3, "Margaret", "Hamilton", "555 Technology Square", "Charles Stark Draper Laboratory", "Cambridge", "MA", "02139", "(617) 258-1000", "(123)456-7890", NULL);
INSERT INTO Donut
VALUES
(1, 'Plain' , 'Plain Donut' , 1.50),
(2, 'Glazed' , 'Glazed Donut' , 1.75),
(3, 'Cinnamon' , 'Cinnamon Donut' , 1.75),
(4, 'Chocolate' , 'Chocolate Donut' , 1.75),
(5, 'Sprinkle' , 'Sprinkle Donut' , 1.75),
(6, 'Gluten-Free' , 'Gluten-Free Donut' , 2.00);
INSERT INTO Order_Items VALUES
(2 , 4 , 3),
(3, 2, 1);
INSERT INTO CustOrder VALUES
('1', '11-24-2017', NULL, '1'),
('2', '11-25-2017', NULL, '2');
This is my first time working with anything SQL related and have tried referring to the MySQL docs, but don't know what I'm doing wrong. The error does not appear until after the bottom 2 INSERT INTO statements are added. Any help would be greatly appreciated.
You are getting this error because you are trying to insert data set in table whose references are missing in referenced table for example in Order_Items you are trying to link custorder table with Donut_Order_ID 2 and 3 but it is empty
So first fill your custorder and then link with your table
INSERT INTO CustOrder VALUES
('1', '11-24-2017', NULL, '1'),
('2', '11-25-2017', NULL, '2');
INSERT INTO Order_Items VALUES
(2 , 4 , 3),
(3, 2, 1);
Also i see there is no reference present in CustOrder for Donut_Order_ID = 3 but in Order_Items data you have trying to link with this missing reference which will again give you error
demo

NEW TO SQL, INSERT INTO 'TABLE' Error

I'm new to SQL, there's an error in my syntax that I don't understand. Any help/suggestions?
I created a table called ACCOUNT
CREATE TABLE `ACCOUNT` (
`acc_ID` INT NOT NULL,
`acc_name` VARCHAR(45) NOT NULL,
`acc_manager` VARCHAR(45) NOT NULL,
`acc_balance` VARCHAR(45) NOT NULL,
`acc_transactionLimit` INT NOT NULL,
`acc_creditLimit` INT NOT NULL,
`OUTLET_out_ID` INT NOT NULL,
PRIMARY KEY (`acc_ID`),
INDEX `fk_ACCOUNT_OUTLET1_idx` (`OUTLET_out_ID` ASC),
CONSTRAINT `fk_ACCOUNT_OUTLET1`
FOREIGN KEY (`OUTLET_out_ID`)
REFERENCES `OUTLET` (`out_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
No problems so far. But when i try to insert records into the table i get the following error:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key
constraint fails (Database.ACCOUNT, CONSTRAINT fk_ACCOUNT_OUTLET1
FOREIGN KEY (OUTLET_out_ID) REFERENCES OUTLET (out_ID))
I checked back on my OUTLET reference table:
CREATE TABLE `OUTLET` (
`out_ID` INT NOT NULL,
`out_name` VARCHAR(45) NOT NULL,
`out_manager` VARCHAR(45) NOT NULL,
`out_address` VARCHAR(100) NOT NULL,
`out_phone` VARCHAR(15) NOT NULL,
`out_email` VARCHAR(45) NULL,
PRIMARY KEY (`out_ID`))
I didn't find any problems with it.
Yet when trying to insert:
INSERT INTO ACCOUNT(acc_ID, acc_name, acc_manager, acc_balance, acc_transactionLimit, acc_creditLimit) VALUES
( 01, 'White', 'Mr.Good', '352.00', 1000.00, 500.00),
( 02, 'Hopkins', 'Mr.Good', '403.00', 1000.00, 500.00),
( 03, 'Aumbry', 'Mr.Good', '240.00', 1000.00, 500.00),
( 04, 'Kaze', 'Mr.Good', '76.00', 1000.00, 500.00),
( 05, 'Ashley', 'Mr.Bad', '24.00', 1000.00, 500.00),
( 06, 'Zoara', 'Mr.Bad', '503.00', 1000.00, 500.00),
( 07, 'Shawn', 'Mr.Bad', '34.00', 1000.00, 500.00),
( 08, 'Obsie', 'Mr.Bad', '278.00', 1000.00, 500.00),
( 09, 'Ven', 'Mr.Mr.Bad', '345.00', 1000.00, 500.00),
( 10, 'Zhan', 'Mr.Mr.Bad', '491.00', 1000.00, 500.00);
I get the error stated above.
You need to insert data into the Outlet table that the OUTLET_out_ID references, as this is a NON-NULL column but is a foreign key but no key has yet been made, so you need to re-order your inserts accordingly.
You also can't skip this value because it's NON-NULL and your current inserts are failing as you're not giving it a valid Foreign Key reference.
Insert data into the source table of your foreign key constraints First and then the Account data second.
Additionally, the data inserted into the Outlet table needs to correspond to the values referenced in the Accounts table, as dictated by a foreign key.
Personally I think it's easier in these data insert situations to simply tinsert the data without FK constraints and add these conditions after the data has been inserted. Personally.
It would have been nice to see your OUTLET table script; but then there's something more obvious here: the field OUTLET_out_ID is set to NOT NULL and your INSERT script does not have value for that field.
So, either modify that field to OUTLET_out_ID INT NULL or include the values in your INSERT query.

MySql Workbench error 1452 cannot add or update a child row a foreign key constraint fails

Here is my table and I keep getting this error. Everything is good to go until I execute the code that I have put in bold at the bottom. Im really close to completing this table but ive tried everything to solve this error but it keeps coming up.
Please Help me
Thank You`
UPDATE
I took your guys suggestions and changed the inserted data now im getting an error 1136 which is column doesnt match value count for row 1 which is visit ID so its a datatype problem but ive tried everything and I cant figure it out IM SO CLOSE TO BEING DONE
PLEASE HELP!
Create Schema Visit;
create table roomtableS(
RoomID char (2) not null,
RoomNum char (2) not null,
Charge integer not null,
CONSTRAINT RoomTable_PK Primary Key(RoomID));
Insert into roomtableS values
('01','1A',125.00),
('02','1A',150.00),
('03','1A',100.00),
('04','1A',200.00),
('05','2B',150.00),
('06','2B',125.00),
('07','3C',200.00),
('08','3C',125.00),
('09','3C',100.00);
SELECT * FROM ROOMTABLES;
create table PATIENT(
PatientID char(5) not null,
PatientName Char(25) not null,
PatientEmail Char(30) null,
PatientPhoneNumber Char(10) null,
PatientAddress Char(100) null,
constraint PATIENT_PK Primary key(PatientID));
insert PATIENT values
('P1', 'Bruce Willis', 'bwillis#mail.org', '2022223333', '1111 Cosmic dr'),
('P2', 'Demi Moore', 'moore#email.net', '2021113333', '1112 Cosmic dr'),
('P3', 'Andre Agassi', 'agassi#mail.org', '2023333333', '1113 Cosmic dr'),
('P4', 'Jet Lee', 'jetlee#email.net', '2023334444', '1114 Chinatown ct'),
('P5', 'Jim Carey', 'carey#email.net', '2023335555', '1115 United dr'),
('P6', 'Bruce Lee', 'bruce#gmail.com', '2023336666', '1115 Chinatown ct');
select* From PATIENT;
Create table SERVICETable(
ServiceID Char (5) not null,
ServiceTreatment Char(25) not null,
ServiceCost numeric not null,
constraint SERVICE_PK Primary Key(ServiceID));
insert SERVICETable values
('S1','Sore throat', 10.00),
('S2', 'Fever', 15.00),
('S3', 'Headache', 10.00),
('S4', 'Blood pressusre', 20.00),
('S5', 'Yearly checkup', 30.00),
('S6', 'Common cold', 15.00);
select* from SERVICETable;
Create Table doctortable(
DocID char (5) NOT NULL,
DoctorFirstName char(15) Not NULL,
DoctorLastName char (15) Not Null,
DoctorPhone char (15) Not Null,
CONSTRAINT DoctorTable_PK Primary Key(DocID));
INSERT INTO doctortable values
('D1','Tim','Edward','555-123-4567'),
('D2','Andy','Smith','888-777-6666'),
('D3','John','Smith','222-321-7654');
Select * From doctortable;
Create Table visit(
VisitID char (2) not Null,
PatientID Char (5) not null,
DocID Char (5) not null,
ServiceID Char (5) not Null,
RoomID char (2) not Null,
Visit date not null,
CONSTRAINT VISIT_PK PRIMARY KEY (VisitID));
Alter table Visit
add foreign key (PatientID)
references Patient (PatientID);
Alter table Visit
add foreign key (DocID)
references doctortable (DocID);
Alter table Visit
add foreign key (ServiceID)
references ServiceTable (ServiceID);
Alter table Visit
add foreign key (RoomID)
references roomtableS (RoomID);
Insert into Visit (VisitID,RoomID,ServiceID,PatientID,Visit) values
**('1','P1','D1','S1','05','2014-01-03'),
('2','P2','D2','S2','01','2014-01-10'),
('3','P3','D1','S3','02','2014-01-10'),
('4','P4','D2','S4','07','2014-01-15'),
('5','P1','D3','S2','08','2014-01-10'),
('6','P5','D3','S5','03','2014-02-02'),
('7','P4','D1','S6','06','2014-01-10'),
('8','P3','D2','S5','03','2014-02-03'),
('9','P2','D3','S6','01','2014-02-04'),
('10','P3','D1','S2','06','2014-02-04'),
('11','P5','D2','S4','04','2014-02-05'),
('12','P4','D1','S5','09','2014-02-06');**
Select * from Visit;
Thank You!
Your insert query into Visit table is like this:
Insert Visit Values
('1','P1','D1','S1','2B','2014-01-03'),
Values are expected to be in the order of
(VisitID, RoomID, ServiceID, PatientID, DocID, Visit)
But they seem to be in a different order.
Change the insert statement to include column names.
Insert Visit
(VisitID, PatientID, DocID, ServiceID, RoomID, Visit)
Values
('1','P1','D1','S1','2B','2014-01-03'),
And the values, '2B' being inserted into 'RoomID' column seem to be 'RoomNum' values but not 'RoomID' values. Change it to '05', or '06'. Such change has to be done in all other inputs for the column.

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.