Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Formulierung einer komplexen MySQL-Unterabfrage

Ich stimme Strawberry über das Schema zu. Wir können Ideen für eine bessere Leistung und all das diskutieren. Aber hier ist meine Meinung, wie ich das nach ein paar Chats und Änderungen an der Frage lösen kann.

Beachten Sie unten die Datenänderungen, um mit verschiedenen Randbedingungen umzugehen, die Bücher ohne Bilder in dieser Tabelle und Tie-Breaks beinhalten. Tie-Breaks bedeuten die Verwendung von max(upvotes) . Das OP hat die Frage ein paar Mal geändert und eine neue Spalte in der Bildtabelle hinzugefügt.

Die geänderte Frage wurde zur Rückgabe von 1 Zeile pro Buch. Streichen Sie das, immer 1 Zeile pro Buch, auch wenn keine Bilder vorhanden sind. Die zurückzugebenden Bildinformationen wären die mit den maximalen Upvotes.

Büchertisch

create table books 
(   id int primary key, 
    name varchar(1000), 
    releasedate date, 
    purchasecount int
) ENGINE=InnoDB;

insert into books values(1,"fool","1963-12-18",456);
insert into books values(2,"foo","1933-12-18",11);
insert into books values(3,"fooherty","1943-12-18",77);
insert into books values(4,"eoo","1953-12-18",678);
insert into books values(5,"fooe","1973-12-18",459);
insert into books values(6,"qoo","1983-12-18",500);

Datenänderungen gegenüber der ursprünglichen Frage.

Hauptsächlich die neuen upvotes Spalte.

Das Folgende enthält eine hinzugefügte Tie-Break-Reihe.

create table images 
(   bookid int, 
    poster varchar(150) primary key, 
    bucketid int, 
    upvotes int -- a new column introduced by OP
) ENGINE=InnoDB;

insert into images values (1,"xxx",12,27);
insert into images values (5,"pqr",11,0);
insert into images values (5,"swt",11,100);
insert into images values (2,"yyy",77,65);
insert into images values (1,"qwe",111,69);
insert into images values (1,"blah_blah_tie_break",111,69);
insert into images values (3,"qwqqe",14,81);
insert into images values (1,"qqawe",8,45);
insert into images values (2,"z",81,79);

Visualisierung einer abgeleiteten Tabelle

Dies dient lediglich der Visualisierung eines inneren Teils der endgültigen Abfrage. Es demonstriert den Gotcha für Tie-Break-Situationen, also die rownum Variable. Diese Variable wird jedes Mal auf 1 zurückgesetzt, wenn bookid ändert, andernfalls erhöht es sich. Am Ende (unserer letzten Abfrage) wollen wir nur noch rownum=1 Zeilen, sodass maximal 1 Zeile pro Buch (falls vorhanden) zurückgegeben wird.

Letzte Abfrage

select b.id,b.purchasecount,xDerivedImages2.poster,xDerivedImages2.bucketid
from books b
left join
(   select i.bookid,i.poster,i.bucketid,i.upvotes,
    @rn := if(@lastbookid = i.bookid, @rn + 1, 1) as rownum,
    @lastbookid := i.bookid as dummy
    from 
    (   select bookid,max(upvotes) as maxup
        from images
        group by bookid
    ) xDerivedImages
    join images i
    on i.bookid=xDerivedImages.bookid and i.upvotes=xDerivedImages.maxup
    cross join (select @rn:=0,@lastbookid:=-1) params
    order by i.bookid
) xDerivedImages2
on xDerivedImages2.bookid=b.id and xDerivedImages2.rownum=1
order by b.purchasecount desc
limit 10

Ergebnisse

+----+---------------+---------------------+----------+
| id | purchasecount | poster              | bucketid |
+----+---------------+---------------------+----------+
|  4 |           678 | NULL                |     NULL |
|  6 |           500 | NULL                |     NULL |
|  5 |           459 | swt                 |       11 |
|  1 |           456 | blah_blah_tie_break |      111 |
|  3 |            77 | qwqqe               |       14 |
|  2 |            11 | z                   |       81 |
+----+---------------+---------------------+----------+

Die Bedeutung des cross join besteht lediglich darin, Startwerte für 2 Variablen einzuführen und festzulegen. Das ist alles.

Die Ergebnisse sind die Top-Ten-Bücher in absteigender Reihenfolge nach purchasecount mit den Informationen von images falls vorhanden (ansonsten NULL ) für das Bild mit den meisten positiven Stimmen. Das ausgewählte Bild erfüllt die Tie-Break-Regeln, indem das erste Bild ausgewählt wird, wie oben im Abschnitt „Visualisierung“ mit rownum erwähnt .

Abschließende Gedanken

Ich überlasse es dem OP, das entsprechende where einzufügen Klausel am Ende, da die angegebenen Beispieldaten keinen nützlichen Buchnamen zum Suchen enthielten. Dieser Teil ist trivial. Oh, und tun Sie etwas mit dem Schema für die große Breite Ihrer Primärschlüssel. Aber das ist im Moment Off-Topic.