SQL server 2017 ON DELETE CASCADE question - sql

Below is the code for the entire script. the only issue i have is with the FK below (see lines with -- in front) to remove it. if I add that I get an error using a DELETE, if I only apply the 4 constraints instead of 5 I can delete from the Artist table and it deletes from the other 3 as it should. but when I add PersonalInfo with an ON DELETE CASCADE suddenly I get an error, why? I plan to remove AlbumID from all tables so that they all rely on ArtistID to be identified. Allowing me to use the same column for FK as PK.
CREATE TABLE Artists
( ArtistName varchar(20) NOT NULL, ArtistID varchar(20) NOT NULL, NumberOfAlbumTitles varchar(10) NOT NULL, AlbumID varchar(20) NOT NULL,
PRIMARY KEY (ArtistID))
GO
CREATE TABLE Sales
( AlbumID varchar(20) NOT NULL, CopiesSoldYTD varchar(20) NOT NULL, ArtistID varchar(20) NOT NULL, SalesTotal varchar(20) NOT NULL,
PRIMARY KEY (AlbumID))
GO
CREATE TABLE Production
( AlbumID varchar(20), Copies varchar(20) NOT NULL, UnitPrice varchar(10) NOT NULL, AlbumTitle varchar(20) NOT NULL, ArtistID varchar(20) NOT NULL,
PRIMARY KEY (ArtistID))
GO
CREATE TABLE PersonalInfo
( FirstName varchar(20) NOT NULL, LastName varchar(30) NOT NULL, HomeAddress varchar(30) NOT NULL, PhoneNumber varchar(10) NOT NULL, ArtistID varchar(20) NOT NULL,
PRIMARY KEY (ArtistID))
GO
CREATE TABLE PersonalInfo2
( City varchar(20) NOT NULL, LabelName varchar(20), PostalZip varchar(6) NOT NULL, Region varchar(30) NOT NULL, ArtistID varchar(20) NOT NULL,
PRIMARY KEY (ArtistID))
GO
INSERT INTO Artists
VALUES ('Mr Roberts', 1, 4, 10),
('MC Boogie', 2, 3, 11),
('Singin Sam', 3, 1, 12),
('Avenger', 4, 2, 13)
GO
INSERT INTO Sales
VALUES (10, 232 , 1, 2320),
(11, 151, 2, 1510),
(12, 129, 3, 1290),
(13, 487, 4, 4870)
GO
INSERT INTO Production
VALUES (10 , 500 , 10, 'Roberts 1', 1),
(11, 700, 10, 'Time To Boogie', 2),
(12, 250, 10, ' Dance Dance Dance', 3),
(13, 1000, 10, 'The Revenge Of...', 4)
GO
INSERT INTO PersonalInfo
VALUES ('Brad', 'Roberts' , ' 126 Somewhere Lane', 2048888888, 1),
('Doug', 'Boogie', '234 East bay', 9078789090, 2),
('Raymond', 'Disco', ' 123 Dancing Queen Blvd', 3038761234, 3),
('Ryan', 'Apple', '66 Berkshire Bay', 4549091212, 4)
GO
INSERT INTO PersonalInfo2
VALUES ('Winnipeg', 'Ready Records', 'R2E9N8', 1, 1),
('Calgary','Set Records', 'R3J1M7', 2, 2),
('Texas', 'Go Records', '56555', 5, 3),
('London', 'Canadian Recordings','98887', 4, 4)
GO
ALTER TABLE Sales
ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
ON DELETE CASCADE
GO
--ALTER TABLE PersonalInfo
--ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
--GO
ALTER TABLE PersonalInfo2
ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
ON DELETE CASCADE
GO
ALTER TABLE Sales
ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
GO
ALTER TABLE Production
ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
ON DELETE CASCADE
GO
UPDATE Artists
SET ArtistName = 'Mr. Roberts'
WHERE ArtistID = 1
GO
UPDATE Production
SET Copies = 589, UnitPrice = 12
WHERE AlbumID = 10
GO
UPDATE PersonalInfo
SET HomeAddress = '345 Pritchard Rd', PhoneNumber = 2042341234
WHERE ArtistID = 1
GO
CREATE INDEX index1
ON dbo.Artists (ArtistID, AlbumID);
GO
CREATE INDEX index3
ON Sales (AlbumID, ArtistID);
GO
CREATE INDEX index4
ON Production (AlbumID, ArtistID);
GO
CREATE INDEX index5
ON PersonalInfo2 (City, ArtistID);
GO
CREATE INDEX index6
ON PersonalInfo (ArtistID);
GO
CREATE INDEX index7
ON Artists (ArtistName, NumberOfAlbumTitles);
GO
CREATE INDEX index8
ON Production (ArtistID, AlbumID, Copies, UnitPrice);
GO
CREATE INDEX index9
ON Artists (AlbumID);
GO
CREATE INDEX index11
ON Sales (ArtistID);
GO
CREATE INDEX index12
ON Production (ArtistID)
GO
CREATE INDEX index13
ON PersonalInfo2 (ArtistID);
GO
CREATE VIEW view1 AS
SELECT FirstName, LastName, ArtistName, PhoneNumber, CopiesSoldYTD, SalesTotal
FROM PersonalInfo
INNER JOIN Sales
ON PersonalInfo.ArtistID = Sales.ArtistID
INNER JOIN Artists
ON Sales.ArtistID = Artists.ArtistID
GO
CREATE PROCEDURE Proc1
AS
SELECT FirstName, LastName, Artists.ArtistName, NumberOfAlbumTitles, Artists.ArtistID, LabelName, PhoneNumber, City, UnitPrice, CopiesSoldYTD, SalesTotal
FROM Artists
LEFT JOIN PersonalInfo
ON Artists.ArtistID = PersonalInfo.ArtistID
LEFT JOIN PersonalInfo2
ON PersonalInfo.ArtistID = PersonalInfo2.ArtistID
INNER JOIN Production
ON PersonalInfo2.ArtistID = Production.ArtistID
INNER JOIN Sales
ON Production.ArtistID = Sales.ArtistID
GO
CREATE PROCEDURE dbo.FinalProjectErrorHandling2
AS
BEGIN TRY
SELECT CopiesSoldYTD, SalesTotal
FROM Sales
GROUP BY SalesTotal, CopiesSoldYTD
HAVING CopiesSoldYTD > 200
END TRY
BEGIN CATCH
WHILE(ERROR_NUMBER() > 0 )
RAISERROR ('the error was handled',0,1) WITH NOWAIT
SELECT
ERROR_MESSAGE() AS ErrorMessage
END CATCH
GO

