sql >> Database >  >> RDS >> Mysql

MySQL complexe subquery formulering

Ik ben het met Strawberry eens over het schema. We kunnen ideeën bespreken voor betere prestaties en zo. Maar hier is mijn mening over hoe dit op te lossen na een paar chats en wijzigingen in de vraag.

Noteer hieronder de gegevenswijzigingen om met verschillende randvoorwaarden om te gaan, waaronder boeken zonder afbeeldingen in die tabel en tiebreaks. Tie-breaks betekenis met behulp van de max(upvotes) . De OP heeft de vraag een paar keer gewijzigd en een nieuwe kolom toegevoegd aan de afbeeldingentabel.

Gewijzigde vraag werd retour 1 rij maken per boek. Kras dat, altijd 1 rij per boek, ook als er geen afbeeldingen zijn. De afbeeldingsinformatie die moet worden geretourneerd, is degene met maximale stemmen.

Boekentabel

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

Gegevenswijzigingen van oorspronkelijke vraag.

Voornamelijk de nieuwe upvotes kolom.

Het onderstaande bevat een tiebreak-rij toegevoegd.

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

Visualisatie van een afgeleide tabel

Dit is alleen om te helpen bij het visualiseren van een binnenste deel van de uiteindelijke vraag. Het demonstreert de gotcha voor tie-break-situaties, dus het rownum variabel. Die variabele wordt elke keer dat de bookid . op 1 wordt gezet verandert, anders neemt het toe. Uiteindelijk (onze laatste vraag) willen we alleen rownum=1 rijen zodat er maximaal 1 rij wordt geretourneerd per boek (indien aanwezig).

Laatste zoekopdracht

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

Resultaten

+----+---------------+---------------------+----------+
| 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 |
+----+---------------+---------------------+----------+

De betekenis van de cross join is slechts het invoeren en instellen van startwaarden voor 2 variabelen. Dat is alles.

De resultaten zijn de top tien boeken in aflopende volgorde van purchasecount met de info van images als het bestaat (anders NULL ) voor de afbeelding met de meeste stemmen. De geselecteerde afbeelding voldoet aan de tie-break-regels en kiest de eerste zoals hierboven vermeld in de sectie Visualisatie met rownum .

Laatste gedachten

Ik laat het aan de OP over om in de juiste where te wiggen clausule aan het einde omdat de gegeven voorbeeldgegevens geen bruikbare boeknaam hadden om op te zoeken. Dat deel is triviaal. Oh, en doe iets aan het schema voor de grote breedte van je primaire sleutels. Maar dat is momenteel off-topic.




  1. CLOB invoegen in Oracle-database

  2. RETOURNEREN van gegevens uit de updatebare weergave werkt niet?

  3. sub-tekenreeks in orakel

  4. SQL:rijen beperken die aan elke samengevoegde rij zijn gekoppeld