mysql implicit join+ subquery - mysql

I'm meant to use an implicit join to get all the movies with angelina jolie as director or were she stars here's what I have so far
SELECT DISTINCT title, relYear
FROM actor,movie
WHERE director ='Angelina Jolie' OR aID in (SELECT aID
FROM actor
WHERE fName='Angelina' and surname='Jolie'
Here are the relevant tables
movie(id, title, relYear, category, runTime, director,
studioName, description, rating)
actor(aID, fName, surname, gender)
stars(movieID, actorID)
movGenre(movieID, genre)
This returns all of the movies , I think that's because of aID in (SELECT aID
I don't know how to do this without using explicit join on three tables is the subquery even the most efficient approach ? Thanks

This is what I would do on MSSQL. Think it should work on MySql.
Select title, relYear FROM movie WHERE director = 'Angelina Jolie' OR id IN
(SELECT movieId FROM stars inner join actor ON stars.actorId = actor.aID WHERE
actor.fName = 'Angelina' AND surname = 'Jolie')

Related

SQL queries when two or more tables to be joined

IMDB database has the following tables
actors(id, first_name, last_name, gender)
directors(id, first_name,last_name)
directors_genres(director_id, genre, prob)
movies(id, name,year, rank)
movies_directors(director_id, movie_id)
roles(actor_id,movie_id, role)
movies_genres(movie_id, genre)
a) Write a query that lists the female actors who appeared in a movie during the 90s (1990-1999) that was rated higher than 8.5.
b) Write a query that lists all actors who was in a movie rated lower than 3.0 two or more times. List the name of the actor, the movie and each rating, ordered ascending by the actors’ last name then first name.
c) Write a query that lists all actors who have been in two or more movies of different genres. List their name, movie and their respective genres.
My answers:
a)
SELECT actors.firstname
from ((roles inner join movies on roles.mid=movies.id)
inner join actors on actors.id=roles.aid)
where (movies.year between 1990 and 1999)
and
(movies.rank >= 8.5)
. is it correct ?
and can anyone help how to approach other queries. Thanks in advance
You forget gender, and higher than 8.5 (not higher than or equals).
SELECT actors.firstname
from roles inner join movies on roles.movie_id = movies.id
inner join actors on actors.id=roles.aid
where movies.year between 1990 and 1999
and movies.rank > 8.5
and actors.gender = 'F';
P.S. Is this your school work?
SELECT
first_name, last_name
FROM actors
JOIN
movies ON actors.id=movies.id
WHERE movies.gender='female'and movies.rank>8.5 AND movies.year
BETWEEN
1990-1999
Add role to actors table
actors(id, first_name, last_name, gender,role)
movies(id, name,year, rank)
One more variant:
SELECT actors.firstname FROM actors WHERE id IN(
SELECT actors_id FROM roles WHERE movies_id IN(
SELECT id FROM movies WHERE (movies.year BETWEEN 1990 and 1999)
and (movies.rank >=8)));

having trouble with sql about movie theme

Movie(mID int, title text, year int, director text);
Reviewer(rID int, name text);
Rating(rID int, mID int, stars int, ratingDate date);
For each director, return the director's name together with the title(s) of the movie(s) they directed that received the highest rating among all of their movies, and the value of that rating. Ignore movies whose director is NULL.
I am stuck at highest rating part.
select title, director
from Movie natural join Rating
where director is not NULL
i know i just couldn't really write it.
select distinct director, title, stars
from (movie join rating using (mid)) m
where stars in (select max(stars)
from rating join movie using (mid)
where m.director = director);
Here's one option using a subquery with the max aggregate:
select m.title, m.director, r.stars
from movie m
join rating r on m.mid = r.mid
join (select director, max(stars) maxstars
from rating join movie on rating.mid = movie.mid
group by director) maxr on m.director = maxr.director
and r.stars = maxr.maxstars
where m.director is not null
SQL Fiddle Demo
Edited when I realized you need to group by director instead of movie to get the max(stars) per director.

How do I find the directors for the movies directly?

So I have three separate tables labeled directors, studios, and movie.
Directors columns: id, name, dob, nationality, gender.
Studios columns: id, name, founding date, and director_id
(Foreign Key is director_id)
Movies: ID, name, length, studio_id (foreign key is studios_id)
I have to find all the directors who directed movies with the name awakening but I have no idea how to use foreign keys properly. Best I've come up with was
SELECT name, studio_id FROM studios WHERE name = "awakening"
I have no idea what I'm doing. Please help.
Please try to use INNER JOIN on your query
SELECT d.id, d.name FROM director d INNER JOIN studios s ON d.id = s.director_id INNER JOIN movie m ON s.id = m.studio_id WHERE m.name = "awakening";
SELECT Movies.name as movie_name, Directors.name as director_name
FROM Movies
JOIN Studios ON (Movies.studio_id = Studios.id)
JOIN Directors ON (Studios.director_id = Directors.id)
WHERE Movies.name = 'awakening';