Because you are missing "ON DELETE CASCADE" here
--ALTER TABLE PersonalInfo
--ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID) <---- Missing on delete cascade
--GO
Once you add that
ALTER TABLE PersonalInfo
ADD FOREIGN KEY (ArtistID) REFERENCES Artists(ArtistID)
ON DELETE CASCADE
GO
it works as required

Related

I am receiving 'FOREIGN KEY constraint failed' errors but cannot find the source

I have these four tables that represent a hardware store:
PRAGMA foreign_keys = 1;
DROP TABLE IF EXISTS transactions;
DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS tools;
DROP TABLE IF EXISTS departments;
CREATE TABLE departments (
name PRIMARY KEY NOT NULL
);
CREATE TABLE tools (
id INTEGER PRIMARY KEY AUTOINCREMENT,
tool_name TEXT NOT NULL UNIQUE,
tool_price DECIMAL(5, 2),
tool_department VARCHAR(250),
FOREIGN KEY (tool_department) REFERENCES departments(name) ON DELETE CASCADE
);
CREATE TABLE customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name TEXT NOT NULL UNIQUE,
last_name TEXT NOT NULL UNIQUE,
phone_number INTEGER UNIQUE NOT NULL
);
CREATE TABLE transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER,
customer_first_name TEXT NOT NULL,
customer_last_name TEXT NOT NULL,
customer_phone_number INTEGER NOT NULL,
tool_purchased TEXT NOT NULL,
item_quantity INTEGER NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE,
FOREIGN KEY (tool_purchased) REFERENCES tools(tool_name) ON DELETE CASCADE,
FOREIGN KEY (customer_first_name) REFERENCES customers(first_name) ON DELETE CASCADE,
FOREIGN KEY (customer_last_name) REFERENCES customers(last_name) ON DELETE CASCADE,
FOREIGN KEY (customer_phone_number) REFERENCES customers(phone_number) ON DELETE CASCADE
);
I am trying to insert this data into my tables:
INSERT INTO tools(tool_name, tool_price, tool_department)
VALUES
('Snow shovel', 16.50, 'Home & Garden'),
('Work light', 29.99, 'Electrical'),
('Wheelbarrow', 89.99, 'Home & Garden'),
('Pipe Wrench', 18.99, 'Plumbing'),
('Pipe Cutter', 36.36, 'Plumbing'),
('Rake', 15.45, 'Home & Garden');
INSERT INTO customers(first_name, last_name, phone_number)
VALUES
('John', 'Smith', 1111111111),
('Jane', 'Doe', 2222222222);
INSERT INTO transactions(customer_id, customer_first_name, customer_last_name, customer_phone_number, tool_purchased, item_quantity)
VALUES
(1, 'John', 'Smith', 1111111111, 'Work light', 1),
(1, 'John', 'Smith', 1111111111, 'Pipe Cutter', 2),
(2, 'Jane', 'Doe', 2222222222, 'Snow shovel', 3),
(2, 'Jane', 'Doe', 2222222222, 'Work light', 1),
(2, 'Jane', 'Doe', 2222222222, 'Pipe Wrench', 1),
(2, 'Jane', 'Doe', 2222222222, 'Pipe Cutter', 1),
(1, 'John', 'Smith', 1111111111, 'Wheelbarrow', 3);
However, I am getting these errors back:
Error: near line 1: FOREIGN KEY constraint failed
Error: near line 15: FOREIGN KEY constraint failed
You haven't defined the type of column name in table departments! Must be VARCHAR(250) like in table tools (FK).
CREATE TABLE departments (
name VARCHAR(250) PRIMARY KEY NOT NULL
);
Correct departments table and insert department in it in order to reference tools to this dept. You cannot reference a tool to department that does not exist yet. Also read docs about column types TEXT and VARCHAR.

Movie booking: How to let every show have its own set of seats?

