0

我正在研究 SQL,但似乎找不到这个练习的答案。

练习:对于同一评论者对同一部电影两次评分并且第二次给它更高评分的所有情况,返回评论者的姓名和电影的标题。

我不知道如何比较 2 行然后获得更高的评分。

表的模式是:

  • 电影 ( mID, title, year, director ) 英文:有一部电影,ID号为mID,有片名,上映年份,导演。
  • Reviewer ( rID, name ) 英文:ID号为rID的reviewer有一定的名字。
  • 评分 ( rID, mID, stars, ratingDate ) 英文:评论者 rID 在某个 ratingDate 给电影 mIDa 星级评分 (1-5)。*

就这一点而言,我在论坛中进行了研究:

select *
from rating a
join Reviewer rv on rv.rid = a.rid
where 1 < (select COUNT(*) from rating b
            where b.rid = a.rid and b.mid = a.mid)

我很高兴也能得到代码的解释。因为即使是上面的代码也让我很困惑。

/* 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

3 回答 3

3

类似的东西应该有效(它们也是其他方式)

SELECT rev.name, m.title
FROM Reviewer rev
INNER JOIN Rating r1 on r1.rID = rev.rID
INNER JOIN Rating r2 on r2.rID = rev.rID and r2.mID = r1.mID
INNER JOIN Movie m on m.mID = r1.mID
WHERE r2.ratingDate > r1.ratingDate and r2.stars > r1.stars 

或者在这种情况下,您可以在 join 中执行所有操作(而不是 WHERE 子句)

SELECT rev.name, m.title
FROM Reviewer rev
INNER JOIN Rating r1 on r1.rID = rev.rID
INNER JOIN Rating r2 
  on r2.rID = rev.rID 
  and r2.mID = r1.mID
  and r2.ratingDate > r1.ratingDate
  and r2.stars > r1.stars
INNER JOIN Movie m on m.mID = r1.mID

SqlFiddle(带有您的示例数据)

解释:我想你知道 JOIN 语法,所以

诀窍是两次加入Rating。然后 WHERE 部分检查是否存在一条线,其中一个评级(来自同一部电影的同一评论者)具有更大的 ratingDate 和更多的星星。检查:“第二次给它更高的评价”。

然后我们只按评论者姓名和电影标题分组(这部分是为了避免重复,如果我们有 3 个评论,第二个比第一个多,第三个比第二个多):使用您的示例数据,GROUP BY 不是需要,但是...

于 2013-02-02T17:11:34.553 回答
0

首先让所有审查过两次的审查员开始:

select rid
from rating r
group by rid
having count(*) = 2

现在的问题是:它们是相同的还是第二个更大?为此,请重新加入评级,但还包括两个日期:

from (select rid, min(ratingdate) as minratingdate, max(ratingdate) as maxratingdate
      from rating r
      group by rid
      having count(*) = 2
     ) twotimes join
     rating r1
     on r1.rid = twotimes.rid and r1.ratingdate = twotimes.minratingdate join
     rating r2
     on r2.rid = twotimes.rid and r2.ratingdate = twotimes.maxratingdate

这带来了关于这两个评论的信息。您可以从这里完成查询。

于 2013-02-02T17:13:03.263 回答
0

您可以使用GROUP BYHAVING

SELECT m.mId, m.Title, r.Name, ra.stars
FROM Movie m 
   JOIN (SELECT mId, rId, MAX(stars) stars
        FROM Rating 
        GROUP BY mId, rId
        HAVING COUNT(*) > 1) ra ON m.mId = ra.mId
   JOIN Reviewer r ON ra.rId = r.rId
GROUP BY m.mId, m.Title, r.Name, ra.stars

这将为您返回任何具有来自同一评论者的多个评论且星数最多的电影。

这是用于测试的SQL Fiddle 。

祝你好运。

于 2013-02-02T17:16:52.303 回答