sql >> Database teknologi >  >> Database Tools >> phpMyAdmin

Vælg en post, bare hvis den før den har en lavere værdi tager for lang tid og mislykkes

Her er en løsning på dit spørgsmål 1, som vil køre meget hurtigere, da du har mange fulde tabelscanninger og afhængige underforespørgsler. Her vil du højst have kun én tabelscanning (og måske en midlertidig tabel, alt efter hvor store dine data er og hvor meget hukommelse du har). Jeg tror, ​​du nemt kan tilpasse det til dit spørgsmål her. Spørgsmål 2 (jeg har ikke rigtig læst det) er sikkert også besvaret, da det nu er nemt bare at tilføje hvor date_column =whatever

vælg * fra ( vælg t.*, if(@prev_toner  

EDIT:

Forklaring:

Med denne linje

 , (vælg @prev_toner:=0, @prev_sn:=SerialNumber fra Tabel1 sorter efter SerieNumber  

vi initialiserer bare variablerne @prev_toner og @prev_sn på farten. Det er det samme som slet ikke at have denne linje i forespørgslen, men at skrive foran forespørgslen

SET @prev_toner =0;SET @prev_sn =(vælg serienummer fra din_tabelrækkefølge efter serienummergrænse 1);VÆLG ... 

Så hvorfor skal forespørgslen tildeles en værdi til @prev_sn og hvorfor bestilles efter serienummer? Rækkefølgen er meget vigtig. Uden en ordre fra er der ingen garanteret rækkefølge, hvori rækker returneres. Vi vil også få adgang til den foregående rækkes værdi med variabler, så det er vigtigt, at de samme serienumre er "grupperet sammen".

Kolonnerne i select-klausulen evalueres efter hinanden, så det er vigtigt, at du først vælger denne linje

if(@prev_toner  

før du vælger disse to linjer

@prev_sn :=Serienummer,@prev_toner :=Remain_Toner_Black

Hvorfor det? De sidste to linjer tildeler kun værdierne af de aktuelle rækker til variablerne. Derfor i denne linje

if(@prev_toner  

variablerne holder stadig værdierne fra de foregående rækker. Og det, vi gør her, er ikke andet end at sige "hvis værdien af ​​den foregående række i kolonnen Remain_Toner_Black er mindre end den i den aktuelle række og den foregående rækkes serienummer er det samme som den faktiske rækkes serienummer, return 1, ellers returner 0."

Så kan vi blot sige i den ydre forespørgsel "vælg hver række, hvor ovenstående returnerede 1".

På baggrund af din forespørgsel har du ikke brug for alle disse underforespørgsler. De er meget dyre og unødvendige. Det er faktisk ret sindssygt. I denne del af forespørgslen

 VÆLG a.ID, a.Time, a.SerialNumber, a.Remain_Toner_Black, a.Remain_Toner_Cyan, a.Remain_Toner_Magenta, a.Remain_Toner_Yellow, ( SELECT COUNT(*) FROM Reports c WHERE c.SerialNumber =a.SerialNumber .SerialNumber AND c.ID <=a.ID) SOM RowNumber FROM rapporterer a 

du vælger hele tabellen og for hver række du tæller rækkerne i den gruppe. Det er en afhængig underforespørgsel. Alt sammen bare for at have en slags rækkenummer. Så gør du dette en anden gang, bare så du kan slutte dig til de to midlertidige tabeller for at få den forrige række. Egentlig ikke underligt, at præstationen er forfærdelig.

Så hvordan tilpasser jeg min løsning til din forespørgsel? I stedet for den ene variabel, jeg brugte til at få den forrige række for Remain_Toner_Black, brug fire til farverne sort, cyan, magenta og gul. Og tilmeld dig bare printer- og kundetabellen, som du allerede har gjort. Glem ikke bestillingen inden, og du er færdig.




  1. SQL-forespørgsel max(), count()

  2. MySQL 5.1 / phpMyAdmin - logning af CREATE/ALTER-udsagn

  3. Hvordan finder man ud af tegnsættet for en database og tabel med PHPmyAdmin?

  4. MariaDB tillader ikke fjernforbindelser