0%

Vat veel rijen samen · oefening

Filter gevormde groepen met HAVING

Na het rijfilter van veertien dagen heeft elektronica nog maar één bijdragend voorwerp. Stel dat het rapport categorieën alleen mag tonen wanneer ten minste twee passende voorwerpen de samenvatting ondersteunen. Die regel kun je niet beoordelen door naar één bronrij te kijken; hij hangt af van het aantal in de gevormde groep.

Open summary.sql. Voeg deze regel toe tussen GROUP BY category en ORDER BY category ASC:

HAVING COUNT(*) >= 2

Druk op Run. De elektronicagroep verdwijnt, terwijl evenementen en gereedschap overblijven:

Columns: category | item_count | total_loan_days | shortest_loan_days | longest_loan_days | average_loan_days
events | 2 | 21 | 7 | 14 | 10.5
tools | 2 | 10 | 3 | 7 | 5.0

De query neemt nu twee verschillende filterbeslissingen in twee verschillende fasen. WHERE loan_days <= 14 bekijkt afzonderlijke voorwerpen voordat groepen worden gevormd. HAVING COUNT(*) >= 2 bekijkt elke gevormde categoriegroep nadat SQLite weet hoeveel passende rijen die bevat.

De zichtbare groepen bereiken HAVING met deze aantallen:

Gevormde groepAantal passende rijenBehouden?
electronics1nee
events2ja
tools2ja

Het groepsfilter leest die berekende aantallen; het bekijkt de termijnen van afzonderlijke voorwerpen niet opnieuw.

Dit onderscheid is van belang voor elektronica. De tabel begint met twee elektronische voorwerpen, maar de luidspreker voldoet niet aan de WHERE-regel. De gevormde elektronicagroep heeft daardoor een aantal van één en HAVING verwijdert die groep. Tellen vóór het rijfilter zou een andere vraag beantwoorden.

Ook hier telt de grens mee. Een groep met precies twee passende voorwerpen moet blijven staan, dus is de vergelijking >= 2, niet > 2.

Behoud de regel voor de maximumtermijn in WHERE. Als je die naar HAVING verplaatst, verwijdert hij geen afzonderlijke bronrijen meer voordat de totalen en gemiddelden worden berekend. Behoud de regel voor de minimale groepsgrootte in HAVING, want een bronrij bevat niet het uiteindelijke aantal van zijn groep.

Je ziet COUNT(*) misschien zowel in het geselecteerde resultaat als in de HAVING-voorwaarde. Ze verwijzen naar hetzelfde berekende groepsaantal. De ene toont het aan de lezer; de andere gebruikt het om te bepalen of die groep in het antwoord thuishoort.

Submit bevat een groep met één passende rij, een met precies twee en een die met twee rijen begint maar na het rijfilter op één uitkomt. Als die laatste groep blijft staan, controleer dan in welke fase het aantal is berekend dat HAVING gebruikt.

Je kunt de query nu als een reeks vragen lezen: Welke voorwerpen mogen bijdragen? Hoe worden ze gegroepeerd? Welke gevormde groepen zijn groot genoeg om te rapporteren? Elke clausule heeft één duidelijke beslissing te nemen.

Opdracht

Voeg HAVING COUNT(*) >= 2 toe tussen GROUP BY category en ORDER BY category ASC in summary.sql.

Behoud de regel voor bronrijen in WHERE, voer de query uit en stuur de overgebleven groepen in.