每个类别获得最多租借的电影

时间:2017-05-22 18:48:43

标签: oracle plsql

我有电影租赁数据库,我在这里工作,我试图找到每个类别租得最多的电影。我想打印出标题和类别。这是我的代码块:

declare
type listOfCat is varray(10) of varchar2(10);

categories listOfCat;
movCount number(2);
title varchar2(50);

begin 
  select distinct category bulk collect into categories from movie;

  for i in 1.. categories.count loop
    select max(count) into movCount from 
    (select count(r.movie_id) as count, m.title as mov, m.CATEGORY as cat from rental r
    join movie m on r.movie_id = m.movie_id
    where m.category = categories(i)
    group by m.title, m.CATEGORY
    );

    dbms_output.put_line(movCount || ' ' || categories(i)); 
  end loop;
end;

现在问题是我不知道在这种情况下如何获得电影片名。我尝试给max(count)一个别名并执行alias.mov但是当在末尾添加group by子句时,它会给出一个无效的标识符错误。如果我每个类别有几部电影,那么按最大(计数)得到的结果进行分组只会再次分离结果。最后,我还尝试将movCount,mov和cat放入数组并并行显示,但这并不能保证订单是正确的。

电影桌有movie_id,title,category,qty_available。 租赁表有movie_id,customer_id,due_date,已退回 客户表有customer_id,名称

1 个答案:

答案 0 :(得分:1)

获取maxmin一个属性并带来与该maxmin相关联的其他字段的一种方法是使用KEEPKEEP用于按一个字段对数据进行排序,然后获取该属性中具有极值的记录,并按maxmin解析关联。

以下是一些示例,其中一些表应与您提供的查询和表兼容:

创建测试表:

CREATE TABLE RENTAL(
MOVIE_ID NUMBER
);

CREATE TABLE MOVIE(
  MOVIE_ID NUMBER,
  TITLE VARCHAR2(64),
  CATEGORY VARCHAR2(64)
);

并加载一些测试数据;

INSERT INTO MOVIE VALUES(1,'The Fugitive','Thriller');
INSERT INTO MOVIE VALUES(2,'No Country for Old Men','Thriller');
INSERT INTO MOVIE VALUES(3,'The Martian','Sci-Fi');
INSERT INTO MOVIE VALUES(4,'Back To The Future','Sci-Fi');
INSERT INTO MOVIE VALUES(5,'Alien','Sci-Fi');


INSERT INTO RENTAL VALUES (1);
INSERT INTO RENTAL VALUES (2);
INSERT INTO RENTAL VALUES (3);
INSERT INTO RENTAL VALUES (3);
INSERT INTO RENTAL VALUES (5);
INSERT INTO RENTAL VALUES (1);
INSERT INTO RENTAL VALUES (3);
INSERT INTO RENTAL VALUES (4);
INSERT INTO RENTAL VALUES (5);
INSERT INTO RENTAL VALUES (1);
INSERT INTO RENTAL VALUES (4);
INSERT INTO RENTAL VALUES (2);
INSERT INTO RENTAL VALUES (1);
INSERT INTO RENTAL VALUES (3);
INSERT INTO RENTAL VALUES (2);
INSERT INTO RENTAL VALUES (2);

现在,如果我们查询以获得pl / sql块的初始期望,我们可以看到我们在Thriller类别中有一个平局:

SELECT MOVIE.TITLE, MOVIE.CATEGORY, COUNT(*) AS RENTAL_COUNT FROM MOVIE
  INNER JOIN RENTAL
    ON MOVIE.MOVIE_ID = RENTAL.MOVIE_ID
GROUP BY MOVIE.TITLE, MOVIE.CATEGORY
ORDER BY 2 ASC, 3 DESC;

TITLE                   CATEGORY  RENTAL_COUNT  
The Martian             Sci-Fi    4             
Alien                   Sci-Fi    2             
Back To The Future      Sci-Fi    2             
No Country for Old Men  Thriller  4             
The Fugitive            Thriller  4         

因此,我们应该在The Martian中使用Sci-Fi,但我们需要在Thriller中使用KEEP来解决该问题。

现在运行pl / sql块。我修改了查询并在此处将电影标题添加到打印的语句中,但它大致相同。 max-count获得最高租金数量,KEEP获得具有该租金数量的电影。

declare
  type listOfCat is varray(10) of varchar2(10);

  categories listOfCat;
  movCount number(2);
  movieTitle varchar2(50);

begin
  select distinct category bulk collect into categories from movie;

  for i in 1.. categories.count loop
    SELECT MIN(TITLE) KEEP (DENSE_RANK FIRST ORDER BY COUNT(*) DESC),
      MAX(COUNT(*))
    INTO movieTitle, movCount
    FROM MOVIE
      INNER JOIN RENTAL
        ON MOVIE.MOVIE_ID = RENTAL.MOVIE_ID
    WHERE MOVIE.CATEGORY = categories(i)
    GROUP BY MOVIE.TITLE;

    dbms_output.put_line(utl_lms.format_message('Category: %s, Most-Rented-Movie:%s, Rental-Count:%s',categories(i),movieTitle,to_char(movCount)));
  end loop;
end;
/

结果:

Category: Sci-Fi, Most-Rented-Movie:The Martian, Rental-Count:4
Category: Thriller, Most-Rented-Movie:No Country for Old Men, Rental-Count:4

在这种情况下,MIN(TITLE)解决了The FugitiveNo Country for Old Men之间的关系。