SQL - 比较两行和两列

时间:2013-02-02 17:01:15

标签: sql compare rows

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

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

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

表的模式是:

  • 电影(mID,标题,年份,导演) 英语:有一部ID号为mID,标题,发行的电影 一年,还有一位导演。
  • 审稿人(rID,姓名) 中文:身份证号码为rID的审稿人有一定的名称。
  • 评级(rID,mID,星级,评级日期) 中文:评论家rID在某个评级日期给予电影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');

3 个答案:

答案 0 :(得分: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 

或者你可以在这种情况下加入(而不是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语法,所以

诀窍是加入评级两次。 然后WHERE部分检查是否存在其中一个评级(来自同一电影上的同一评论者)具有更大评级日期和更多星级的行。哪个检查:&#34;第二次给予它更高的评价&#34;。

然后我们按照reviewerName和电影标题进行分组(这部分是为了避免重复,如果我们有3个评论,第二个比第一个有更多的星,第三个比第二个更多):使用您的样本数据,GROUP BY不是必需的,但是......

答案 1 :(得分: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

这会带来有关这两个评论的信息。您可以从此处完成查询。

答案 2 :(得分: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

祝你好运。