我有电影租赁数据库,我在这里工作,我试图找到每个类别租得最多的电影。我想打印出标题和类别。这是我的代码块:
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,名称
答案 0 :(得分:1)
获取max
或min
一个属性并带来与该max
或min
相关联的其他字段的一种方法是使用KEEP
。 KEEP
用于按一个字段对数据进行排序,然后获取该属性中具有极值的记录,并按max
或min
解析关联。
以下是一些示例,其中一些表应与您提供的查询和表兼容:
创建测试表:
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 Fugitive
和No Country for Old Men
之间的关系。