SQL聚合函数

时间:2012-11-19 08:23:10

标签: sql oracle function aggregation

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

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的新手,所以这对我来说都很新......

修改

好的只是为了澄清事情,有很多人在评级表中评价相同的电影,基本上需要获得每部电影的所有评级的平均值,并列出平均电影最低的电影

6 个答案:

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

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

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

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

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

答案 5 :(得分:0)

如果您还需要电影片名,我会使用分析功能来获得分数。这样你就可以只打一次每一张桌子(今草顿given给出的解决方案会在每张桌子上打两次......一次在主选中,一次在“有”选择中)。

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;