【问题标题】:a SQL multi-match join from Stanford open course斯坦福公开课程的 SQL 多匹配连接
【发布时间】:2014-10-04 07:27:50
【问题描述】:

您创建了一个新的电影评分网站,并且一直在收集评论者对各种电影的评分数据。目前还没有太多数据,但您仍然可以尝试一些有趣的查询。这是架构:

电影(mID、片名、年份、导演) Chinese: 有一部电影,ID号为mID、片名、上映年份和导演。

审稿人(rID,姓名) 中文:ID号为rID的审稿人有一定的名字。

评分(rID、mID、星数、ratingDate) 中文: 评论者 rID 在某个 ratingDate 给电影 mID 打了几颗星 (1-5)。

问题: 对于每位导演,返回导演的姓名以及他们执导的在所有电影中获得最高评分的电影的名称,以及该评分的值。忽略导演为 NULL 的电影。

注意:您的查询是使用 SQLite 执行的,因此您必须符合 SQLite 支持的 SQL 结构。

我的理解: 每个导演可能有多部电影,每部电影由不同的评论家评分。这里的最高评分确实是最高的平均评分。我认为这个 SQL 应该携带多个子查询或连接,并且在我 5 次尝试后系统接受了它,并且花费了 10 多分钟。如果这是来自 Google 或 Facebook 的面试问题,我会失败的。任何人都可以给出一个优雅而简洁的解决方案吗?

我确实在网上搜索了解决方案,发现很多错误的解决方案,虽然它们可以通过系统小数据检查。比如下面的 SQL 确实是不正确的。

select title, max(stars) as max_star, director
from Movie, Rating
where Movie.mID = Rating.mID and director is not NULL
group by director;

我的解决方案如下,如果有人可以提供更优雅但逻辑正确的解决方案,请告诉我。谢谢

select Q2.director, title, maxStar from Movie m join
(select director, mID, max(stars) as maxStar from
(select director, mID, stars
from Movie m join Rating r using(mID)
where director NOT NULL
group by mID ) Q1
group by director ) Q2
on m.mID = Q2.mID;

【问题讨论】:

    标签: mysql join subquery


    【解决方案1】:

    试试下面:

    Select Movie.title,
           MAX(A.rate),
           Movie.director (Select  rID, mID, AVG(stars) as rate, ratingDate 
                           From Rating Group By mID
                           ) A 
           Inner Join Movie on A.mID=Movie.mID  
    where Movie.director is not NULL
    group by Movie.director;
    

    【讨论】:

      【解决方案2】:
      SELECT DISTINCT m.director, m.title, r.stars 
      FROM movie m
      JOIN rating r USING(mid)
      JOIN (SELECT director, max(stars) AS rate
             FROM movie
             JOIN rating USING(mid)
             WHERE director IS NOT NULL
             GROUP BY director) q
      ON q.director=m.director AND r.stars=q.rate
      ORDER BY m.director
      

      我不是专家,但这个查询对我有用。而且我认为这很容易理解。首先,我查询评分最高的导演,然后使用内部查询作为过滤器编写主查询。

      【讨论】:

        【解决方案3】:
        select t.director, t.title, t.stars, t.ratingdate, t.rankmy 
        from (
        select m.director, m.title, rt.stars, rt.ratingdate, row_number() over( partition by m.director order by rt.stars desc) rankmy
        from movie m inner join rating rt on m.mid = rt.mid 
        where m.director is not null ) T
        where t.rankmy = 1
        

        【讨论】:

          【解决方案4】:
          select distinct q.director,title,stars
          from (select director,max(stars) as b
              from Movie natural join rating
              where director is not null
              group by director) q,
              (select * from Movie natural join rating ) w
          where q.director=w.director and q.b=w.stars
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-20
            • 2019-03-17
            • 2016-10-20
            • 1970-01-01
            • 2014-04-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多