Как получить результаты этого конкретного «запроса» - PullRequest
4 голосов
/ 14 марта 2012

ПРИМЕЧАНИЕ. Я случайно поместил здесь предложение другого вопроса (с огромными извинениями с моей стороны), я обновил этот пост по состоянию на среду 14 марта в 23:21, добавив правильный вопрос.

Я потратил несколько часов, пытаясь выяснить этот вопрос без чьей-либо помощи, но понял, что потратил слишком много продуктивного времени и должен был спросить кого-то раньше. У меня была приличная трещина в этом, и я подошел так близко, но не могу найти нужного мне окончательного решения. То, что я должен получить это:

Для всех случаев, когда один и тот же рецензент оценивал один и тот же фильм дважды и дал ему более высокий рейтинг во второй раз, верните имя рецензента и название фильма.

Это запрос, который мне удалось получить здесь:

SELECT reviewer.name, movie.title, rating.stars  
FROM (reviewer JOIN rating ON reviewer.rid = rating.rid)  
JOIN movie ON movie.mid = rating.mid  
GROUP BY reviewer.name 
HAVING COUNT(*) >= 2  
ORDER BY reviewer.name DESC

(У меня такое ощущение, что в приведенном выше запросе отсутствует предложение WHERE, но я не уверен, где его разместить)

(Из того, что я узнал, RIGHT и FULL OUTER JOIN в настоящее время не поддерживаются в SQLite)

А вот таблицы и данные (на рисунках) ...

Movie

Reviewer

Rating

... и код БД ...

/* Delete the tables if they already exist */
drop table if exists Movie;
drop table if exists Reviewer;
drop table if exists Rating;

/* Create the schema for our tables */
create table Movie(mID int, title text, year int, director text);
create table Reviewer(rID int, name text);
create table Rating(rID int, mID int, stars int, ratingDate date);

/* Populate the tables with our data */
insert into Movie values(101, 'Gone with the Wind', 1939, 'Victor Fleming');
insert into Movie values(102, 'Star Wars', 1977, 'George Lucas');
insert into Movie values(103, 'The Sound of Music', 1965, 'Robert Wise');
insert into Movie values(104, 'E.T.', 1982, 'Steven Spielberg');
insert into Movie values(105, 'Titanic', 1997, 'James Cameron');
insert into Movie values(106, 'Snow White', 1937, null);
insert into Movie values(107, 'Avatar', 2009, 'James Cameron');
insert into Movie values(108, 'Raiders of the Lost Ark', 1981, 'Steven Spielberg');

insert into Reviewer values(201, 'Sarah Martinez');
insert into Reviewer values(202, 'Daniel Lewis');
insert into Reviewer values(203, 'Brittany Harris');
insert into Reviewer values(204, 'Mike Anderson');
insert into Reviewer values(205, 'Chris Jackson');
insert into Reviewer values(206, 'Elizabeth Thomas');
insert into Reviewer values(207, 'James Cameron');
insert into Reviewer values(208, 'Ashley White');

insert into Rating values(201, 101, 2, '2011-01-22');
insert into Rating values(201, 101, 4, '2011-01-27');
insert into Rating values(202, 106, 4, null);
insert into Rating values(203, 103, 2, '2011-01-20');
insert into Rating values(203, 108, 4, '2011-01-12');
insert into Rating values(203, 108, 2, '2011-01-30');
insert into Rating values(204, 101, 3, '2011-01-09');
insert into Rating values(205, 103, 3, '2011-01-27');
insert into Rating values(205, 104, 2, '2011-01-22');
insert into Rating values(205, 108, 4, null);
insert into Rating values(206, 107, 3, '2011-01-15');
insert into Rating values(206, 106, 5, '2011-01-19');
insert into Rating values(207, 107, 5, '2011-01-20');
insert into Rating values(208, 104, 3, '2011-01-02');

У меня есть еще один относительно похожий вопрос, подобный этому, но если я получу некоторую помощь по этому вопросу, я смогу применить шаблоны и приемы от этого к следующему.

Заранее спасибо! :)

Ответы [ 4 ]

5 голосов
/ 14 марта 2012

Я добавил внутреннее соединение с производной таблицей, которая возвращает максимальное количество звезд за фильм. Из-за внутреннего соединения между фильмами и рейтингами будут извлечены только фильмы с оценками. Присоединяйтесь к основному запросу, чтобы получить максимальное количество звезд за фильм.

Примечание. Вы указали, что хотите упорядочить по названию фильма, но заказы по запросу рецензента.

