snippetMinor
How do I go about creating this SQL query?
Viewed 0 times
thiscreatingsqlqueryabouthow
Problem
I'm attending the free DB course at Stanford Online, and frankly one of the exercises gave me some trouble. I have a feeling that this should be horribly simple, so for a DBA, I'm obviously not very good with SQL.
We're working with a simplified scenario for rating movies.
For all cases where the same reviewer rated the same movie twice and gave it a higher rating the second time, return the reviewer's name and the title of the movie.
Here's the schema:
How should I go about this?
We're working with a simplified scenario for rating movies.
For all cases where the same reviewer rated the same movie twice and gave it a higher rating the second time, return the reviewer's name and the title of the movie.
Here's the schema:
Movie ( mID, title, year, director )
Reviewer ( rID, name )
Rating ( rID, mID, stars, ratingDate )How should I go about this?
Solution
You can self join to tables for this sort of criteria(at least, I can do this in SQL Server):
Note that we're joing rating back to itself. This way we can use the WHERE clause to find rows in
You can review the full example I built in SQL Fiddle here.
If you want to add the condition that the reviewer made exactly these 2 reviews of the movie and no more, you can add:
This assumes that the
SELECT
r.name,
m.title
FROM
rating rt
JOIN movie m ON (rt.mid = m.mid)
JOIN reviewer r on (rt.rid = r.rid)
JOIN rating rt2 on (rt.mid = rt2.mid and rt.rid = rt2.rid)
WHERE
rt.ratingDate > rt2.ratingDate
AND rt.stars > rt2.stars;Note that we're joing rating back to itself. This way we can use the WHERE clause to find rows in
rating that are greater in both date and stars to other rows in rating.You can review the full example I built in SQL Fiddle here.
If you want to add the condition that the reviewer made exactly these 2 reviews of the movie and no more, you can add:
AND NOT EXISTS --- not exists
( SELECT *
FROM rating rt3 --- another rating
WHERE rt3.mid = m.mid --- for same movie
AND rt3.rid = r.rid --- by same reviewer
AND rt3.ratingDate <> rt2.ratingDate --- on different date
AND rt3.ratingDate <> rt1.ratingDate --- than the first 2 reviews
)This assumes that the
Rating table has (rID, mID, ratingDate) as primary key.Code Snippets
SELECT
r.name,
m.title
FROM
rating rt
JOIN movie m ON (rt.mid = m.mid)
JOIN reviewer r on (rt.rid = r.rid)
JOIN rating rt2 on (rt.mid = rt2.mid and rt.rid = rt2.rid)
WHERE
rt.ratingDate > rt2.ratingDate
AND rt.stars > rt2.stars;AND NOT EXISTS --- not exists
( SELECT *
FROM rating rt3 --- another rating
WHERE rt3.mid = m.mid --- for same movie
AND rt3.rid = r.rid --- by same reviewer
AND rt3.ratingDate <> rt2.ratingDate --- on different date
AND rt3.ratingDate <> rt1.ratingDate --- than the first 2 reviews
)Context
StackExchange Database Administrators Q#33357, answer score: 4
Revisions (0)
No revisions yet.