Problem with foreign keys in sql database - mysql

I have a school assignment that that is giving me and my friends headaches... So this is my queries that i have executed, one at a time ofc...
CREATE DATABASE GamblingSociety;
USE GamblingSociety;
CREATE TABLE GamblingDen
(
Name VARCHAR (20) PRIMARY KEY,
Address VARCHAR (50),
Phone VARCHAR (10)
);
CREATE TABLE Room (
RoomNr INT,
GameCapaity INT,
GamblingDenName VARCHAR (20),
PRIMARY KEY (RoomNr, GamblingDenName),
FOREIGN KEY (GamblingDenName) REFERENCES GamblingDen (Name)
);
CREATE TABLE Employee (
SSN CHAR (11) PRIMARY KEY,
Name VARCHAR (20),
Address VARCHAR(50),
Salary INT,
isBoss BOOL,
GamblingDenName VARCHAR (20),
FOREIGN KEY (GamblingDenName) REFERENCES GamblingDen (Name)
);
CREATE TABLE GameType (
Name VARCHAR (20) PRIMARY KEY,
WinningProcentage FLOAT,
ResponsibleEmployee CHAR (11),
FOREIGN KEY (ResponsibleEmployee) REFERENCES Employee (SSN)
);
CREATE TABLE Supplier (
Name VARCHAR (20) PRIMARY KEY,
Address VARCHAR (50)
);
CREATE TABLE SupplierOfGameType (
SupplierName VARCHAR (20),
GameTypeName VARCHAR (20),
PRIMARY KEY(SupplierName, GameTypeName),
FOREIGN KEY (SupplierName) REFERENCES Supplier (Name),
FOREIGN KEY (GameTypeName) REFERENCES GameType (Name)
);
CREATE TABLE GamblingTable (
TableNr INT,
RoomNr INT,
GamblingDenName VARCHAR (20),
GameTypeName VARCHAR (20),
Comments VARCHAR (128),
PRIMARY KEY (RoomNr, TableNr, GamblingDenName, GameTypeName),
FOREIGN KEY (RoomNr, GamblingDenName) REFERENCES Room (RoomNr, GamblingDenName),
FOREIGN KEY (GameTypeName) REFERENCES GameType (Name)
);
CREATE TABLE Shylock (
Phone CHAR (10) PRIMARY KEY,
Name VARCHAR (20),
Contry CHAR (3)
);
CREATE TABLE Customer (
SSN CHAR (11) PRIMARY KEY,
Name VARCHAR (20),
Phone CHAR (10),
Address VARCHAR (50)
);
But this last query does not work:
USE GamblingSociety;
CREATE TABLE GamblingInstance (
StartTime DATETIME,
EndingTime DATETIME,
GamblingDenName VARCHAR (20),
TableNr INT,
GameTypeName VARCHAR (20),
Customer CHAR (11),
Shylock CHAR (10),
Debt INT,
DebtPayed BOOL,
DebtPayedDate DATETIME,
PRIMARY KEY (StartTime, GameTypeName, Customer),
FOREIGN KEY (GamblingDenName, TableNr, GameTypeName) REFERENCES GamblingTable (GamblingDenName, TableNr, GameTypeName),
FOREIGN KEY (Customer) REFERENCES Customer (SSN),
FOREIGN KEY (Shylock) REFERENCES Shylock (Phone)
);
It gives me this error:
"Error Code: 1005. Can't create table 'gamblingsociety.gamblinginstance' (errno: 150)"
if I replace this:
FOREIGN KEY (GamblingDenName, TableNr, GameTypeName) REFERENCES GamblingTable (GamblingDenName, TableNr, GameTypeName),
with this:
FOREIGN KEY (GameTypeName) REFERENCES GamblingTable (GameTypeName),
It works, so it's something with the GamblingDenName and TableNr.
And i have google it and found a lot of tips, but nothing yeat have worked...
So anyone with any idea?
Thanks in advance!

