SQL Server 2014 server new to JOINS - sql

I am new to SQL server.
I would like to ask how can I join these statements? The result should be batman, tim burton to james murrilo.
CREATE TABLE Movie(
movieId INT NOT NULL,
movieTitle CHAR(50) NOT NULL,
director CHAR(50) NOT NULL
PRIMARY KEY (movieId)
);
INSERT INTO Movie (movieId, movieTitle, director)VALUES (1, 'Batman', 'Tim Burton');
INSERT INTO Movie (movieId, movieTitle, director)VALUES (2, 'Spiderman','Sam Raimi');
CREATE TABLE Reviewer(
reviewerId INT NOT NULL,
reviewerName CHAR(50) NOT NULL,
PRIMARY KEY (reviewerId)
);
INSERT INTO Reviewer (reviewerId, reviewerName) VALUES(1, 'David Carroll');
INSERT INTO Reviewer (reviewerId, reviewerName) VALUES(2, 'James Murillo');
CREATE TABLE Movie_Reviewers(
movieId INT NOT NULL,
reviewerId INT NOT NULL,
CONSTRAINT movieReviewerPK PRIMARY KEY(movieId, reviewerId),
CONSTRAINT movieFK1 FOREIGN KEY(movieId) REFERENCES Movie,
CONSTRAINT reviewerFK1 FOREIGN KEY(reviewerId) REFERENCES Reviewer
);
INSERT INTO Movie_Reviewers (MovieId, reviewerId) VALUES(1,2);
INSERT INTO Movie_Reviewers (MovieId, reviewerId) VALUES(2,1);
SELECT Movie_Reviewers.*, Movie.MovieTitle, Movie.director, Reviewer.reviewerName
FROM Movie_Reviewers
JOIN Movie ON Movie.MovieId = Movie_Reviewers.MovieId
JOIN Reviewer ON Reviewer.reviewerId = Movie_Reviewers.MovieId

Just fix the last line - Movie_Reviewers.ReviewerID
JOIN Reviewer ON Reviewer.reviewerId = Movie_Reviewers.ReviewerId

Use where clause and there is a small mistake in your last join - what I understand from your question you need to get movie id 1 value
using your query you'll get all results for movie
SELECT Movie_Reviewers.*, Movie.MovieTitle, Movie.director, Reviewer.reviewerName
FROM Movie_Reviewers
JOIN Movie ON Movie.MovieId = Movie_Reviewers.MovieId
JOIN Reviewer ON Reviewer.reviewerId = Movie_Reviewers.reviewerId
where Movie.MovieId=1

Join with valid Primary key and Foreign key Relationship,
SELECT Movie_Reviewers.*, Movie.MovieTitle, Movie.director, Reviewer.reviewerName
FROM Movie_Reviewers
JOIN Movie ON Movie.MovieId = Movie_Reviewers.MovieId
JOIN Reviewer ON Reviewer.reviewerId = Movie_Reviewers.reviewerId

Related

Find all the persons which contains the provided resources

Below are the tables:
CREATE TABLE Person(
PersonID INT PRIMARY KEY,
FirstName VARCHAR(10),
LastName VARCHAR(10));
CREATE TABLE Resources(
ResourceID CHAR(3) PRIMARY KEY
);
CREATE TABLE PR (
PersonID INT,
ResourceID CHAR(3),
CONSTRAINT pkpr PRIMARY KEY (PersonID, ResourceID),
CONSTRAINT fkPersonID FOREIGN KEY (PersonID) REFERENCES Person(PersonID),
CONSTRAINT fkResourceID FOREIGN KEY (ResourceID) REFERENCES Resources(ResourceID));
INSERT INTO Person(PersonID, FirstName, LastName) VALUES (1, 'Bill', 'Smith'),(2, 'John','Jones');
INSERT INTO Resources (ResourceID) VALUES ('ABC'),('DEF'),('HIJ');
INSERT INTO PR (PersonID, ResourceID) VALUES (1,'ABC'),(1,'DEF'),(2,'ABC'), (2,'HIJ'), (1,'HIJ');
How to find all the persons which has resources ('ABC', 'DEF') ?
With above inserted data it should return person Bill Smith
I am using PostgreSql.
You can use aggregation:
select pr.personid
from pr
where pr.resourceid in ('ABC', 'DEF')
group by pr.personid
having count(*) = 2;
The primary key on pr prevents duplicates, so count(*) ensures that both resources are assigned to the person.

