Get what areas have more than three qualified employees - mysql

I have this tables from the MySql database i'm working with:
create table employees (
num_pass int(5) not null,
name varchar(40),
primary key (num_pass)
)engine=innodb;
create table laboratories (
code int(10) not null,
name varchar(40),
primary key (codi),
)engine=innodb;
create table areas (
code int(5) not null,
codeLab int(10) not null,
level enum('H','M','L'),
primary key (code, codeLab),
foreign key (codeLab) references laboratories(code)
)engine=innodb;
create table qualifieds (
num_pass int(5) not null,
area_assigned int(5),
lab int(5),
primary key (num_pass),
foreign key (num_pass) references employees(num_pass),
foreign key (area_assigned, lab) references areas (code, codeLab)
)engine=innodb;
Now i want to get what areas have more than three qualified employees. Specifically, i want to get area code along with the name of the laboratory, laboratory and ordered by region.
I tried to use this command in order to get the code of the area
select b.code
from employees e, areas b, qualifieds q
where e.num_pass=q.num_pass
and 3 < (select count(b1.code)
from areas b1, qualifieds q1, employers e1
where e1.num_pass=q1.num_pass
and q1.area_assigned=b1.code
and q1.lab=b1.codeLab);
But all what i get is a list of all the area codes repeated as many times as the number of employees (i have areas with code 1,2,3,4 and 6 employees, what i get is the sequence 1,2,3,4 repeated 6 times).Any idea about how to get the information i need?

You can use GROUP BY and HAVING to find a group with more than 3 records...
select areas_assigned, lab, count(num_pass)
from qualifieds
group by areas_assigned, lab
having count(num_pass)>3;
If you then need to expand on this, then add joins...
select q.areas_assigned, l.name, count(q.num_pass)
join laboratories l on l.lab = q.lab
from qualifieds q
group by q.areas_assigned, l.name
having count(q.num_pass)>3;

Related

Mysql Selecting the average value of a column from things that are stored in 3 tables

I am fairly new with databases and I am starting with mysql.
I have 4 tables (movie, genre, movieGenre and movieRating):
movie:
CREATE TABLE `movie` (
`movieId` INT NOT NULL,
`title` VARCHAR(155) NOT NULL,
PRIMARY KEY (`movieId`)
);
genre
CREATE TABLE `genre` (
`code` INT NOT NULL AUTO_INCREMENT,
`genre` VARCHAR(20) NOT NULL,
PRIMARY KEY (`code`)
);
movieGenre
CREATE TABLE `movieGenre` (
`movieId` INT,
`genreId` INT,
CONSTRAINT `fk_movieGenre_movie` FOREIGN KEY (`movieId`) REFERENCES `movie`(`movieId`),
CONSTRAINT `fk_movieGenre_genre` FOREIGN KEY (`genreId`) references `genre`(`code`)
);
and movieRating
CREATE TABLE `movieRating` (
`userId` INT NOT NULL AUTO_INCREMENT,
`movieId` INT NOT NULL,
`rating` FLOAT NOT NULL,
`date` DATE,
CONSTRAINT `fk_movieRating_user` FOREIGN KEY (`userId`) REFERENCES `user`(`userId`),
CONSTRAINT `fk_movieRating_movie` FOREIGN KEY (`movieId`) REFERENCES `movie`(`movieId`)
);
I need to find the average rate for each movie genre, sorted in descended average rating value and if a genre does not have any associated rating, it should be reported with 0 ratings value
I am lost. I don't know how to achieve this result. Could you please help me?
I have figured out how to find the avg rate for each movie but I don't know how to change this so I find for each genre:
SELECT `movie`.`movieId`, AVG(`movieRating`.`rating`) FROM `movie`
INNER JOIN `movieRating` ON `movie`.`movieId` = `movieRating`.`movieId`
GROUP BY `movieRating`.`movieId`
ORDER BY AVG(`movieRating`.`rating`) DESC;
Well, I have put an ID in your genre table, otherwise I can't make this work. So, it has become:
CREATE TABLE `genre` (
`genreId` INT,
`code` INT NOT NULL AUTO_INCREMENT,
`genre` VARCHAR(20) NOT NULL,
PRIMARY KEY (`code`)
);
And I have to make the assumption that all the genres are defined in this table. I'll take this table as a base, and, as you suggested use a subquery:
SELECT
genre.code,
genre.genre,
(<my sub select comes here>)
FROM
genre;
This basically gets you a list of all genres. Now it is up to the subquery to give the average rate for the movies in each genre. That subquery could look something like this:
SELECT AVG(movieRating.rating)
FROM movieRating
JOIN movie ON movie.movieId = movieRating.movieId
JOIN movieGenre ON movieGenre.movieId = M.movieId
WHERE movieGenre.genreId = genre.genreId;
I kept it very simple. We start with the average we want, from movieRating, and work through the movie and movieGenre tables to get to the genreId in that last table. Notice the genre.genreId which comes from the main query. We are implicitly grouping by genreId.
Now you can put this subselect in the main query, but that still doesn't solve the situation in which there is not rating to take an average from. It would result in NULL, meaning: no result. That is almost good enough, but you could put a IFNULL() around it to get a proper zero result.
The total query would then become this:
SELECT
genre.code,
genre.genre,
IFNULL((SELECT AVG(movieRating.rating)
FROM movieRating
JOIN movie ON movie.movieId = movieRating.movieId
JOIN movieGenre ON movieGenre.movieId = M.movieId
WHERE movieGenre.genreId = genre.genreId), 0) AS Average
FROM
genre;
I can't guarantee this will work since I cannot test it, and testing is everything when writing queries.
You should left join all tables and then group by gerne
SELECT `genre`,AVG(IFNULL(`rating`,0)) avgrate
FROM `movie` m
LEFT JOIN `movieRating` mr ON m.`movieId` = mr.`movieId`
LEFT JOIN movieGenre mg ON mg.`movieId` = m.`movieId`
LEFT JOIN `genre` g ON g.`code` = mg.`genreId`
GROUP BY `genre`
I general produce data for your tables, and then start by joing the tables, and see f you get the result you want, if not change the joins to LET Join one by one till you get the result you want, of course you need ro calculate teh avg from 3 or 4 movies

