2017-05-22 3 views
0

Ich habe Film-Verleih-Datenbank, mit der ich arbeite hier und ich versuche, den am meisten gemieteten Film pro Kategorie zu finden. Ich möchte den Titel und die Kategorie ausdrucken. Hier ist mein Code-Block:bekommen am meisten gemieteten Film pro Kategorie

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; 

Nun das Problem ist, ich weiß nicht, wie der Filmtitel in diesem Fall zu erhalten. Ich habe versucht, max (count) einen Alias ​​zu geben und Alias.mov zu tun, aber wenn man am Ende eine group by-Klausel hinzufügt, gibt es einen ungültigen Bezeichnerfehler. Auch die Gruppierung nach dem Ergebnis, das ich bei max (count) erhalte, wird das Ergebnis nur dann wieder trennen, wenn ich mehrere Filme pro Kategorie habe. Schließlich habe ich auch versucht, movCount, mov und cat in Arrays zu setzen und sie parallel anzuzeigen, aber das garantiert mir nicht, dass die Reihenfolge richtig ist.

Filmtabelle hat movie_id, title, category, qty_available. Vermietung Tisch hat movie_id, customer_id, DUE_DATE kehrte Customer-Tabelle CUSTOMER_ID hat, Name

+0

Gibt es eine Chance, dass Sie ein Beispiel der Daten in 'Film' und' Verleih' bereitstellen können? – alexgibbs

+0

Ich fragte mich, was würden Sie im Falle eines Unentschiedens tun? Zum Beispiel, wenn die maximale Anzahl von Mieten in einer Kategorie von zwei Filmen in dieser Kategorie geteilt wird. – alexgibbs

+0

nehmen Sie die erste – user220177

Antwort

1

Eine Möglichkeit, eine max oder min eines Attributs und auch entlang einem anderen Feld mit dem max oder min assoziiert bringen zu bekommen, ist KEEP zu verwenden. KEEP Funktionen zum Sortieren der Daten nach einem Feld, dann nehmen Sie die Datensätze mit dem Extremwert in diesem Attribut und lösen Verbindungen durch max oder min.

Hier ist ein Beispiel mit einigen Tabellen, die mit der Abfrage und Tabellen, die Sie zur Verfügung gestellt kompatibel sein sollte:

Erstellen Sie die Testtabellen:

CREATE TABLE RENTAL(
MOVIE_ID NUMBER 
); 

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

Und laden einige Testdaten;

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); 

Wenn wir nun einige anfängliche Erwartung für die PL/SQL-Block erhalten abfragen, können wir sehen wir eine Krawatte in der Thriller Kategorie haben:

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   

Also sollten wir mit The Martian am Ende in Sci-Fi, aber wir müssen diese Krawatte in Thriller mit KEEP lösen.

Jetzt den PL/SQL-Block ausführen. Ich habe die Abfrage modifiziert und den Filmtitel zu der gedruckten Aussage hinzugefügt, aber es ist weitgehend dasselbe. max-count erhält die höchste Anzahl an Mietangeboten und KEEP bekommt den Film mit dieser Anzahl von Mietobjekten.

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; 
/

Ergebnis:

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

In diesem Fall gelöst MIN(TITLE) die Verbindung zwischen The Fugitive und No Country for Old Men.

+0

jetzt sehe ich so, um andere Spalten in den Max (Anzahl) Datensatz, den ich benutze, zu behalten – user220177

Verwandte Themen