I have made a movie booking database in mysql workbench (6.2). This database is then connected to eclipse where I in java have programmed a GUI for the movie booking system.
Everything works well with the GUI/database but there is one logical problem:
If a reservation is made for a show, naturally, the number of seats left in that theater where that show is to be played, will be reduced by 1 for every reservation. But if there is a show that's on a different date but on the same theater then this theaters seats is also reduced by 1 which is wrong.
E.g. a show on Monday should have its own set of seats and one on Tuesday should have its own. A solution could be to create a new column 'nbrseats' in 'shows' but I want it to get its seats from Theaters if that's possible.
Database
set foreign_key_checks = 0;
drop table if exists Users;
drop table if exists Theaters;
drop table if exists Movies;
drop table if exists reservations;
drop table if exists Shows;
create table Theaters (
theatername char(11) not null,
NbrSeats char(20) not null,
primary key (theatername)
)engine innoDB;
create table Movies (
moviename char(30) not null,
primary key (moviename)
)engine innoDB;
create table Shows (
movieDate DATE not null,
theatername char(11) not null,
moviename char(30) not null,
id integer auto_increment,
foreign key (theatername) references Theaters(theatername),
foreign key (moviename) references Movies(moviename),
primary key (id)
)engine innoDB;
create table Users (
username char(20) not null,
fullname char(30) not null,
phonenbr char(10) not null,
address varchar(20) not null,
primary key (username)
) engine innoDB;
create table reservations (
resNbr integer auto_increment,
username char(20) not null,
showId int(30) not null,
foreign key(showid) references Shows(id),
foreign key (username) references Users(username),
primary key (resNbr)
)engine innoDB;
-- insert data into the tables
insert into Users values
('Temp1','Name Name', '0701231231', 'Street1');
insert into Movies values
('Star Wars'),
('Dallas'),
('Falcon Crest');
insert into Theaters values
('Filmstaden', '100'),
('SF', '129'),
('Royal', '120');
insert into Shows values
('20151203','Royal', 'Falcon Crest', null),
('20151003','SF', 'Dallas', null),
('20150803','Filmstaden', 'Star Wars', null);
Thanks!
Just make a new column to store the number of booked seats in the reservations table. Then you can write a query to calculate the number of free seats based on the reservations made and the seats available in this theater.
Example to get free seats of showid 1, with two reservations of 5 and 2 seats:
set foreign_key_checks = 0;
drop table if exists Users;
drop table if exists Theaters;
drop table if exists Movies;
drop table if exists reservations;
drop table if exists Shows;
create table Theaters (
theatername char(11) not null,
NbrSeats char(20) not null,
primary key (theatername)
)engine innoDB;
create table Movies (
moviename char(30) not null,
primary key (moviename)
)engine innoDB;
create table Shows (
movieDate DATE not null,
theatername char(11) not null,
moviename char(30) not null,
id integer auto_increment,
foreign key (theatername) references Theaters(theatername),
foreign key (moviename) references Movies(moviename),
primary key (id)
)engine innoDB;
create table Users (
username char(20) not null,
fullname char(30) not null,
phonenbr char(10) not null,
address varchar(20) not null,
primary key (username)
) engine innoDB;
create table reservations (
resNbr integer auto_increment,
username char(20) not null,
showId int(30) not null,
seats int not null,
foreign key(showid) references Shows(id),
foreign key (username) references Users(username),
primary key (resNbr)
)engine innoDB;
-- insert data into the tables
insert into Users values
('Temp1','Name Name', '0701231231', 'Street1');
insert into Movies values
('Star Wars'),
('Dallas'),
('Falcon Crest');
insert into Theaters values
('Filmstaden', '100'),
('SF', '129'),
('Royal', '120');
insert into Shows values
('20151203','Royal', 'Falcon Crest', null),
('20151003','SF', 'Dallas', null),
('20150803','Filmstaden', 'Star Wars', null);
insert into reservations values
(null,'Temp1', 1, 5),
(null,'Temp1', 1, 2),
(null,'Temp1', 2, 3);
select
Shows.id,
Shows.theatername,
Theaters.NbrSeats,
sum(reservations.seats),
Theaters.NbrSeats-sum(reservations.seats) freeseats
from Shows
left join Theaters
on Shows.theatername = Theaters.theatername
left join reservations
on Shows.id = reservations.showId
where Shows.id = 1
group by
Shows.id,
Shows.theatername,
Theaters.NbrSeats
Database is correct, it was a matter of querying
here is an (somewhat primitive) example query for id = 2:
select nbrseats - (select count(showId) from reservations
where showId = (select id from shows where id = 2)) from theaters
where theatername = (select theatername from shows where id = 2);

Create view oracle sql