How to pass one query result to another?

Hi guys, Don't focus on the title of question my main question is this. I am bit confused what exactly I should ask.
Define an SQL view Q1(courseid, code) that gives the distinct course id and subject code of any course that is taught by course Tutor (refers to the staff_roles.name). We only consider the courses with the subject code starting with ‘LAWS’, like ‘LAWS1213’. The view should return the following details about each course:
• Courseid should be taken from courses. id field.
• Code should be taken from subjects. Code field.
My Table structures as are as follows.
create table Courses (
id integer, -- PG: serial
subject integer not null references Subjects(id),
semester integer not null references Semesters(id),
homepage URLString,
primary key (id)
);
create table Subjects (
id integer, -- PG: serial
code char(8) not null,
-- PG: check (code ~ '[A-Z]{4}[0-9]{4}'),
name MediumName not null
);
create table Course_staff (
course integer references Courses(id),
staff integer references Staff(id),
role integer references Staff_roles(id),
primary key (course,staff,role)
);
create table Staff_roles (
id integer, -- PG: serial
rtype char(1) references Staff_role_types(id),
rclass char(1) references Staff_role_classes(id),
name LongString not null,
description LongString,
primary key (id)
);
Kindly tell me the query. What query I should write.
I tried this but no luck.
select Courses.id
, Subjects.code
from Courses
, Subjects
, Staff_roles
where ( Courses.subject = Subjects.id
AND Subjects.code like 'LAWS%'
AND Staff_roles.name ='Course Tutor'
);

Trouble with JOINS in mysql

I was working in mySQL and made a fake database for reviews, reviewers and tv series. So I made 3 different tables, one for reviewers, one for reviews and one for the series.
CREATE TABLE reviewers
(
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(150) NOT NULL
);
CREATE TABLE series
(
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
released_year YEAR(4),
genre VARCHAR(50)
);
CREATE TABLE reviews(
id INT AUTO_INCREMENT PRIMARY KEY,
rating DECIMAL(2,1),
series_id INT,
reviewer_id INT,
FOREIGN KEY(series_id) REFERENCES series(id),
FOREIGN KEY(reviewer_id) REFERENCES reviewers(id)
);
The thing that I wanted to ask is, how can I get the highest rating from each reviewer and in which show they gave it?
UPDATE
I came up with this code
SELECT first_name,last_name,title, a.series_id,a.rating FROM
( SELECT series_id,MAX(rating) AS max FROM reviews
GROUP BY series_id ) AS b
INNER JOIN reviews AS a
ON a.series_id=b.series_id AND a.rating=b.max
INNER JOIN reviewers
ON reviewers.id=a.reviewer_id
INNER JOIN series
ON series.id=a.series_id
GROUP BY series_id;
which gives me the max rating in each series and who gave that rating

Joining 2 tables, need to display all fields based on highest price, with no duplicates from a different field