Same primary keys for relation

Lets say I have two many-to-many relations called Tutors and Assits. They are both connected courses. If they are both inheritance of relation called Staff they both have the same primary keys. That would mean the many-to-many relation will also have the same primary keys.
If I have two relations with the same primary keys what do I do? Here is an example of the table:
It should be pretty simple to add those two relationships. For example:
create table staff (
id int primary key not null,
name varchar(20)
);
create table tutor (
id int primary key not null,
office_number varchar(10),
foreign key (id) references staff (id)
);
create table assistant (
id int primary key not null,
title varchar(20),
foreign key (id) references staff (id)
);
create table course (
course_id int not null,
year int not null,
semester int not null,
primary key (course_id, year, semester),
tutor_id int not null references tutor (id),
assistant_id int not null references assistant (id)
);
Now, if you insert some data:
insert into staff (id, name) values (1, 'Alice');
insert into staff (id, name) values (2, 'Victor');
insert into tutor (id, office_number) values (1, '101-A');
insert into assistant (id, title) values (2, 'Adjunct Professor');
insert into course (course_id, year, semester, tutor_id, assistant_id)
values (101, 2020, 1, 1, 2);
You can run a query over it:
select
c.course_id, c.year, c.semester,
ts.name as tutor, t.office_number,
ta.name as assistant, a.title
from course c
join tutor t on c.tutor_id = t.id
join staff ts on ts.id = t.id
join assistant a on c.assistant_id = a.id
join staff ta on ta.id = a.id
Result:
course_id year semester tutor office_number assistant title
---------- ----- --------- ------ -------------- ---------- -----------------
101 2020 1 Alice 101-A Victor Adjunct Professor
See running example at DB Fiddle.
If the relation course - tutor is a many-to-many relation you will need an extra xref table:
course -|---|< course_tutor >0---|- tutor
The same thing for assistant.
Even when the same person is tutor and assistant in the same course there will be a record in course_tutor and course_assistant with the same course_id and staff_id but that is not a problem.

Counting in Oracle 11g

all day I am struggling with oracle exrcises and again I stuck. I need to select last names of boxers with their wins of each weight category.
So I have:
table "boxer" with columns: id, fname, lname, weight
table "fight" with two foreign keys from table boxer (id_boxer1 and id_boxer2) and with one column winner (if boxer1 won then winner will be number 1, if boxer2 won then winner will be number 2)
table "category_weight" with columns: id, min_weight, max_weight, name (of a category)
Example:
CREATE TABLE category_weight(
id INTEGER NOT NULL,
min_weight SMALLINT NOT NULL,
max_weight SMALLINT NOT NULL,
name VARCHAR2(20) NOT NULL
);
ALTER TABLE category_weight ADD CONSTRAINT category_weight_pk PRIMARY KEY ( id );
CREATE TABLE boxer(
id INTEGER NOT NULL,
fname VARCHAR2(20) NOT NULL,
lname VARCHAR2(20) NOT NULL,
weight INTEGER NOT NULL
);
ALTER TABLE boxer ADD CONSTRAINT boxer_pk PRIMARY KEY ( id );
CREATE TABLE fight(
id INTEGER NOT NULL,
winner SMALLINT NOT NULL,
id_category_weight INTEGER NOT NULL,
id_boxer1 INTEGER NOT NULL,
id_boxer2 INTEGER NOT NULL
);
ALTER TABLE fight ADD CONSTRAINT fight_pk PRIMARY KEY ( id );
ALTER TABLE fight
ADD CONSTRAINT boxer_fk FOREIGN KEY ( id_boxer1 )
REFERENCES boxer ( id );
ALTER TABLE fight
ADD CONSTRAINT boxer_fk2 FOREIGN KEY ( id_boxer2 )
REFERENCES boxer ( id );
ALTER TABLE fight
ADD CONSTRAINT categ_weight_fk FOREIGN KEY ( id_category_weight )
REFERENCES category_weight ( id );
INSERT INTO boxer
VALUES ('1', 'Johnny','Johnny','60');
INSERT INTO boxer
VALUES ('2', 'Anthonny','Anthonny','54');
INSERT INTO boxer
VALUES ('3', 'Anonimm','Anonimm','59');
INSERT INTO boxer
VALUES ('4', 'John','Johnowski','71');
INSERT INTO category_weight
VALUES ('1', '1','70','category1');
INSERT INTO category_weight
VALUES ('2', '71','100','category2');
INSERT INTO fight
VALUES ('1','1','1','1','2');
INSERT INTO fight
VALUES ('2','2','1','3','1');
Boxer with ID "1" won two fights in category1, so the result should be:
Lname Category Wins
Johnny category1 2
Here, try this:
SELECT b.lname,
cw.max_weight AS WEIGHT_CLASS,
COUNT(CASE WHEN f.winner = b.id THEN 1 ELSE NULL END) AS WINS
FROM boxer b
INNER JOIN fight f ON b.id = f.id_boxer1 OR b.id = f.id_boxer2
INNER JOIN category_weight cw ON f.id_category_weight = cw.id
GROUP BY b.lname, cw.max_weight