MYSQL, Max,Group by and Max

I am having the following two table.
1.Movie Detail (Movie-ID,Movie_Name,Rating,Votes,Year)
2.Movie Genre (Movie-ID,Genre)
I am using the following query to perform join and get the movie with highest rating in each
genre.
select Movie_Name,
max(Rating) as Rating,
Genre from movie_test
inner join movie_genre
where movie_test.Movie_ID = movie_genre.Movie_ID
group by Genre
In the output Rating and Genre are correct but the Movie_Name is incorrect.
can anyone suggest what changes I should make to get the correct movie name along with rating and genre.
SELECT g.*, d.*
FROM MovieGenre g
INNER JOIN MovieDetail d
ON g.MovieID = d.MovieID
INNER JOIN
(
SELECT a.Genre, MAX(b.Rating) maxRating
FROM MovieGenre a
INNER JOIN MovieDetail b
ON a.MovieID = b.MovieID
GROUP BY a.Genre
) sub ON g.Genre = sub.Genre AND
d.rating = sub.maxRating
There is something wrong with your schema design. If a Movie can have many Genre as well as Genre can be contain on many Movie, it should be a three table design.
MovieDetails Table
MovieID (PK)
MovieName
MovieRating
Genre Table
GenreID (PK)
GenreName
Movie_Genre Table
MovieID (FK) -- compound primary key with GenreID
GenreID (FK)
This is a common MySQL problem - specifying non-aggregate/non-aggregated-by columns in an aggregate query. Other flavours of SQL do not let you do this and will warn you.
When you do a query like yours, you are selecting non-aggregate columns in an aggregated group. Since many rows share the same genre, when you select Movie_Name it picks one row at random from each group and displays that one, because there is no general algorithm to guess the row you want and return the values of that.
You might ask 'why does it pick randomly? It could pick the one that max(Rating) belongs to?' but what about other aggregate columns, like avg(Rating)? What row does it pick there? What if two rows have the same max, anyway? Therefore it cannot have an algorithm to pick a row.
To solve a problem like this, you have to restructure your query, something like:
select Movie_Name,
Rating,
Genre from movie_test mt
inner join movie_genre
where movie_test.Movie_ID = movie_genre.Movie_ID
and Rating = (select max(Rating) from movie_test mt2 where mt.Genre = mt2.Genre
group by Genre
limit 1
This will select the row with the rating being the same as the maximum rating for that genre, using a subquery.
Query:
SELECT t.Movie_Name,
t.Rating,
g.Genre
FROM movie_test t
INNER JOIN movie_genre g ON t.Movie_ID = g.Movie_ID
WHERE t.Movie_ID = (SELECT t1.Movie_ID
FROM movie_test t1
INNER JOIN movie_genre g1 ON t1.Movie_ID = g1.Movie_ID
WHERE g1.Genre = g.Genre
ORDER BY t1.Rating DESC
LIMIT 1)

MySQL query on single table to find multiple rows

I am trying to figure out a way to find shared credits by two people in a movie database, for example:
table: 'credits'
columns: 'id','movie','person'
My other problem is a person might have multiple credits for the same movie, so how do I filter out duplicates? Any help would be appreciated. The following is what I have so far. Am I on the right track?
SELECT DISTINCT movie
FROM credits
WHERE person = 'condition1' OR person = 'condition2'
GROUP BY movie
HAVING COUNT(*)=2
SELECT DISTINCT c1.movie
FROM credits AS c1
JOIN credits AS c2 on (c1.movie = c2.movie)
WHERE c1.person = 'john'
AND c2.person = 'kate'
This should work:
SELECT DISTINCT movie
FROM (
SELECT movie, COUNT(person) AS contributors
FROM credits
WHERE person IN('person1','person2')
GROUP BY movie, person
HAVING contributors>1
) t1
select distinct cr1.movie
from credits as cr1
join credits as cr2
using (movie)
where cr1.person = {person 1 goes here}
and cr2.person = {person 2 goes here}
You no need this HAVING COUNT(*)=2. It gives you only movies with two matches (one person with two credits or with both condition1 and condition2). More than that - you no need group by at all when you using distinct (in this case).
SELECT DISTINCT movie
FROM credits
WHERE person = 'condition1' OR person = 'condition2'