4

好的,我在这里有这段代码:

SELECT MOVIETITLE AS "Movie Title", MIN(AVG(RATING)) AS "Lowest Average Rating"
FROM MOVIE, RATING
WHERE MOVIE.MOVIEID = RATING.MOVIEID
GROUP BY MOVIETITLE;

我需要从我的评级表中调整最低平均评级,所以我使用了聚合函数

MIN(AVG(RATING))

我不断收到此错误,但我无法弄清楚如何解决它:

ORA-00937: not a single-group group function

我是 SQL 和 Oracle 的新手,所以这对我来说都是全新的......

编辑

好吧,澄清一下,评分表中有多个人对同一部电影进行评分,基本上需要获取每部电影的所有评分的平均值,并列出平均值最低的电影

4

6 回答 6

3

还有一个SQL Fiddle

select min(rating)
from (select m.movietitle, avg(r.rating) as rating
      from movie m, rating r
      where m.movieid = r.movieid
      group by m.movietitle) t;
于 2012-11-19T08:31:48.367 回答
2

你不能这样做,尝试在子查询中添加它

SELECT MOVIETITLE AS "Movie Title", AVG(RATING) AS "AVGRating"
FROM MOVIE, RATING
WHERE MOVIE.MOVIEID = RATING.MOVIEID
GROUP BY MOVIETITLE
HAVING AVG(RATING) =
(
    SELECT MIN(AVG(RATING)) AS "AVGRating"
    FROM MOVIE, RATING
    WHERE MOVIE.MOVIEID = RATING.MOVIEID
    GROUP BY MOVIETITLE
)
于 2012-11-19T08:25:49.377 回答
2

另一种方法(如果有几部电影具有相同的最低评分,它们都将被显示):

-- sample of data just for the sake of demonstration
SQL> with movie as(
  2     select 1  as movieid , 'Departed' as movietitle from dual union all
  3     select 2, 'Shutter Island' from dual union all
  4     select 3, 'Terminator'     from dual
  5  ),
  6  rating as(
  7    select 1  as movieid, 7 as rating from dual union all
  8    select 1, 8 from dual union all
  9    select 1, 9 from dual union all
 10    select 1, 6 from dual union all
 11    select 1, 7 from dual union all
 12    select 2, 9 from dual union all
 13    select 2, 5 from dual union all
 14    select 2, 6 from dual union all
 15    select 3, 6 from dual union all
 16    select 3, 5 from dual union all
 17    select 3, 6 from dual
 18  ) -- the query
 19   select w.movietitle     as "Movie Title"
 20        , round(w.mavr, 1) as "Lowest Average Rating"
 21     from ( select movietitle
 22                 , min(avg(rating)) over() as mavr
 23                 , avg(rating) as avr
 24              from movie
 25                 , rating
 26             where movie.movieid = rating.movieid
 27             group by movietitle
 28          ) w
 29    where w.mavr = w.avr
 30  ;

结果:

Movie Title    Lowest Average Rating
-------------- ---------------------
Terminator                       5,7
于 2012-11-19T09:07:28.953 回答
2

如果有一种标准方法可以在聚合中包含附加值,那就太好了。我发现自己将许多值组合成一个 RAW 值,将其聚合,然后从聚合中提取原始值:

/* lowest returns a single row */
with lowest as (
  select min(
  /* combine movieid and avg(rating) into a single raw
   * binary value with avg(rating) first so that min(..)
   * will sort by rating then by movieid */
  utl_raw.overlay(
  utl_raw.cast_from_binary_integer(movieid),
  utl_raw.cast_from_number(avg(rating)), 5)) packed
  from rating group by movieid)

/* extract our rating and movieid from the packed aggregation
 * and use it to lookup our movietitle */
select movietitle,
  utl_raw.cast_to_number(utl_raw.substr(packed,1,3)) rating
from movie m, lowest l
where m.movieid=
  utl_raw.cast_to_binary_integer(utl_raw.substr(packed,5,4))

注意:这假设 movieid 是一个 int 并且 rating 是一个数字(参见 SQL Fiddle DDL)。如果两者都是整数或数字,您还可以通过将更重要的值向左移动(乘以 2 的幂)并将它们加在一起来“打包”它们。

SQL小提琴

于 2012-11-19T09:10:05.913 回答
0

计算平均评分,按升序排列,取第一个结果。

 SELECT *
 FROM   (
        SELECT   MOVIETITLE AS "Movie Title",
                 AVG(RATING) AS "Lowest Average Rating"
        FROM     MOVIE, RATING
        WHERE    MOVIE.MOVIEID = RATING.MOVIEID
        GROUP BY MOVIETITLE
        ORDER BY 2 ASC)
 WHERE ROWNUM = 1;
于 2012-11-19T11:00:51.840 回答
0

如果您还需要电影标题,我会使用分析函数来获取最小值。这允许您只在每张桌子上打一次(今草顿웃给出的解决方案将在每张桌子上打两次......一次在主选择中,一次在“拥有”选择中)。

select movietitle as "Movie Title", avgrating as "Lowest Average Rating"
from (
    select
        m.movietitle,
        avg(r.rating) avgrating,
        rank() over (order by avg(rating)) rank
    from
        movie m
        inner join rating r
            on r.movieid = m.movieid
    group by
        m.movietitle
)
where rank = 1;
于 2013-11-14T18:52:54.860 回答