There is no key in GamblingTable that can satisfy this REFERENCE:
REFERENCES GamblingTable (GamblingDenName, TableNr, GameTypeName),
That is, there is no key in GamblingTable for which GamblingDenName, TableNr, GameTypeName are the only columns, or the first three columns.
There is a key that satisfies REFERENCES GamblingTable (GameTypeName), which is why that version works.
(I have to say that I've never actually seen FOREIGN KEYs being used to parent other FOREIGN KEYs, but I guess it works).

Related

mySQL trying to create table with constraint foreign key

I have this simple code
create table transport (
CODE varchar (10),
TDATE date,
ID integer,
PNAME varchar (10),
primary key (CODE,TDATE,ID,PNAME) );
create table planes (
NAME varchar (10),
NSEATS integer,
FSEATS integer,
ECSEATS integer,
primary key (NAME),
CONSTRAINT foreign key(NAME) references transport(PNAME));
But it doesn't let me do the foreign key thing as it says errno: 150 "Foreign key constraint is incorrectly formed
Any tips appreciated
Thanks
The use of composite primary keys in this case is not reasonable. If you want a foreign key reference, you need to reference all columns in the primary key. So, this version is simpler:
create table transport (
transportId int not null auto_increment primary key,
CODE varchar (10),
TDATE date,
ID integer,
PNAME varchar (10),
unique (CODE, TDATE, ID, PNAME)
);
create table planes (
planeId int not null auto_increment primary key,
NAME varchar (10),
NSEATS integer,
FSEATS integer,
ECSEATS integer,
primary key (NAME),
transportId int,
CONSTRAINT foreign key(transportId) references transport(transportId)
);
Rule is that : A Foreign key in one table points to a Primary Key in another table.

SQL: A query that verify referential integrity across all tables

I have created my tables and populated it but I am not sure how to write a query to verify the referential integrity across all tables.
This is what I need:
SELECT lists all primary keys
FROM lists all tables
WHERE shows all relationships
This is what I have so far:
SELECT
categId, zipCode, suppId, acctId, prodId, orderId
From
CATEGORY, ZIP, SUPPLIER, ACCOUNT, SUPPLIER_REGION, PRODUCT, PROD_DETAIL, ORDERX, ORDER_LINE_ITEM
I am not sure what to put for WHERE.
My professor wants a command to verify the referential integrity. There are a lot of other stuff he wants but this is the only thing I am not sure how to do.
I added my tables.
create table CATEGORY (
categId varchar (8),
categIdParent varchar (8),
constraint CATEGORY_PK primary key (categId),
constraint CATEGORY_FK foreign key (categIdParent) references CATEGORY (categId)
);
create table ZIP(
zipCode int (5),
city varChar (16),
state varChar (16),
constraint ZIP_PK primary key (zipCode)
);
create table SUPPLIER (
supplId int (9),
supplName varChar (24),
supplStatus varChar (16),
supplYearEstabl date,
zipCode int (5),
constraint SUPPLIER_PK primary key (supplId),
constraint SUPPLIER_FK Foreign Key (zipCode) references ZIP (zipCode)
);
CREATE TABLE SUPPLIER_REGION (
supplId int (9),
region varChar (24),
constraint SUPPLIER_REGION_PK primary key (supplId, region),
constraint SUPPLIER_REGION_FK foreign key (supplId) references SUPPLIER (supplId)
);
create table PRODUCT (
prodId int (11),
prodDescr varChar (256),
prodType varChar (12),
prodModel Char (16),
prodPlaceOrigin Char (16),
prodPrice decimal (10,2),
prodMinQty int (8),
supplId int (9),
categId varchar (8),
constraint PRODUCT_PK primary key (prodId),
constraint PRODUCT_FK1 foreign key (supplId) references SUPPLIER (supplId),
constraint PRODUCT_FK2 foreign key (categId) references CATEGORY (categId)
);
create table PROD_DETAIL (
prodId int (11),
prodDetailNo int (8),
prodDetailName varChar (32),
prodDetailValue decimal (10,2),
constraint PROD_DETAIL_PK primary key (prodID, prodDetailNo),
constraint PROD_DETAIL_FK foreign key (prodID) references PRODUCT (prodID)
);
create table ACCOUNT (
acctId varchar(50),
acctName varChar (24),
acctDept varChar (16),
acctTitle varChar (16),
acctGender Char (1),
acctEmail varChar (24),
acctAddr varChar (24),
zipCode int (5),
acctPhone int (11),
constraint ACCOUNT_PK primary key (acctId),
constraint ACCOUNT_FK foreign key (zipCode) references ZIP (zipCode)
);
create table ORDERX (
orderId int (8),
orderPayMethod varChar (16),
orderShipDate date,
acctId varchar (50),
constraint ORDER_PK primary key (orderId),
constraint ORDER_FK foreign key (acctId) references ACCOUNT (acctId)
);
create table ORDER_LINE_ITEM (
orderId int (8),
orderLineNo int (8),
orderLineQty int (8),
orderLineUnit int (8),
orderLinePrice decimal (10,2),
prodId int (11),
constraint ORDER_LINE_ITEM_PK primary key (orderId, orderLineNo),
constraint ORDER_LINE_ITEM_FK1 foreign key (orderId) references ORDERX (orderId),
constraint ORDER_LINE_ITEM_FK2 foreign key (prodId) references PRODUCT (prodId)
);
For SQL Server one good way is to create a diagram in SSMS. As you place each table into the diagram the FK relationships will be rendered as lines between tables and primary keys will be displayed as "key" icons.

MySQL Workbench cannot add foreign key constraint

My SQL script works fine, till some point where error 1215 appears. I don't know what is wrong whith the code.
Here's the code:
CREATE DATABASE IF NOT EXISTS ΝΟΣΟΚΟΜΕΙΟ;
CREATE TABLE IF NOT EXISTS ΤΜΗΜΑΤΑ
(ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ INT,
ΟΝΟΜΑΣΙΑ_ΤΜΗΜΑΤΟΣ CHAR,
ΣΥΝΟΛΙΚΟΣ_ΑΡΙΘΜΟΣ_ΚΛΙΝΩΝ INT,
ΔΙΑΘΕΣΙΜΟΣ_ΑΡΙΘΜΟΣ_ΚΛΙΝΩΝ INT,
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ));
CREATE TABLE IF NOT EXISTS ΑΣΘΕΝΕΙΣ
(ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ INT,
ΟΝΟΜΑ_ΑΣΘΕΝΗ VARCHAR (20),
ΕΠΩΝΥΜΟ_ΑΣΘΕΝΗ VARCHAR (20),
ΦΥΛΛΟ VARCHAR (1),
ΗΜ_ΝΙΑ_ΓΕΝΝΗΣΗΣ DATE,
ΔΙΕΥΘΥΝΣΗ_ΑΣΘΕΝΗ CHAR ,
ΤΗΛΕΦΩΝΟ_ΑΣΘΕΝΗ VARCHAR (10),
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ));
CREATE TABLE IF NOT EXISTS ΙΑΤΡΟΙ
(ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ INT ,
ΟΝΟΜΑ_ΙΑΤΡΟΥ VARCHAR (20),
ΕΠΩΝΥΜΟ_ΙΑΤΡΟΥ VARCHAR (20),
ΕΙΔΙΚΟΤΗΤΑ CHAR,
ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ INT,
ΔΙΕΥΘΥΝΣΗ_ΙΑΤΡΟΥ CHAR,
ΤΗΛΕΦΩΝΟ_ΙΑΤΡΟΥ VARCHAR (10),
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ) REFERENCES ΤΜΗΜΑΤΑ(ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ)
);
CREATE TABLE IF NOT EXISTS ΠΕΡΙΣΤΑΤΙΚΑ
(ΚΩΔΙΚΟΣ_ΠΕΡΙΣΤΑΤΙΚΟΥ INT,
ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ INT,
ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ INT,
ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ INT,
ΗΜ_ΝΙΑ_ΕΙΣΑΓΩΓΗΣ DATE,
ΗΜ_ΝΙΑ_ΕΞΙΤΗΡΙΟΥ DATE,
ΑΞΙΑ_ΠΕΡΙΣΤΑΤΙΚΟΥ INT,
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΠΕΡΙΣΤΑΤΙΚΟΥ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ) REFERENCES ασθενεισ(ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ) REFERENCES τμηματα(ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ) REFERENCES ιατροι(ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ)
);
CREATE TABLE IF NOT EXISTS ΚΑΤΗΓΟΡΙΕΣ_ΠΡΟΪΟΝΤΩΝ
(ΚΩΔΙΚΟΣ_ΚΑΤΗΓΟΡΙΑΣ INT,
ΟΝΟΜΑΣΙΑ_ΚΑΤΗΓΟΡΙΑΣ CHAR,
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΚΑΤΗΓΟΡΙΑΣ)
);
CREATE TABLE IF NOT EXISTS ΠΡΟΪΟΝΤΑ
(ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ INT,
ΚΩΔΙΚΟΣ_ΚΑΤΗΓΟΡΙΑΣ INT,
ΟΝΟΜΑΣΙΑ_ΠΡΟΪΟΝΤΟΣ CHAR,
ΑΞΙΑ_ΜΟΝΑΔΑΣ_ΠΡΟΪΟΝΤΟΣ INT,
PRIMARY KEY (ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΚΑΤΗΓΟΡΙΑΣ) REFERENCES ΚΑΤΗΓΟΡΙΕΣ_ΠΡΟΪΟΝΤΩΝ(ΚΩΔΙΚΟΣ_ΚΑΤΗΓΟΡΙΑΣ)
);
CREATE TABLE IF NOT EXISTS ΧΡΕΩΣΕΙΣ_ΠΕΡΙΣΤΑΤΙΚΩΝ
(ΚΩΔΙΚΟΣ_ΠΕΡΙΣΤΑΤΙΚΟΥ INT,
ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ INT,
ΗΜΕΡΟΜΗΝΙΑ_ΧΡΕΩΣΗΣ DATE,
ΠΟΣΟΤΗΤΑ INT,
PRIMARY KEY (ΗΜΕΡΟΜΗΝΙΑ_ΧΡΕΩΣΗΣ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΠΕΡΙΣΤΑΤΙΚΟΥ) REFERENCES ΠΕΡΙΣΤΑΤΙΚΑ(ΚΩΔΙΚΟΣ_ΠΕΡΙΣΤΑΤΙΚΟΥ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ) REFERENCES ΠΡΟΙΟΝΤΑ(ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ)
);
...........................................
I have a problem with the last two tables where that error occurs.Is there anyone that could help me ?
Thanks, Dimitris
I tested this on Linux, MySQL 5.6.17. I was able to get this to work with two changes:
Match the case of table names to the way they are spelled when you create them:
CREATE TABLE IF NOT EXISTS ΠΕΡΙΣΤΑΤΙΚΑ
(
. . .
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ) REFERENCES ΑΣΘΕΝΕΙΣ(ΚΩΔΙΚΟΣ_ΑΣΘΕΝΗ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ) REFERENCES ΤΜΗΜΑΤΑ(ΚΩΔΙΚΟΣ_ΤΜΗΜΑΤΟΣ),
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ) REFERENCES ΙΑΤΡΟΙ(ΚΩΔΙΚΟΣ_ΙΑΤΡΟΥ)
);
Use the same spelling, including diacritics in ΠΡΟΪΟΝΤΑ:
CREATE TABLE IF NOT EXISTS ΧΡΕΩΣΕΙΣ_ΠΕΡΙΣΤΑΤΙΚΩΝ
(
. . .
FOREIGN KEY (ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ) REFERENCES ΠΡΟΪΟΝΤΑ(ΚΩΔΙΚΟΣ_ΠΡΟΪΟΝΤΟΣ)
);

