How to impelment a foriegn key in sql? - sql

I tried writing it like that but i keep getting errors but when i removed the line it worked how do i set a foreign key in this?
PlayerNum int,
PlayerName varchar(255),
PlayerPosition varchar(255),
NumOfRedCards int,
NumOfYellowCards int,
Goals int,
Fouls int,
PRIMARY KEY (PlayerNum),
/*FOREIGN KEY (TeamName) REFERENCES Teams(TeamName)*/
);```

You don't have a column defined for TeamName in your table. Try this:
PlayerNum int,
PlayerName varchar(255),
PlayerPosition varchar(255),
NumOfRedCards int,
NumOfYellowCards int,
Goals int,
Fouls int,
TeamName varchar(255),
PRIMARY KEY (PlayerNum),
FOREIGN KEY (TeamName) REFERENCES Teams(TeamName)
);```
That should work, assuming that you have a Teams table with a defined primary key of TeamName.
NOTE: I would highly recommend NOT having a varchar for a primary key. A far better implementation would be:
PlayerNum int,
PlayerName varchar(255),
PlayerPosition varchar(255),
NumOfRedCards int,
NumOfYellowCards int,
Goals int,
Fouls int,
TeamId int,
PRIMARY KEY (PlayerNum),
FOREIGN KEY (TeamId) REFERENCES Teams(TeamId)
);```
You can always join tables on the ID to get the team name, or at worst write a view for a flattened structure to query against.
SELECT p.PlayerNum, p.PlayerName, ..., t.TeamName FROM Players p
LEFT JOIN Teams t ON p.TeamId = t.TeamId
WHERE p.PlayerId = 1

Related

Sql Fiddle errors

I am trying to create SQL statements for an assignment in SQL Fiddle and I keep getting the error "Cannot add foreign key constraint". I have tried various things but I recieve different errors when I change things. What am I doing wrong?
CREATE TABLE Person (
ID int NOT NULL,
FName varchar(255),
LName varchar(255),
Preferred_Name varchar(255),
PRIMARY KEY (ID)
)
;
CREATE TABLE Song (
ID varchar(255) NOT NULL,
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Album (
Title varchar(255) NOT NULL,
Run_Time int,
Release_Year TIMESTAMP,
PRIMARY KEY (Title)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255),
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int,
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;
In the Song and Has tables you defined Song.ID and Has.Song_Title as a varchar(255). In the Part_Of table you defined SongID as an int. This is why the foreign key is failing. Use the same datatype in all tables (INT seems like a good option) to fix this.
CREATE TABLE Song (
ID varchar(255) NOT NULL, <------
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255), <-----
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int, <-----
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;

Error Code 1005. Can't create table : "takes" and "Teaches"

Would appreciate help. Can not create the "Teaches" and "takes" table.
CREATE DATABASE university;
use university;
CREATE TABLE classroom(
building VARCHAR(20),
room_number INT,
capacity INT,
PRIMARY KEY (building,room_number)
) ;
CREATE TABLE Sales(
item VARCHAR(20),
color VARCHAR(20),
clothes_size VARCHAR(20),
quantity INT,
PRIMARY KEY (item,color,clothes_size,quantity)
);
CREATE TABLE Department (
dept_name VARCHAR(20),
building VARCHAR(20),
budget INT,
FOREIGN KEY (building) references classroom(building),
PRIMARY KEY (dept_name,building,budget)
);
CREATE TABLE Course (
course_id VARCHAR(20)PRIMARY KEY,
title VARCHAR(20),
dept_name VARCHAR(20),
credits INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
CREATE TABLE Instructor(
ID VARCHAR(20) PRIMARY KEY,
neme VARCHAR(20),
dept_name VARCHAR(20),
salary INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
CREATE TABLE section(
course_id VARCHAR(20),
sec_id INT,
semester VARCHAR(20),
year1 INT,
building1 VARCHAR(20),
room_number INT,
time_slot_id CHAR,
FOREIGN KEY (course_id) REFERENCES Course(course_id),
FOREIGN KEY (building1,room_number) references classroom(building,room_number),
PRIMARY KEY(course_id,sec_id,semester,year1)
);
CREATE TABLE Teaches(
ID VARCHAR(20),
course_id VARCHAR(20),
sec_id VARCHAR(20),
semester VARCHAR(20),
year1 INT,
FOREIGN KEY (ID) references Instructor(ID),
FOREIGN KEY (sec_id) references section(sec_id),
FOREIGN KEY (semester,year1) references section(semester,year1),
FOREIGN KEY (course_id) references course(course_id),
PRIMARY KEY (ID,course_id,sec_id,year1,semester)
);
CREATE TABLE student(
ID VARCHAR(20) PRIMARY KEY,
name1 VARCHAR(20),
dept_name VARCHAR(20),
tot_cred INT);
CREATE TABLE Takes(
ID VARCHAR(20),
course_id VARCHAR(20),
sec_id INT,
semester VARCHAR(20),
year1 INT,
grade char,
FOREIGN KEY (ID) references student(ID),
FOREIGN KEY (sec_id) references section(sec_id),
FOREIGN KEY (semester) references section(semester),
FOREIGN KEY (year1) references section(year1),
FOREIGN KEY (course_id) references course(course_id),
PRIMARY KEY(ID,sec_id,semester,year1,course_id)
);
Foreign key references need to have the same types as the primary keys they refer to. So consider:
CREATE TABLE Department (
dept_name VARCHAR(20),
building VARCHAR(20),
budget INT,
FOREIGN KEY (building) references classroom(building),
PRIMARY KEY (dept_name,building,budget)
);
CREATE TABLE Instructor (
ID VARCHAR(20) PRIMARY KEY,
neme VARCHAR(20),
dept_name VARCHAR(20),
salary INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
The primary key for Department has three components -- dept_name, building, budget. However, the reference has only one component. They cannot match; the number is not correct, much less the types.
I would recommend that you use auto-incremented ids for your primary keys. You can also specify uniqueness constraints, if you like. So for this small example:
create table buildings (
building_id int auto_increment primary key,
building varchar(20),
constraint unq_buildings_building unique(building)
);
create table classrooms (
classroom_id int auto_increment primary key,
building_id int,
room_number int,
capacity int,
constraint fk_classrooms_building_id foreign key (building_id) references buildings (building_id)
) ;
create table Departments (
department_id int auto_increment primary key,
dept_name varchar(20),
building_id int,
budget INT,
constraint fk_departments_building_id foreign key (building_id) references buildings(building_id)
);
create table instructors (
instructor_id int auto_increment primary key,
id varchar(20) unique,
name varchar(20),
department_id int,
salary int,
foreign key instructors_department_id foreign key (department_id) references departments (department_id)
);
This is just a small sample of your tables. But the following are some rules that I follow:
Table names are plural.
They have a primary key which is the singular form followed by _id (or Id).
Foreign key references are only to primary keys.
To the extent possible, foreign keys and primary keys have the exact same name.
Explicit constraints are given names. The names follow a very precise naming convention.
I also added a buildings table. It is referenced in at least two places, so it seems worthy of being its own entity.
This should give you some ideas on how to build your database.

SQL Query that displays the number of athletes that have competed in at least ten different places(locations)

I'm building a query based on the fact that they have competed in ten or more places. Note that it does not matter how many sports or competitions they competed in, just how many places they have competed in.
CREATE TABLE Gender (
gender CHAR(1),
description VARCHAR(10),
PRIMARY KEY (gender));
CREATE TABLE People (
ID INT,
name VARCHAR(50),
gender CHAR(1),
height FLOAT,
PRIMARY KEY (ID),
FOREIGN KEY (gender) REFERENCES Gender (gender));
CREATE TABLE Sports (
ID INT,
name VARCHAR(50),
record FLOAT,
PRIMARY KEY (ID),
UNIQUE (name));
CREATE TABLE Competitions (
ID INT,
place VARCHAR(50),
held DATE,
PRIMARY KEY (ID));
CREATE TABLE Results (
peopleID INT NOT NULL,
competitionID INT NOT NULL,
sportID INT NOT NULL,
result FLOAT,
PRIMARY KEY (peopleID, competitionID, sportID),
FOREIGN KEY (peopleID) REFERENCES People (ID),
FOREIGN KEY (competitionID) REFERENCES Competitions (ID),
FOREIGN KEY (sportID) REFERENCES Sports (ID));
If anyone can help me with this it would be much appreciated!
As commented by Brad, you can use a simple aggregated query that JOINs table People with Results, with a HAVING BY clause to filter on the number of competitions each person participated to. It seems like you don’t need to bring in any other table to achieve your goal.
SELECT
p.ID,
p.Name
FROM
People p
Results r ON r.peopleID = p.ID
GROUP BY
p.ID,
p.Name
HAVING COUNT(*) >= 10

SQL Can't create Foreign key

I'm sure my question would be kinda silly, but I can't solve it. Here is my issue:
create table Product
(
ProductID int PRIMARY KEY,
ProductName varchar(16),
RetrailPrice int,
WholesalePrice int,
MonthDelivery int,
Waste int,
StorageName varchar(16)
)
create table Storage
(
StorageID int PRIMARY KEY,
StorageName varchar(16),
City varchar(16),
Employees int,
Area int,
ProductID int
)
And of course I want to link them
alter table Product
add FOREIGN KEY (StorageName) references Storage(StorageName)
But I can't do it, I'm wrong somewhere :/
You have to reference the PK from the Storage table. StorageName is a poor choice for a FK. What if there are Storages with the same name in different cities?
Replace the StorageName in the Product table with StorageID
create table Product(
ProductID int PRIMARY KEY,
ProductName varchar(16),
RetrailPrice int,
WholesalePrice int,
MonthDelivery int,
Waste int,
StorageID int) --this has chnaged, it will hold the id/PK of the Storage
create table Storage(
StorageID int PRIMARY KEY,
StorageName varchar(16),
City varchar(16),
Employees int,
Area int,
ProductID int)
And then:
alter table Product
add FOREIGN KEY (StorageID) references Storage(StorageID)

Sql query join and aggragation at the same time

How can I Select the Sum of the ProjectPossibilityRatio column from the ProjectCompletion table given the ProjectID? I couldnt find sum:
SELECT pp.ProjectID,
pp.ProjectAlias,
Sum(pd.projectpossibilityratio)
FROM project pp
INNER JOIN projectcompletion pc
ON pp.projectId = pc.projectID
JOIN projectprocedure pd
ON pd.projectprocedureID = pc.projectprocedureID
GROUP BY pd.projectpossibilityratio
Here are the table definitions:
Create TABLE ProjectType(
ProjectTypeID int identity(1,1),
ProjectTypeName nvarchar(100),
Description nvarchar(200),
primary key(ProjectTypeID)
)
CREATE TABLE Project(
ProjectID int identity(1,1),
ProjectAlias nvarchar(100),
ProjectTypeID int foreign key references ProjectType(ProjectTypeID),
MandatedCompanyID int foreign key references Company(CompanyID),
Iscurrent bit,
BuySide bit,
TeamID int foreign key references WorkTeam(TeamID),
ProjectTurnOver varchar(100),
ProjectStartDate Datetime
primary key(ProjectID))
CREATE TABLE ProjectProcedure(
ProjectProcedureID int identity(1,1),
ProjectProcedureName nvarchar(100),
ProjectProcedureDescription nvarchar(200),
ProjectType int foreign key references ProjectType(ProjectTypeID),
ProjectProcedurePosition int,
ProjectProcedureTime smallint,
ProjectPossibilityRatio int,
Primary Key(ProjectProcedureID))
CREATE TABLE ProjectCompletion(
ProjectID int foreign key references Project(ProjectID),
ProjectProcedureID int foreign key references ProjectProcedure(ProjectProcedureID),
StartDate Datetime,
IsCompletedDate Datetime
Primary Key(ProjectID,ProjectProcedureID)
)
Add all the column names that you are selecting to the group by list.
Try this:
SELECT pp.ProjectID,pp.ProjectAlias,Sum(pd.projectpossibilityratio)
FROM project pp INNER JOIN projectcompletion pc ON pp.projectId=pc.projectID
JOIN projectprocedure pd ON pd.projectprocedureID=pc.projectprocedureID
GROUP BY pp.ProjectID,pp.ProjectAlias
And I agree with LeftyX, you should go back and accept answers