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'
Related
I am provided three tables, one called Person which has an id (primary key) and name attribute, a Movie table with title, year (where title and year together are the primary key) and finally a Saw table which connects the two previous tables and has primary keys, id, title, year, and attribute numStars (rating person gave movie).
So to recap:
Person table:
id
name
Movie table:
title
year
Saw table:
id
title
year
numStars
I'm confused about how to accomplish finding a movie with both a 5 star user rating and a less than 3 star user rating. I'm supposed to do this with both WHERE IN and with a join. Any help would be greatly appreciated.
One solution would be to use aggregation and a having clause:
select
m.title,
m.year
from movie m
inner join saw s
on s.title = m.title
and s.year = m.year
group by m.title, m.year
having
having
sum(numStars = 5) >= 1
and sum(numStars < 3) >= 1
Another option, which avoids the use of aggregation, is to use two exists condition with correlated subqueries:
select
m.title,
m.year
from movie m
where
exists (
select 1
from saw s
where
s.title = m.title
and s.year = m.year
and s.numStars = 5
)
and exists (
select 1
from saw s
where
s.title = m.title
and s.year = m.year
and s.numStars < 3
)
Is there a way in which I can change the way in which I see results of my query?
I'll use an example. I have a table with the id of a market, and then the name of the market, and the sport ID. I want the the sport id to be displayed as a sport name instead.
SELECT id, name, sport_id FROM markets where sport_id = 2;
I was thinking something like:
SELECT * FROM markets where sport_id = 2 as 'Football';
But that didn't work. I don't want to modify the results like an update would, I just want the results to be displayed as football instead of sport_id 2.
Is this possible?
if you do have only one table and like to give Alias then go for Query 1
SELECT id, name, sport_id AS 'sport name' FROM markets where sport_id = 2;
or
if you do have two different tables then Go for it
You need to join with other table as given below
SELECT m.id, m.name, t.sport_name
FROM markets m
JOIN other_Table t ON m.sport_id = t.sport_Id
where m.sport_id = 2;
I hope this might be helpful to solve your Issue.
You can do this with a JOIN to your sports table, something like:
SELECT m.id, m.name, s.sport_name
FROM markets m
JOIN sports s
ON m.sport_id = s.sport_Id
where m.sport_id = 2;
I need to write a SQL query to get the patients that have stayed in ALL the hospitals of the city where they live. In one city there may be several hospitals of course.
So for example, if the patient 'xxx' who lives in Washington has been in a hospital, I need to list him only if he's been in all the hospitals of Washington and no less.
This is the structure of the tables:
table patient
patientID
patientCity
table hospital
hospitalCode
hospitalCity
table hospital_stay
hospitalCode
patientID
cityStay
What's the most efficient way to do this for MySQL? Thank you!
Unfortunately, MySQL can't order before grouping, so I had to use subquery to order the result correctly before grouping it.
Have fun :)
SELECT * FROM (
SELECT
p.patientID,
hs.hospitalCode
FROM
patient p
INNER JOIN hospital h ON (p.patientCity = h.hospitalCity)
LEFT JOIN hospital_stay hs ON (p.patientID = hs.patientID AND h.hospitalCode = hs.hospitalCode)
ORDER BY 2
) AS tmp_table
GROUP BY 1
HAVING NOT ISNULL(hospitalCode)
This query should work :
Select p.patientID
, p.patientCity
from patient p
inner join hospital h on h.hospitalCity = p.patientCity
inner join hospital_stay hs on hs.hospitalCode = h.hospitalCode
--where hs.cityStay = 1
group by p.patientID, p.patientCity
having count(*) = (select count(*) from hospital
where hospitalCity = p.patientCity);
Remove the comment if cityStay is kind of a flag that says that the patient went to the hospital.
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)
I have two queries that I want to join together, but I don't know how to.
Select father, mother, guardian from students where user_id = '201209291';
I get a result of 3 IDs.
Now, I need to use those three IDs to get their personal information;
Select * from system_users where user_id = (The 3 IDs from the previous query);
How would i go about solving this problem? I thought of the result of the first query into 3 rows, but I don't know how to do that either.
Select * from system_users where user_id IN
(
Select father from students where user_id = '201209291'
UNION
Select mother from students where user_id = '201209291'
UNION
Select guardian from students where user_id = '201209291'
)
Well, you can join directly using a series of ORs in the join predicate, as long as the father, mother, and guardian columns are actually user_ids in system_users.
select usrs.*
from students s
join system_users usrs on
s.father=usrs.user_id OR
s.mother=usrs.user_id OR
s.guardian=usrs.user_id
where s.user_id = '201209291';
Why don't you use join?
Select father, mother, guardian from students as s
join system_users usrs
on s.user_id=usrs.user_id
where s.user_id = '201209291';
From the first query you will have not IDs but 3 columns.
Select father, mother, guardian from students where user_id = '201209291'.
Probably you mean
Select distinct some_id from students where user_id = '201209291'
I suggest simple:
Select * from system_users where user_id in (Select distinct some_id from students where user_id = '201209291');
Did I understand the question correctly?