MYSQL designing query issue

I am trying to create a query that shows the name and adress of all people who have incurred fines but do not have a driving license. (So do not show up in the driving license table) How would I go about including something who does not show up in a table?
Here are my tables
CREATE TABLE offences (
oOffenceID VARCHAR (30),
oDescription VARCHAR (200),
oMaximumFine INT (10),
CONSTRAINT o_pk
PRIMARY KEY (oOffenceID)
);
CREATE TABLE drivers (
dPersonID VARCHAR (30),
dLicenseNumber INT (20),
dLicenseRemoved ENUM('yes','no'),
dExpiryDate DATE,
CONSTRAINT d_pk
PRIMARY KEY (dLicenseNumber),
CONSTRAINT d_fk
FOREIGN KEY (dPersonId)
REFERENCES People (pPersonID)
);
CREATE TABLE people (
pPersonID VARCHAR (30),
pName VARCHAR (30),
pAddress VARCHAR (50),
pNIN VARCHAR (30),
CONSTRAINT p_pk
PRIMARY KEY (pPersonID)
);
CREATE TABLE vehicle (
vOwnerID VARCHAR (30),
vColour VARCHAR (30),
vModel VARCHAR (30),
vMake VARCHAR (30),
vVehicleID VARCHAR (30),
CONSTRAINT v_pk
PRIMARY KEY (vVehicleID),
CONSTRAINT v_fk
FOREIGN KEY (vOwnerID)
REFERENCES People (pPersonID)
);
CREATE TABLE fines (
fFineID INT (30) AUTO_INCREMENT,
fVehicleID VARCHAR (30),
fPersonID VARCHAR (30),
fTime DATE,
fAmount INT (10),
fOfficerStatement VARCHAR (500),
fOffenceID VARCHAR (30),
CONSTRAINT f_pk
PRIMARY KEY (fFineID),
CONSTRAINT f_fk
FOREIGN KEY (fVehicleID)
REFERENCES vehicle (vVehicleID),
CONSTRAINT f_fk1
FOREIGN KEY (fPersonID)
REFERENCES people (pPersonID),
CONSTRAINT f_fk2
FOREIGN KEY (fOffenceID)
REFERENCES offences (oOffenceID)
);
So far I have
SELECT DISTINCT pName, pAddress
FROM people, fines, drivers
WHERE
pPersonID <> dPersonID
AND
pPersonID = fPersonID
AND
fAmount > 0
but this doesn't remove all the necessary data.
Any help or guidance of the right tools to use would be much appreciated.
Use a LEFT JOIN and check for NULL values
example:
SELECT *
FROM
table_A
LEFT JOIN table_B
ON table_A.id = table_b.a_id
WHERE table_B.a_id IS NULL

