我应该如何在Oracle中加入这3个SQL查询?

时间:2011-01-03 15:28:24

标签: sql oracle join

我有这三个查询:

SELECT
  title, year, MovieGenres(m.mid) genres,
  MovieDirectors(m.mid) directors, MovieWriters(m.mid) writers,
  synopsis, poster_url
FROM movies m
WHERE m.mid = 1;

SELECT AVG(rating) FROM movie_ratings WHERE mid = 1;

SELECT COUNT(rating) FROM movie_ratings WHERE mid = 1;

我需要将它们加入到单个查询中。我能够这样做:

SELECT
  title, year, MovieGenres(m.mid) genres,
  MovieDirectors(m.mid) directors, MovieWriters(m.mid) writers,
  synopsis, poster_url, AVG(rating) average, COUNT(rating) count
FROM movies m INNER JOIN movie_ratings mr
  ON m.mid = mr.mid
WHERE m.mid = 1
GROUP BY
  title, year, MovieGenres(m.mid), MovieDirectors(m.mid),
  MovieWriters(m.mid), synopsis, poster_url;

但我真的不喜欢那个“巨大的”GROUP BY,有没有更简单的方法呢?

3 个答案:

答案 0 :(得分:5)

你可以这样做:

SELECT title
      ,year
      ,MovieGenres(m.mid) genres
      ,MovieDirectors(m.mid) directors
      ,MovieWriters(m.mid) writers
      ,synopsis
      ,poster_url
      ,(select avg(mr.rating) 
         from movie_ratings mr 
        where mr.mid = m.mid) as avg_rating
      ,(select count(rating)  
         from movie_ratings mr 
        where mr.mid = m.mid) as num_ratings
  FROM movies m
 WHERE m.mid = 1;

甚至

with grouped as(
   select avg(rating)   as avg_rating 
         ,count(rating) as num_ratings
     from movie_ratings 
    where mid = 1
)
select title
      ,year
      ,MovieGenres(m.mid) genres
      ,MovieDirectors(m.mid) directors
      ,MovieWriters(m.mid) writers
      ,synopsis
      ,poster_url
      ,avg_rating
      ,num_ratings
  from movies m cross join grouped
 where m.mid = 1;

答案 1 :(得分:2)

我想我没有看到有几个GroupBy列的问题。这是SQL中非常常见的模式。当然,代码清晰度通常在旁观者眼中。

检查这两种方法的解释计划;我猜你的原始版本会有更好的表现,因为它只需要处理一次movie_ratings表。但我没有检查过,这将取决于数据和安装。

答案 2 :(得分:0)

怎么样

SELECT
  title, year, MovieGenres(m.mid) genres,
  MovieDirectors(m.mid) directors, MovieWriters(m.mid) writers,
  synopsis, poster_url,
  (SELECT AVG(rating) FROM movie_ratings WHERE mid = 1) av,
  (SELECT COUNT(rating) FROM movie_ratings WHERE mid = 1) cnt 
FROM movies m
WHERE m.mid = 1;

SELECT
  title, year, MovieGenres(m.mid) genres,
  MovieDirectors(m.mid) directors, MovieWriters(m.mid) writers,
  synopsis, poster_url,
  av.av,
  cnt.cnt 
FROM movies m,
  (SELECT AVG(rating) av FROM movie_ratings WHERE mid = 1) av,
  (SELECT COUNT(rating) cnt FROM movie_ratings WHERE mid = 1) cnt 
WHERE m.mid = 1;