SQL: "foreign key constraint fails" error message

I get an error when attempting to insert data into the songs table. I'm not sure why.
Any help would be greatly appreciated. Thanks. This is me adding details so it will let me post haha.
create table artist
(
id int primary key auto_increment,
name varchar(128) not null,
nationality varchar(128)
) ENGINE=InnoDB;
insert into artist (name, nationality) values ('Metallica', 'American');
insert into artist (name, nationality) values ('Rush', 'Canadian');
create table album
(
id int primary key auto_increment,
name varchar (128) not null,
artist int not null,
foreign key (artist) references artist(id),
genre int,
foreign key (genre) references genre(id)
) ENGINE=InnoDB;
insert into album (name, artist, genre) values ('Ride the Lightning', 1, 1);
insert into album (name, artist, genre) values ('Moving Pictures', 2, 2);
create table song
(
id int primary key auto_increment,
name varchar (128) not null,
duration varchar (128),
album int not null,
foreign key (album) references album(id)
) ENGINE=InnoDB;
insert into song (name, duration, album) values ('Fade to Black', '1 min', 1);
insert into song (name, duration, album) values ('Tom Sawyer', '2 min', 2);
create table genre
(
id int primary key auto_increment,
name varchar (128) not null,
description varchar (256)
) ENGINE=InnoDB;
insert into genre (name, description) values ('Rock', 'Lots of drums and guitars');
insert into genre (name, description) values ('Metal', 'Drums and guitars on steroids');
The order of your code is causing the problem. You need to move the
create table genre
(
id int primary key auto_increment,
name varchar (128) not null,
description varchar (256)
) ENGINE=InnoDB;
insert into genre (name, description) values ('Rock', 'Lots of drums and guitars');
insert into genre (name, description) values ('Metal', 'Drums and guitars on steroids');
Up above the "Create table album"
Here is the correct way to do it: HOW TO DO IT
This is some reasons why it did not work:
There is no table "genre" when you try to create table album:
create table album
(
id int primary key auto_increment,
name varchar (128) not null,
artist int not null,
foreign key (artist) references artist(id),
genre int,
foreign key (genre) references genre(id)
) ENGINE=InnoDB;
Here is the DEMO
Also, when you create table "genre" on time, there is another problem. You have to insert data in table "genre" to be able to insert other data.
Here is the DEMO where all works.
One is the order of the create and insert statements shouldve given you error already as table referres doesnt exists etc.
Assuming if the order is rightly implemented, as per the above error not able to insert data in songs is likely because
Your album table has a null id or id which you are inserting in songs doesnt exists in album first insert the data in album table then insert into songs table as the foreign key of songs table is checking the album table for id data

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