Writing a query that shows the total amount of the fines accumulated for all cars which have accumulated more than 1000 of fines

I can't figure out how to write a query in SQL.
Here are my tables,
CREATE TABLE offences (
oOffenceID VARCHAR (30),
oDescription VARCHAR (200),
oMaximumFine INT (10),
CONSTRAINT o_pk
PRIMARY KEY (oOffenceID)
);
CREATE TABLE drivers (
dPersonID VARCHAR (30),
dLicenseNumber INT (20),
dLicenseRemoved ENUM('yes','no'),
dExpiryDate DATE,
CONSTRAINT d_pk
PRIMARY KEY (dLicenseNumber),
CONSTRAINT d_fk
FOREIGN KEY (dPersonId)
REFERENCES People (pPersonID)
);
CREATE TABLE people (
pPersonID VARCHAR (30),
pName VARCHAR (30),
pAddress VARCHAR (50),
pNIN VARCHAR (30),
CONSTRAINT p_pk
PRIMARY KEY (pPersonID)
);
CREATE TABLE vehicle (
vOwnerID VARCHAR (30),
vColour VARCHAR (30),
vModel VARCHAR (30),
vMake VARCHAR (30),
vVehicleID VARCHAR (30),
CONSTRAINT v_pk
PRIMARY KEY (vVehicleID),
CONSTRAINT v_fk
FOREIGN KEY (vOwnerID)
REFERENCES People (pPersonID)
);
CREATE TABLE fines (
fFineID INT (30) AUTO_INCREMENT,
fVehicleID VARCHAR (30),
fPersonID VARCHAR (30),
fTime DATE,
fAmount INT (10),
fOfficerStatement VARCHAR (500),
fOffenceID VARCHAR (30),
CONSTRAINT f_pk
PRIMARY KEY (fFineID),
CONSTRAINT f_fk
FOREIGN KEY (fVehicleID)
REFERENCES vehicle (vVehicleID),
CONSTRAINT f_fk1
FOREIGN KEY (fPersonID)
REFERENCES people (pPersonID),
CONSTRAINT f_fk2
FOREIGN KEY (fOffenceID)
REFERENCES offences (oOffenceID)
);
I need a query that shows the car VehicleID, the name of the Owner and the total amount of the fines accumulated for all cars which have accumulated more than 1000 of fines. Can anyone see how to do it?
Hopefully this will get you going in the right direction:
select fVehicleId,p.pName,sum(fi.totalFines) as totalFinesOver1000ForPerson
from
(select fVehicleId,sum(fAmount) as totalFines
from fines f
group by fVehicleId
having sum(fAmount) > 1000) fi
inner join vehicle v on v.vVehicleID = fi.fVehicleId
inner join people p on v.vOwnerId = p.pPersonId
group by fVehicleId,p.pName;
Select a.vVehicleID,
b.pName,
sum(d.fAmount) fine
from vehicle a,people b,fines d,drivers e
where a.vVehicleID=d.vVehicleID and d.fPersonID=e.dPersonID and d.fPersonID=a.vOwnerID and
b.pPersonID = e.dPersonID
group by a.vVehicleID,b.pNamem
having fine > 1000;
This should work