sql >> Database teknologi >  >> RDS >> Mysql

MySQL kompleks underforespørgsel formulering

Jeg er enig med Strawberry om skemaet. Vi kan diskutere ideer til bedre ydeevne og alt det der. Men her er mit bud på, hvordan man løser dette efter et par chats og ændringer af spørgsmålet.

Bemærk nedenfor dataændringerne for at håndtere forskellige randbetingelser, som inkluderer bøger uden billeder i den tabel og tie-breaks. Tie-breaks betyder at bruge max(upvotes) . OP ændrede spørgsmålet et par gange og tilføjede en ny kolonne i billedtabellen.

Ændret spørgsmål blev retur 1 række fabrikat pr. bog. Rids det, altid 1 række pr. bog, selvom der ikke er nogen billeder. Billedinformationen, der skal returneres, ville være den med maks. opstemmer.

Tabel med bøger

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

Dataændringer fra det oprindelige spørgsmål.

Hovedsageligt de nye upvotes kolonne.

Nedenstående inkluderer en tie-break række tilføjet.

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

Visualisering af en afledt tabel

Dette er blot for at hjælpe med at visualisere en indre del af den endelige forespørgsel. Det demonstrerer gotcha for tie-break situationer, således rownum variabel. Denne variabel nulstilles til 1 hver gang bookid ændres ellers stiger den. Til sidst (vores sidste forespørgsel) vil vi kun have rownum=1 rækker, så der maksimalt returneres 1 række pr. bog (hvis nogen).

Endelig forespørgsel

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
 

Resultater

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

Betydningen af ​​cross join er blot at indføre og indstille startværdier for 2 variable. Det er alt.

Resultaterne er de ti bedste bøger i faldende rækkefølge efter purchasecount med oplysningerne fra images hvis den findes (ellers NULL ) for det mest stemte billede. Det valgte billede overholder tie-break reglerne og vælger det første som nævnt ovenfor i visualiseringssektionen med rownum .

Sidste tanker

Jeg overlader det til OP at kile den passende where ind klausul i slutningen, da de angivne eksempeldata ikke havde noget brugbart bognavn at søge på. Den del er triviel. Åh, og gør noget ved skemaet for den store bredde af dine primære nøgler. Men det er off-topic i øjeblikket.




  1. MySQL sammensat indeks bliver ikke brugt

  2. Sådan sletter du fuldstændigt duplikerede rækker

  3. Sådan laver du cascading drop-down lister ved hjælp af mysql og php

  4. SQL Server Operativsystem fejl 5:5 (Adgang nægtes.)