SELECT reviewer.name, movie.title, rating.stars, maxStarsPerMovie.MaxStars
FROM (reviewer JOIN rating ON reviewer.rid = rating.rid)  
JOIN movie ON movie.mid = rating.mid  
join
(
   select movie.mid, max(rating.stars) MaxStars
   from movie
   inner join rating
      on movie.mid = rating.mid
   group by movie.mid
) maxStarsPerMovie
on movie.mid = maxStarsPerMovie.mid
ORDER BY reviewer.name DESC

РЕДАКТИРОВАТЬ: требование изменено. Этот запрос вернет список рецензентов, которые позднее изменили свое мнение в пользу фильма. Это делается путем повторного присоединения к рейтингу с добавлением двух фильтров по звездам и дате присоединения.

SELECT reviewer.name, movie.title, rating.ratingDate, rating.stars,
       newRating.ratingDate newRatingDate, newRating.Stars newRatingStars
FROM (reviewer JOIN rating ON reviewer.rid = rating.rid)  
JOIN movie ON movie.mid = rating.mid 
inner join rating newRating
     on newRating.mid = movie.mid
        and newRating.rid = reviewer.rid
        and newRating.ratingdate > rating.ratingdate
        and newRating.stars > rating.stars
ORDER BY reviewer.name, movie.title
2 голосов
/ 14 марта 2012

Из описания требования:

Вернуть название фильма и количество звезд (отсортировано по названию фильма) Для каждого фильма, который имеет хотя бы один рейтинг, и найти наибольшее количество звездэтот фильм получен.

Сведения о рецензенте не требуются - только фильм и максимальное количество звезд.

Поэтому я предлагаю:

SELECT movie.mid, MAX(movie.title) as title, MAX(rating.stars) as max_stars
FROM rating 
JOIN movie ON movie.mid = rating.mid  
GROUP BY movie.mid 
ORDER BY 2, 1
0 голосов
/ 21 марта 2017

Я бы предложил использовать Self Join в подзапросе, чтобы идентифицировать рецензента, а затем использовать результат, чтобы получить имя рецензента и название фильма.

SELECT name, title FROM Reviewer R join (SELECT Ra.mID as mID, Ra.rID as rID FROM Rating Ra JOIN Rating Rb ON Ra.mID=Rb.mID WHERE Ra.rID=Rb.rID  AND Ra.ratingDate<Rb.ratingDate AND Ra.stars<Rb.stars) AS Tmp ON R.rID=Tmp.rID JOIN Movie M ON M.mID=Tmp.mID
0 голосов
/ 09 ноября 2014

Вы, вероятно, делали это для мини-курса Стэнфорда по SQL, как я только что сделал.Вот что я получил за ответ (до просмотра лекций у меня не было опыта работы с SQL, так что, надеюсь, это не так уж страшно):

Начните с запроса, который находит каждый rID для рецензента, который оценилфильм дважды, и во второй раз он получил более высокий балл:

 select R1.rID from Rating R1, Rating R2 where R1.mID = R2.mID and R1.rID = R2.rID
        and R1.ratingDate < R2.ratingDate and R2.stars > R1.stars;

воспринимайте R1 как первую оценку определенного фильма конкретным рецензентом, а R2 - как второй.Нам нужно поговорить о двух рецензиях на один и тот же фильм одного и того же человека, следовательно, R1.mID = R2.mID и R1.rID = R2.rID.Затем, чтобы убедиться, что R1 действительно был первым, в хронологическом порядке мы устанавливаем R1.ratingDate R1.stars.

Вы можете проверить, что это дает нам МПОГ 201, который является правильным ответом (можно проверить, проверив данные).Теперь нам нужно отобразить имя и заголовок рецензента фильма вместо идентификатора RID.

Я сделал это путем перекрестного произведения всех трех отношений (я полагаю, использование объединений будет чище?), Удаление дубликатов и использованиезапрос, указанный выше как подзапрос предложения where:

 select distinct name, title
 from Movie, Reviewer, Rating
 where Movie.mID = Rating.mID and Reviewer.rID = Rating.rID and Rating.rID in (select R1.rID from          
 Rating R1, Rating R2 where R1.mID =R2.mID and R1.rID = R2.rID and R1.ratingDate < R2.ratingDate
 and R2.stars > R1.stars);

В предложении where я только что превратил перекрестные продукты в естественные объединения, установив равные соответствующие mID и rID, и удостоверившись, что rID (называемый Rating.rID для устранения неоднозначности) были определены первоначальным запросом, который я написал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...