I need to show all fields on the most expensive car of each manufacturer.
The two tables being used are:
CREATE TABLE CARS
(
Vehicle_Identification_Number int(10) NOT NULL UNIQUE,
Manufacturers_ID int(5),
Owner_ID int(10),
Model varchar(25),
Manufaturer_Year int(4),
Mileage int(10),
Price int(10),
PRIMARY KEY (Vehicle_Identification_Number),
FOREIGN KEY (Manufacturers_ID) REFERENCES MANUFACTURERS (Manufacturers_ID),
FOREIGN KEY (Owner_ID) REFERENCES OWNERS (Owner_ID)
)
ENGINE= innodb;
CREATE TABLE MANUFACTURERS
(
Manufacturers_ID int(5) UNIQUE,
Name varchar(15) UNIQUE,
City varchar(30),
State char(2),
Zip char(5),
Phone char(10),
PRIMARY KEY (Manufacturers_ID)
)
ENGINE= innodb;
What I have working so far is:
SELECT *
FROM MANUFACTURERS
LEFT JOIN CARS
ON MANUFACTURERS.Manufacturers_ID = CARS.Manufacturers_ID
UNION
SELECT *
FROM MANUFACTURERS
RIGHT JOIN CARS
ON MANUFACTURERS.Manufacturers_ID = CARS.Manufacturers_ID
ORDER BY Price DESC;
Here is where I am stuck, everything I have tried left me with an error message. Any help would be appreciated.
I'm not sure what you mean by "no duplicates from a different field".
The highest price for each manufacturer is this set. (There might be more than one car at the highest price.)
select Manufacturers_ID, max(Price)
from cars
group by Manufacturers_ID;
Join on both columns in that set. (Second inner join, below.)
select MANUFACTURERS.*, CARS.*
from CARS
inner join MANUFACTURERS
on MANUFACTURERS.Manufacturers_ID = CARS.Manufacturers_ID
inner join (select Manufacturers_ID, max(Price) as Price
from cars
group by Manufacturers_ID) as MOST_EXPENSIVE
on CARS.Manufacturers_ID = MOST_EXPENSIVE.Manufacturers_ID
and CARS.Price = MOST_EXPENSIVE.Price;

How to write an SQL SELECT statement that returns values from multiple tables?

I've got four tables: person, coach, player, games. I need to write an SQL SELECT statement that will return: my id, name, date of birth, join date, the name of the coach with whom I am registered, and the date, time and duration of the game.
The person table consists of: person id, name, date of birth, and some other unnecessary values.
The coach table consists of: coach id, and some other unnecessary values.
The player table consists of: player id, join date, joined with.
The game table consists of: coach id, player id, game date, game time, game duration.
The person table basically stores all the names and main details both of the coach and of the players. The tables are linked correctly.
I've tried various statements but I totally confused myself. The example is kind of lame, I had something else but not really sure how to go about it anymore.
e.g.
SELECT person_id, full_name, date_of_birth, join_date
FROM (person JOIN player ON player_id = person_id)
WHERE person_id='100' AND person_id, full_name
FROM (person JOIN coach ON coach_id = person_id);
These are the CREATE statements:
CREATE TABLE person (
person_id CHAR(10) NOT NULL,
full_name VARCHAR(54) NOT NULL,
date_of_birth DATE,
sex CHAR(1),
PRIMARY KEY (person_id)
) engine innodb;
CREATE TABLE coach (
coach_id CHAR(10) NOT NULL,
phone_no CHAR(10) NOT NULL,
hall_no CHAR(4) NOT NULL,
PRIMARY KEY (coach_id),
FOREIGN KEY (coach_id) REFERENCES person (person_id)
) engine innodb;
CREATE TABLE player (
player_id CHAR(10) NOT NULL,
join_date DATE NOT NULL,
joined_with CHAR(10),
PRIMARY KEY (player_id),
FOREIGN KEY (player_id) REFERENCES person (person_id),
FOREIGN KEY (joined_with) REFERENCES coach (coach_id)
) engine innodb;
CREATE TABLE game (
coach_id CHAR(10) NOT NULL,
player_id CHAR(10) NOT NULL,
game_date DATE NOT NULL,
game_time TIME NOT NULL,
game_duration INTEGER DEFAULT 10,
PRIMARY KEY (coach_id, player_id, game_date, game_time),
FOREIGN KEY (coach_id) REFERENCES coach (coach_id),
FOREIGN KEY (player_id) REFERENCES player (player_id)
) engine innodb;
Your SQL is WAY off. It looks like you're trying for the following just using several INNER JOINs:
SELECT p.person_id, p.full_name, p.date_of_birth, pl.join_date,
c.coach_id, p2.full_name as coach_name, g.*
FROM person p
JOIN player pl ON p.person_id = pl.player_id
JOIN game g ON p.person_id = g.player_id
JOIN coach c ON c.coach_id = g.coach_id
JOIN person p2 on c.coach_id= p2.person_id
WHERE p.person_id='1'
ORDER BY p.person_id, p.full_name
You won't need to rejoin on person a second time if you don't need the coach's name -- I just presumed that would be useful information.
SQL Fiddle Demo
I hope this helps.
SELECT person.person_id, person.full_name, person.date_of_birth, player.join_date
FROM person
INNER JOIN player
ON player.player_id = person.person_id
WHERE person.person_id = '100'