I am making a database with tv-shows and users.
These users can follow each other and are saved in the database by an UserID.
Now I wan't to create a view with the names of the users instead of the UserID's.
--Drop all tables.
DROP TABLE Series CASCADE CONSTRAINTS;
DROP TABLE User1 CASCADE CONSTRAINTS;
DROP TABLE FollowingSeries CASCADE CONSTRAINTS;
DROP TABLE FollowingUser CASCADE CONSTRAINTS;
DROP TABLE Episode CASCADE CONSTRAINTS;
DROP TABLE Watched CASCADE CONSTRAINTS;
DROP VIEW Test CASCADE CONSTRAINTS;
--Create all tables.
CREATE TABLE Series
( SeriesID NUMBER(5) primary key,
Name VARCHAR2(100) NOT NULL,
Status VARCHAR2(20),
Premiered DATE,
Genre VARCHAR2(100),
Country VARCHAR2(100),
Network VARCHAR2(100),
Runtime VARCHAR2(25)
);
CREATE TABLE User1(
UserID NUMBER(5) primary key,
Username VARCHAR2(100) NOT NULL,
Country varchar2(100),
Gender VARCHAR2(10),
Birthday VARCHAR2(100),
About_me VARCHAR2(300),
Password VARCHAR2(100) NOT NULL
);
CREATE TABLE FollowingSeries (
UserID NUMBER(5) NOT NULL,
SeriesID NUMBER(5) NOT NULL,
Ignore1 CHAR(1) DEFAULT 0,
constraint FollowingS_pk primary key(UserID, SeriesID),
constraint FollowingS_fk1 foreign key(UserID) REFERENCES User1(UserID),
constraint FollowingS_fk2 foreign key(SeriesID) REFERENCES Series(SeriesID)
);
CREATE TABLE FollowingUser (
UserID1 NUMBER(5) NOT NULL,
UserID2 NUMBER(5) NOT NULL,
constraint FollowingU_pk primary key(UserID1, UserID2),
constraint FollowingU_fk1 foreign key(UserID1) REFERENCES User1(UserID) ON DELETE SET NULL,
constraint FollowingU_fk2 foreign key(UserID2) REFERENCES User1(UserID) ON DELETE SET NULL
);
CREATE TABLE Episode(
SeriesID NUMBER(5) NOT NULL,
Season NUMBER(2) NOT NULL,
Episode NUMBER(2) NOT NULL,
Name varchar2(100) NOT NULL,
Airdate DATE,
Summary varchar2(1500),
constraint episode_pk primary key(SeriesID, Season, Episode),
constraint episode_fk foreign key(SeriesID) REFERENCES Series(SeriesID) ON DELETE SET NULL
);
CREATE TABLE Watched(
UserID NUMBER(5) NOT NULL,
SeriesID NUMBER(5) NOT NULL,
Season NUMBER(2) NOT NULL,
Episode NUMBER(2) NOT NULL,
constraint watched_pk primary key(UserID, SeriesID, Season, Episode),
constraint watched_fk1 foreign key(UserID) REFERENCES User1(UserID),
constraint watched_fk4 foreign key(SeriesID, Season, Episode) REFERENCES Episode(SeriesID, Season, Episode)
);
--Add users.
INSERT INTO User1 VALUES (1, 'StefPhilipsen', 'Netherlands', 'Male', TO_DATE('02-01-1994','DD-MM-YYYY'), 'Ik ben Stef', 'abcd1234');
INSERT INTO User1 VALUES (2, 'Dorothy142', 'America', 'Female', TO_DATE('01-10-1963','DD-MM-YYYY'), 'I love mountainbiking', 'Oow6sai4Ie');
INSERT INTO User1 VALUES (3, 'Rudo12', 'England', 'Male', TO_DATE('05-6-1985','DD-MM-YYYY'), 'I watched Breaking Bad and a lot more', 'Oph9Ge2yai');
INSERT INTO User1 VALUES (4, 'JohnSmith', 'England', 'Male', TO_DATE('27-9-1945','DD-MM-YYYY'), 'I like potatoes.', 'phiShaip0c');
INSERT INTO User1 VALUES (5, 'EulaWGibson', 'America', 'Female', TO_DATE('12-8-1990','DD-MM-YYYY'), 'I''m Eula. I live in massachusetts and I''m happily married with my husband Hank.', 'EiM5wii2am8');
INSERT INTO User1 VALUES (6, 'Pedro', 'Spain', 'Male', TO_DATE('12-10-1945','DD-MM-YYYY'), 'I love watching Arrow.', 'Gith0yaiw');
INSERT INTO User1 VALUES (7, 'TravisC', 'England', 'Male', TO_DATE('12-7-1970','DD-MM-YYYY'), 'My favorite TV-shows are Modern Family and Dexter.', 'gie9aiPh2Ii');
INSERT INTO User1 VALUES (8, 'DonellaScott', 'America', 'Female', TO_DATE('31-1-1996','DD-MM-YYYY'), 'Living the life.', 'Gued1996');
--Who follows which series.
INSERT INTO FollowingSeries(UserID, SeriesID) VALUES (1,1);
INSERT INTO FollowingSeries(UserID, SeriesID) VALUES (1,2);
INSERT INTO FollowingSeries(UserID, SeriesID) VALUES (1,3);
INSERT INTO FollowingSeries VALUES (1,4,1);
--Who follows who.
INSERT INTO FollowingUser VALUES(1,2);
INSERT INTO FollowingUser VALUES (2,3);
INSERT INTO FollowingUser VALUES (3,4);
INSERT INTO FollowingUser VALUES (1,3);
INSERT INTO FollowingUser VALUES (5,8);
INSERT INTO FollowingUser VALUES (5,6);
INSERT INTO FollowingUser VALUES (6,5);
-- Which episodes are watched by whom.
INSERT INTO Watched VALUES(1, 4, 1, 1);
INSERT INTO Watched VALUES(1, 4, 1, 2);
INSERT INTO Watched VALUES(1, 4, 1, 3);
INSERT INTO Watched VALUES(1, 4, 1, 4);
INSERT INTO Watched VALUES(1, 4, 1, 5);
INSERT INTO Watched VALUES(1, 4, 1, 6);
INSERT INTO Watched VALUES(1, 4, 1, 7);
This is what I tried but then I get an error message
--Create view
CREATE VIEW follownaam AS
SELECT followerUser.Username AS Follower, followingUser.Username AS Following
FROM FollowingUser AS fu
INNER JOIN User1 followerUser ON(fu.UserID1 = followerUser.Username)
INNER JOIN User1 followingUser ON(fu.UserID2 = followingUser.Username)
WHERE fu.UserID1 = 1;
[Err] ORA-00911: invalid character
The table I have exists of 2 UserID's. But now I want exactly the same table, but this view must contain the Usernames of these UserID's.
This should work (although i don't understand why You want a view only for user with ID = 1).
CREATE VIEW follownaam AS
SELECT
followerUser.Username AS Follower, followingUser.Username AS Following
FROM FollowingUser fu
INNER JOIN User1 followerUser ON(fu.UserID1 = followerUser.UserID)
INNER JOIN User1 followingUser ON(fu.UserID2 = followingUser.UserID)
WHERE fu.UserID1 = 1;
I changed Username to UserId because it made much more sense.
Edit:
Here's sqlfiddle i created to test it and it works.

difficulty inserting values in database

I have created my tables as shown below (I am using Oracle XE). The problem that occurs is that when I try to insert values into the tables, I get an error because the value of one's foreign key, has not been entered as a primary key of the other. For example, see tables DEPARTMENT and EMPLOYEE. Below, along with table creation code, is also the data inserting part. How to bypass that problem?
CREATE TABLE DEPARTMENT
(
DNAME VARCHAR(10),
DEPTID INTEGER NOT NULL,
MNG_IDNO INTEGER NOT NULL,
PRIMARY KEY (DEPTID)
);
CREATE TABLE EMPLOYEE
(
IDNO INTEGER NOT NULL,
FNAME VARCHAR(10) NOT NULL,
LNAME VARCHAR(10) NOT NULL,
GENDER VARCHAR(6) NOT NULL,
CITY VARCHAR(20),
AREA VARCHAR(20),
STREET VARCHAR(50),
HOUSENO VARCHAR(4),
ZIPCODE INTEGER,
BIRTHDAY DATE,
SALARY INTEGER,
IBAN VARCHAR(34),
DEPT_ID INTEGER NOT NULL,
PRIMARY KEY (IDNO)
);
CREATE TABLE CUSTOMER
(
IDNO INTEGER NOT NULL,
FNAME VARCHAR(10) NOT NULL,
LNAME VARCHAR(10) NOT NULL,
GENDER VARCHAR(6) NOT NULL,
CITY VARCHAR(20),
AREA VARCHAR(20),
STREET VARCHAR(50),
HOUSENO VARCHAR(4),
ZIPCODE INTEGER,
BIRTHDAY DATE,
PRIMARY KEY (IDNO)
);
CREATE TABLE CAR
(
VIN INTEGER NOT NULL,
BRAND VARCHAR(10) NOT NULL,
MODEL VARCHAR(10) NOT NULL,
COLOR VARCHAR(10) NOT NULL,
TRANTYPE VARCHAR(10) NOT NULL,
FUELTYPE VARCHAR(10) NOT NULL,
ENGCC INTEGER NOT NULL,
ENTRYDATE DATE,
PRICE INTEGER NOT NULL,
PAYMENTMETHOD VARCHAR(10) NOT NULL,
DEPT_ID INTEGER NOT NULL,
CUST_IDNO INTEGER NOT NULL,
PRIMARY KEY (VIN)
);
CREATE TABLE CAR_PARTS
(
PARTNUM VARCHAR(25) NOT NULL,
PARTNAME VARCHAR(25) NOT NULL,
COST INTEGER NOT NULL,
PRIMARY KEY (PARTNUM)
);
CREATE TABLE USED_CAR
(
CAR_VIN INTEGER NOT NULL,
MILEAGE INTEGER NOT NULL,
REGDATE DATE NOT NULL,
PRIMARY KEY (CAR_VIN)
);
CREATE TABLE SERVICE
(
DUE_DATE DATE,
ARR_DATE DATE,
COST INTEGER NOT NULL,
SERVICE_NUM INTEGER NOT NULL,
CUST_IDNO INTEGER NOT NULL,
PAYMENTMETHOD VARCHAR(10) NOT NULL,
CAR_VIN INTEGER NOT NULL,
PRIMARY KEY (SERVICE_NUM)
);
CREATE TABLE CUST_PHONUMBER
(
PHONE_NUM INTEGER NOT NULL,
CUST_IDNO INTEGER NOT NULL,
PHONE_TYPE VARCHAR(10),
PRIMARY KEY (CUST_IDNO, PHONE_NUM)
);
CREATE TABLE CAR_DEFECTS
(
DEFECTS VARCHAR(100) NOT NULL,
CAR_VIN VARCHAR(100) NOT NULL,
PRIMARY KEY (DEFECTS, CAR_VIN)
);
CREATE TABLE EMPLOYEE_PHONUMBER
(
PHONENUM INTEGER NOT NULL,
EMPL_IDNO INTEGER NOT NULL,
PRIMARY KEY (PHONENUM, EMPL_IDNO)
);
CREATE TABLE SERVICE_DETAILS
(
SERVICENUM INTEGER NOT NULL,
PROBLEMS VARCHAR(100) NOT NULL,
SOLUTION VARCHAR(100),
PRIMARY KEY (PROBLEMS, SERVICENUM)
);
CREATE TABLE HAS
(
PART_NUM VARCHAR(25) NOT NULL,
CAR_VIN INTEGER NOT NULL,
PRIMARY KEY (PART_NUM, CAR_VIN)
);
CREATE TABLE USES
(
PART_NUM VARCHAR(25) NOT NULL,
SERVICE_NUM INTEGER NOT NULL,
PRIMARY KEY (PART_NUM, SERVICE_NUM)
);
ALTER TABLE DEPARTMENT ADD FOREIGN KEY (MNG_IDNO) REFERENCES EMPLOYEE(IDNO);
ALTER TABLE EMPLOYEE ADD FOREIGN KEY (DEPT_ID) REFERENCES DEPARTMENT(DEPTID);
ALTER TABLE CAR ADD FOREIGN KEY (DEPT_ID) REFERENCES DEPARTMENT(DEPTID);
ALTER TABLE CAR ADD FOREIGN KEY (CUST_IDNO) REFERENCES CUSTOMER(IDNO);
ALTER TABLE SERVICE ADD FOREIGN KEY (CUST_IDNO) REFERENCES CUSTOMER(IDNO);
ALTER TABLE SERVICE ADD FOREIGN KEY (CAR_VIN) REFERENCES CAR(VIN);
ALTER TABLE USED_CAR ADD FOREIGN KEY (CAR_VIN) REFERENCES CAR(VIN);
ALTER TABLE HAS ADD FOREIGN KEY (PART_NUM) REFERENCES CAR_PARTS(PARTNUM);
ALTER TABLE HAS ADD FOREIGN KEY (CAR_VIN) REFERENCES CAR(VIN);
ALTER TABLE USES ADD FOREIGN KEY (PART_NUM) REFERENCES CAR_PARTS(PARTNUM);
ALTER TABLE USES ADD FOREIGN KEY (SERVICE_NUM) REFERENCES SERVICE(SERVICE_NUM);
ALTER TABLE CUSTOMER_PHONUMBER ADD FOREIGN KEY (CUST_IDNO) REFERENCES CUSTOMER(IDNO);
ALTER TABLE EMPLOYEE_PHONUMBER ADD FOREIGN KEY (EMPL_IDNO) REFERENCES EMPLOYEE(IDNO);
ALTER TABLE SERVICE_DETAILS ADD FOREIGN KEY (SERVICENUM) REFERENCES SERVICE(SERVICE_NUM);
Data Insert:
INSERT INTO EMPLOYEE VALUES (1234,'ANTREAS','GEORGIOU','MALE','NICOSIA','STROVOLOS','PANAYIAS','12',2682,TO_DATE('01.01.1989', 'DD.MM.YYYY'),5000,9999999,1);
INSERT INTO EMPLOYEE VALUES (1235,'KOSTAS', 'KOSTA', 'MALE', 'NICOSIA','STROVOLOS','VIZANTIOU','12',2064,TO_DATE('01.02.1980', 'DD.MM.YYYY'),5000,9999998,2);
INSERT INTO EMPLOYEE VALUES (1236,'MARIA', 'ANTREOU', 'FEMALE', 'NICOSIA','EGKOMI','TSAROU','12',2522,TO_DATE('05.05.1988', 'DD.MM.YYYY'),5000,9999995,3);
INSERT INTO EMPLOYEE VALUES (1237,'GEORGIA', 'ANTREOU', 'FEMALE', 'NICOSIA','EGKOMI','TSAROU','13',2522,TO_DATE('05.05.1978', 'DD.MM.YYYY'),5000,9999996,4);
INSERT INTO DEPARTMENT VALUES ('SERVICE',1,1234);
INSERT INTO DEPARTMENT VALUES ('SALES',2,1235);
INSERT INTO DEPARTMENT VALUES ('ACCOUNTING',3,1236);
INSERT INTO DEPARTMENT VALUES ('MANAGEMENT',4,1237);
INSERT INTO CUSTOMER VALUES (4321, 'ANTREAS', 'ANTREOU','MALE','PAFOS','GEROSKIPOU','VIZANTIOU','3',2525,TO_DATE('04.04.1954','DD.MM.YYYY'));
INSERT INTO CUSTOMER VALUES (4322, 'MARIA', 'ANTREOU','FEMALE','PAFOS','GEROSKIPOU','VIZANTIOU','7',2525,TO_DATE('03.03.1953','DD.MM.YYYY'));
INSERT INTO CUSTOMER VALUES (4323, 'KOSTAS', 'ANTREOU','MALE','PAFOS','GEROSKIPOU','VIZANTIOU','3',2525,TO_DATE('04.04.1970','DD.MM.YYYY'));
INSERT INTO CUSTOMER VALUES (4324, 'ELENA', 'ANTREOU','MALE','PAFOS','GEROSKIPOU','VIZANTIOU','3',2252,TO_DATE('04.04.1985','DD.MM.YYYY'));
INSERT INTO CUSTOMER VALUES (4325, 'MARIOS', 'ANTREOU','MALE','PAFOS','GEROSKIPOU','VIZANTIOU','3',2525,TO_DATE('04.04.1987','DD.MM.YYYY'));
INSERT INTO CAR VALUES (1111111111, 'MAZDA', '3', 'BLUE', 'MANUAL', 'PETROL', 1600, TO_DATE('08.01.2013','DD.MM.YYYY'), 5000, 'CASH', 2, 4321);
INSERT INTO CAR VALUES (2222222222, 'TOYOTA', 'COROLLA','BLACK', 'MANUAL','PETROL',1600,TO_DATE('08.01.2013','DD.MM.YYYY'),7000,'FINANCE',2,4322);
INSERT INTO CAR VALUES (3333333333, 'TOYOTA', 'HILUX', 'GRAY', '4X4', 'DIESEL', 2500, TO_DATE('08.01.2013','DD.MM.YYYY'), 10000, 'CASH', 2 , 4325);
INSERT INTO CAR VALUES (4444444444, 'HONDA', 'CIVIC', 'BLACK', 'MANUAL', 'PETROL', 1300, TO_DATE('08.01.2013','DD.MM.YYYY'), 3000,'CASH', 2, 4323);
INSERT INTO CAR VALUES (5555555555, 'HONDA', 'INSIGHT', 'WHITE', 'AUTO', 'PETROL', 1500, TO_DATE('08.01.2013','DD.MM.YYYY'), 20000, 'FINANCE', 2, 4324);
INSERT INTO CAR_PARTS VALUES ('A20005B', 'RIGHT FRONT AXLE', 200);
INSERT INTO CAR_PARTS VALUES ('C15220C', 'AIR FILTER', 50);
INSERT INTO CAR_PARTS VALUES ('V99T', 'ENGINE GASKET', 80);
INSERT INTO CAR_PARTS VALUES ('A20004B', 'LEFT FRONT AXLE', 200);
INSERT INTO CAR_PARTS VALUES ('U9P002', 'INTAKE MANIFOLD', 300);
INSERT INTO USED_CAR VALUES (4444444444, 25000, TO_DATE('02.02.2000','DD.MM.YYYY'));
INSERT INTO USED_CAR VALUES (5555555555, 122000, TO_DATE('05.08.2003','DD.MM.YYYY'));
INSERT INTO SERVICE VALUES (TO_DATE('12.01.2013','DD.MM.YYYY'), TO_DATE('01.01.2013','DD.MM.YYYY'), 300, 0001, 4321, 'CASH', 1111111111);
INSERT INTO CUST_PHONUMBER VALUES (99123456, 4321, 'MOBILE');
INSERT INTO CUST_PHONUMBER VALUES (99849563, 4322, 'MOBILE');
INSERT INTO CUST_PHONUMBER VALUES (22568988, 4323, 'LANDLINE');
INSERT INTO CUST_PHONUMBER VALUES (25698974, 4324, 'LANDLINE');
INSERT INTO CUST_PHONUMBER VALUES (97584692, 4325, 'MOBILE');
INSERT INTO CAR_DEFECTS VALUES ('BROKEN SIDE MIRRORS|OIL LEAKS', 4444444444);
INSERT INTO CAR_DEFECTS VALUES ('RUSTY PAINT|WORN-OUT CLUTCH', 5555555555);
INSERT INTO EMPLOYEE_PHONUMBER VALUES (97989565, 1234);
INSERT INTO EMPLOYEE_PHONUMBER VALUES (97585858, 1235);
INSERT INTO EMPLOYEE_PHONUMBER VALUES (96525263, 1236);
INSERT INTO EMPLOYEE_PHONUMBER VALUES (97484852, 1237);
INSERT INTO SERVICE_DETAILS VALUES (0001, 'BROKEN FRONT RIGHT AXLE', 'REPLACED FRONT RIGHT AXLE');
INSERT INTO HAS VALUES ('A20005B', 1111111111);
INSERT INTO HAS VALUES ('A20004B', 1111111111);
INSERT INTO USES VALUES ('A20005B', 0001);

SQL server, HAVING clause issue

I have to write a query for my database. The query is below.
/* Query 9 – Most Valuable Players
"Who has received at least 2 MVP awards?"
Produce a query to display the full name and number of MVP awards of any players who have been awarded the MVP in at least 2 races.
Make sure that races where no MVP was awarded are not included in the results, and order your results by the number of MVP awards in descending order.
Using your race view in this query is recommended.
Hint: Use HAVING to limit the results to players with an MVP count of at least 2.
I've tried it using this code:
CREATE VIEW playerView1
AS
select
player.id, player.firstName + ' ' + player.surname AS 'Full Name', race.mvp
from
player
JOIN
race ON player.team = race.team
GO
SELECT playerView1.[Full Name]
From playerView1
GROUP BY [Full Name]
HAVING (playerView1.mvp) >1
and also tried
SELECT
player.firstName + ' ' + player.surname AS 'Full_name', raceView.mvp AS 'MVP Number',
raceView.mvp_name AS 'MVP Name'
FROM
raceView
JOIN
player ON raceView.mvp_name = player.firstName
WHERE
raceView.mvp > 1
And no luck. Any ideas on where I've gone wrong? and possibly a fix?
One of the errors I came across using the first query was
Msg 8121, Level 16, State 1, Line 4
Column 'playerView1.mvp' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Below is my entire database script which include create, populate and view before been able to do the query which results in my issue.
IF DB_ID ('Assignment2') IS NOT NULL
BEGIN
DROP DATABASE Assignment2;
END
/* Now create new database*/
CREATE DATABASE Assignment2;
GO
/* Make system use new database */
USE Assignment2;
/* Begin Creating tables */
/** Create Course Table **/
PRINT 'Creating table course.';
CREATE TABLE course (
id INT IDENTITY, -- [CourseID] [int] IDENTITY(1,1) NOT NULL,
name VARCHAR(50), -- [CourseName] [varchar](50) NULL,
passingScore NUMERIC(18,0), -- [PassingScore] [numeric](18, 0) NOT NULL,
CONSTRAINT course_pk PRIMARY KEY (id),
CONSTRAINT passingScore CHECK (passingScore BETWEEN 0 AND 100)
);
/** Create RaceType Table**/
PRINT 'Creating table Race Type.'
CREATE TABLE raceType (
id INT IDENTITY, -- [RaceTypeID] [int] IDENTITY(1,1) NOT NULL,
name VARCHAR(25) NOT NULL, -- [RaceTypeName] [varchar](25) NOT NULL,
CONSTRAINT raceType_pk PRIMARY KEY (id),
CONSTRAINT raceType_unique UNIQUE (name)
);
/** Create 'Teams' Table */
PRINT ' Creating table called Teams'
CREATE TABLE team (
id INT IDENTITY, -- [TeamID] [int] IDENTITY (1,1) NOT NULL,
name VARCHAR(25) NOT NULL, -- [TeamName] [varchar] (25) NOT NULL,
biography TEXT, -- [Biography] [text] NULL,
hyperlink VARCHAR(max), -- [Hyperlink] [varchar] (max) NULL,
CONSTRAINT team_pk PRIMARY KEY (id),
CONSTRAINT team_unique UNIQUE (name)
);
/** Create "Players" Table**/
PRINT ' Creating table called Players'
CREATE TABLE player (
id INT IDENTITY, -- [PlayerID] [int] IDENTITY(1,1) NOT NULL,
firstName VARCHAR(50) NOT NULL, -- [FirstName] [varchar](50) NOT NULL,
surname VARCHAR(50) NOT NULL, -- [Surname] [varchar](50) NOT NULL,
coach INT, -- fk1 [CoachID] [int] NULL,
team INT, -- fk2 [TeamID] [int] NULL,
CONSTRAINT player_pk PRIMARY KEY (id),
CONSTRAINT player_fk1 FOREIGN KEY (team) REFERENCES team (id),
CONSTRAINT player_fk2 FOREIGN KEY (coach) REFERENCES player (id)
);
/** Create "Races" Table **/
PRINT ' Creating table called Races'
CREATE TABLE race (
id INT IDENTITY, -- [RaceID] [int] IDENTITY(1,1) NOT NULL,
dateOfRace DATETIME NOT NULL, -- [DateOfRace] [datetime] NOT NULL,
raceType INT NOT NULL, -- [RaceTypeID] [int] NOT NULL,
course INT NOT NULL, -- [CourseID] [int] NOT NULL,
team INT NOT NULL, -- [TeamID] [int] NOT NULL,
observer INT NOT NULL, -- [ObserverID] [int] NOT NULL,
mvp INT NULL, -- [MvpPlayerID] [int] NULL,
finalScore INT NOT NULL, -- [FinalScore] [int] NOT NULL,
pointsPenalised INT NOT NULL, -- [PointsPenalised] [int] NOT NULL,
CONSTRAINT race_pk PRIMARY KEY (id),
CONSTRAINT race_fk1 FOREIGN KEY (raceType) REFERENCES raceType(id),
CONSTRAINT race_fk2 FOREIGN KEY (course) REFERENCES course(id),
CONSTRAINT race_fk3 FOREIGN KEY (team) REFERENCES team(id),
CONSTRAINT race_fk4 FOREIGN KEY (observer) REFERENCES player(id),
CONSTRAINT race_fk5 FOREIGN KEY (mvp) REFERENCES player(id)
);
GO
/** End*/
The populate script
/** Begin Populating "Course" table*/
PRINT 'Populating Course Table'
INSERT INTO course (name,passingScore)
VALUES ('Easy Course','80');
INSERT INTO course (name,passingScore)
VALUES ('Medium Course','70');
INSERT INTO course (name,passingScore)
VALUES ('Hard Course','60');
/** Begin Populating "RaceType" Table */
PRINT 'Populating RaceType Table '
INSERT INTO raceType (name)
VALUES ('Ranked')
INSERT INTO raceType (name)
VALUES ('Practise')
/** Begin Populating "Teams" Table */
PRINT ' Populating Teams Table'
INSERT INTO team (name)
VALUES ('Team BMW');
INSERT INTO team (name)
VALUES ('Team Porsche');
INSERT INTO team (name)
VALUES ('Team Mercedez');
INSERT INTO team (name)
VALUES ('Team AMartin');
INSERT INTO team (name)
VALUES ('Team Audi');
INSERT INTO player (firstName, surname)
VALUES ('hoger','amedi');
INSERT INTO player (firstName, surname, coach, team)
VALUES (' Lloyd', 'Banks', 1, 1);
INSERT INTO player (firstName, surname)
VALUES ('Silav', 'Govand');
INSERT INTO player (firstName, surname, coach, team)
VALUES ('hell', 'razor', 2, 2);
INSERT INTO player (firstName, surname, coach, team)
VALUES ( 'Alden', 'Padilla', 3, 1);
INSERT INTO player (firstName, surname)
VALUES ( 'Sina', 'Parker');
INSERT INTO player (firstName, surname, coach, team)
VALUES ( 'Lyle', ' Burks', 4, 2);
INSERT INTO player (firstName, surname, coach, team)
VALUES ('Rhona', 'Anthony', 5, 3);
INSERT INTO player (firstName, surname, team)
VALUES ('Seelie', 'Harper', 5);
INSERT INTO player (firstName, surname, coach, team)
VALUES ('Harper', 'Leonards', 6, 4)
INSERT INTO player (firstName, surname, coach, team)
VALUES ('jack', 'Merril', 7, 5)
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer,mvp)
VALUES ('2011-12-03 06:01:49','53','4','2','1','4','2','1');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer,mvp)
VALUES ('2011-11-25 09:31:26','73','5','2','2','1','3','2');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer,mvp)
VALUES ('2011-12-03 19:36:34','52','1','1','1','5','4','3');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer,mvp)
VALUES ('2011-12-10 20:07:11','51','4','2','3','2','5','2');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer,mvp)
VALUES ('2011-11-15 19:19:33','83','5','2','1','3','6','1');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer)
VALUES ('2011-11-27 02:32:09','53','1','2','3','5','7');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer)
VALUES ('2011-11-24 10:31:53','51','3','1','1','4','8');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer)
VALUES ('2011-11-19 15:17:32','70','2','1','2','5','9');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer)
VALUES ('2011-12-08 18:00:51','59','2','1','3','1','10');
INSERT INTO race (dateOfRace,finalScore,pointsPenalised,raceType,course,team,observer)
VALUES ('2011-12-09 19:55:53','67','5','2','3','5','10');
Select *
From player;
Select *
From team;
Select *
From raceType;
Select *
From course;
Select *
From race;
the View script
USE Assignment2;
GO
PRINT 'Creating Player View'
GO
CREATE VIEW playerView AS
SELECT player.id, player.firstName + ' ' + player.surname AS 'Full name', player.team, team.name, player.coach, coach.firstName, coach.surname
FROM player
LEFT OUTER JOIN team
ON player.team = team.id
LEFT OUTER JOIN player as coach
ON player.coach = coach.id;
GO
/*
Create a view which shows the following details of all races:
• All of the columns in the race table
• The name of the race type, course and team involved in the race
• The full name of the player observing the race and the full name of the MVP (if applicable)
• A calculated column with an alias of “unpenalised_score”, which adds the points penalised to the final score
Creating this view requires a select statement using multiple joins and concatenation of names.
Make sure that you use the appropriate type of join to ensure that races without MVPs are still included in the results.
*/
-- Write your Race View here
PRINT 'Creating Race View'
GO
CREATE VIEW raceView AS
SELECT race.id, race.dateOfRace, race.raceType, raceType.name AS raceTypeName, race.course, course.name AS courseName, race.team, team.name AS teamName, race.observer, obs.firstName + ' ' + obs.surname AS observer_name, race.mvp, mvp.firstName + ' ' + mvp.surname AS mvp_name, race.pointsPenalised, race.finalScore + race.pointsPenalised AS unpenalised_score, race.finalScore
FROM race
INNER JOIN raceType
ON race.raceType = raceType.id
INNER JOIN course
ON race.course = course.id
INNER JOIN team
ON race.team = team.id
LEFT OUTER JOIN player AS mvp
ON race.mvp = mvp.id
LEFT OUTER JOIN player AS obs
ON race.observer = obs.id;
GO
SELECT *
FROM playerView
SELECT *
FROM raceView
you need to use COUNT
select player.id,
player.firstName + ' ' + player.surname AS [Full Name],
COUNT(*)
from player JOIN race
ON player.team = race.team
GROUP BY id, player.firstName + ' ' + player.surname
HAVING COUNT(*) >= 2
UPDATE 1
SELECT MVP_NAME, COUNT(*) TotalMVP
FROM raceView
WHERE MVP IS NOT NULL
GROUP BY MVP_NAME
HAVING COUNT(*) >= 2
ORDER BY TotalMVP DESC;
SQLFiddle Demo