21 Statistikk med SQL
Kari på Bygdekinoen vil vite hvilke filmer som selger best, og når folk går på kino. Svarene må regnes ut fra over tusen billetter. Lagre spørringene og diagrammene dine i mappen kap21-statistikk.
21.1 Telle og summere
COUNT(*) teller rader, og SUM(pris) legger sammen verdiene i kolonnen pris. Slike funksjoner kalles aggregatfunksjoner. De regner ut én verdi fra mange rader, på samme måte som løkkene du skrev i kapittel 15. AS gir kolonnen i resultatet et navn.
- Les spørringen, og gjett hvor mange rader resultatet får. Kjør.
- Fjern
AS antall. Hva heter kolonnen nå? - Tell bare barnebillettene. Skriv
WHERE type = 'barn'på riktig sted. - Hvor mye har kinoen tjent på honnørbilletter?
- Hvor mange visninger har kinoen hatt i sal 2?
WHERE velger radene før de blir talt eller summert. Spørringen teller bare de radene som passer med vilkåret.
21.2 Gjennomsnitt, minste og største verdi
AVG regner ut gjennomsnittet, MIN finner den minste verdien og MAX den største. Gjennomsnittet får ofte mange desimaler. ROUND(AVG(lengde), 1) runder av til én desimal.
- Kjør spørringen. Hvor lang er en film i gjennomsnitt?
- Rund av gjennomsnittet til hele minutter.
- Hva er gjennomsnittsprisen på en billett? Hvorfor er den ikke en av de tre prisene kinoen har?
MAX(lengde)gir den største lengden, men ikke hvilken film det er. Skriv en spørring medORDER BYogLIMITsom gir tittelen til den lengste filmen.
| Funksjon | Gir |
|---|---|
COUNT(*) |
antall rader |
SUM(kolonne) |
summen |
AVG(kolonne) |
gjennomsnittet |
MIN(kolonne), MAX(kolonne) |
den minste og den største verdien |
ROUND(verdi, 1) |
verdien rundet av til én desimal |
21.3 Gruppere med GROUP BY
GROUP BY type deler billettene i grupper, én for hver billettype. Aggregatfunksjonene regner ut ett svar for hver gruppe. Resultatet får derfor én rad for hver billettype.
- Gjett hvor mange rader resultatet får. Kjør, og sjekk.
- Sorter resultatet etter inntekt, med den største først.
- Hvilken billettype selger kinoen flest av? Hvilken tjener kinoen mest på? Hvorfor er svaret ikke det samme?
Med JOIN kan du gruppere etter noe som står i en annen tabell.
- Kjør spørringen. Hvilken film har solgt flest billetter?
- Legg til
COUNT(DISTINCT visning.id) AS visningeriSELECT.DISTINCTteller hver visning bare én gang. Hvor mange ganger er hver film vist? - Månefisken har solgt flest billetter. Er den den mest populære filmen? Regn ut hvor mange billetter hver film selger per visning, og sorter etter det.
- Lag en spørring som viser hvor mange billetter som er solgt til hvert klokkeslett. Når går folk mest på kino?
Nedenfor ser du fire spørringer som skal vise inntekten for hver sjanger. Bare én av dem virker.
Kode A
SELECT film.sjanger, SUM(billett.pris)
FROM billett
JOIN visning ON billett.visning_id = visning.id
JOIN film ON visning.film_id = film.id;Kode B
SELECT film.sjanger, SUM(billett.pris)
FROM billett
JOIN visning ON billett.visning_id = visning.id
JOIN film ON visning.film_id = film.id
GROUP BY film.sjanger;Kode C
SELECT film.sjanger, SUM(billett.pris)
FROM billett
GROUP BY film.sjanger;Kode D
SELECT film.sjanger, SUM(billett.pris)
GROUP BY film.sjanger
FROM billett
JOIN visning ON billett.visning_id = visning.id
JOIN film ON visning.film_id = film.id;- Finn spørringen som virker. Prøv de andre i boksen nedenfor. Hvilken av dem gir et svar uten feilmelding, men et svar som er feil?
Jeg lærer GROUP BY i SQL. Forklar med et eksempel fra hverdagen, for eksempel å sortere klesvask i hauger, hva som skjer når jeg grupperer og teller. Still meg deretter et spørsmål om databasen til en kino som jeg kan svare på med GROUP BY.
21.4 Fra spørring til diagram
diagram/index.html
<h2>Solgte billetter per film</h2>
<div id="divDiagram"></div>
<style>
.rad { display: flex; align-items: center; gap: 0.5rem; margin: 0.2rem 0; }
.navn { width: 11rem; text-align: right; }
.stolpe { background: #1f6fc5; height: 1.2rem; }
</style>
<script>
let data = [
{ tittel: "Månefisken", billetter: 378 },
{ tittel: "Fotballfeber", billetter: 186 },
{ tittel: "Rakettjenta", billetter: 185 },
{ tittel: "Skyggejegeren", billetter: 85 },
{ tittel: "Stormnatt", billetter: 75 }
];
let storst = data[0].billetter;
let html = "";
for (let rad of data) {
let bredde = (rad.billetter / storst) * 100;
html += `<div class="rad"><span class="navn">${rad.tittel}</span>
<span class="stolpe" style="width: ${bredde * 0.6}%"></span>
<span>${rad.billetter}</span></div>`;
}
divDiagram.innerHTML = html;
</script>Nettleser
Her er resultatet fra 21.3 skrevet av som en liste med objekter, og en løkke lager én stolpe for hver film. Det er det samme du lærte om lister, objekter og løkker i Del 4.
- Les koden. Hvorfor deles antall billetter på
storst? - Lag mappen
diagrammed en side der du skriver av koden. Legg til alle de ti filmene fra resultatet i 21.3. - Lag et diagram for antall billetter per klokkeslett, fra spørringen du skrev i 21.3 g).
- Hvorfor er det lurt å skrive tallet ved siden av hver stolpe?
Du kan også kopiere resultatet fra SQL-boksen inn i et regneark og lage diagrammet der. Marker tabellen under boksen, kopier, og lim inn i regnearket.
21.5 Gode og dårlige diagrammer
Diagram A
Diagram B
De to diagrammene viser de samme tallene. Diagram B bruker blekket på det som er viktig: navnet, stolpen og tallet.
| Gjør | Unngå |
|---|---|
| La stolpene begynne på null | en akse som begynner på et annet tall enn null, i stolpediagrammer |
| Sorter stolpene etter størrelse | tilfeldig rekkefølge |
| Skriv navnet rett ved stolpen | en forklaring med farger ved siden av |
| Bruk én farge, og fremhev det som er viktig | mange farger, skygger og 3D |
| Skriv tallene, eller lag en tabell når tallene er det viktigste | et diagram der leseren må gjette tallene |
| La tittelen si hva leseren skal se | titler som «Billettsalg» |
| Skriv hvor dataene kommer fra, og hvilken periode de gjelder | data uten kilde |
- Se på diagram A. Ser det ut som om Månefisken har solgt sju ganger så mange billetter som Skyggejegeren? Hvor mange ganger så mange er det egentlig?
- Hva får du vite i diagram B som du ikke får vite i diagram A?
- Månefisken er vist ti ganger, mens Skyggejegeren er vist to ganger. Lag et diagram over billetter per visning i stedet. Hvilken tittel vil du gi det?
- Finn et diagram i en avis eller på nettet. Bruk tabellen ovenfor til å vurdere det, og foreslå hvordan det kan bli bedre.
- Lag en liste over alt i diagram A som ikke hjelper leseren å forstå tallene. Sammenlign med tabellen ovenfor.
Et diagram skal gjøre det lettere å forstå tallene, og ikke pynte dem. Hver farge, strek og skygge skal ha en grunn. Har du bare to eller tre tall, er en setning eller en liten tabell ofte bedre enn et diagram.
Her er et diagram jeg har laget, beskrevet med ord: [beskriv diagrammet]. Ikke lag et nytt diagram for meg. Still meg tre spørsmål som hjelper meg å finne ut om diagrammet viser tallene ærlig og tydelig.
Oppsummering
I dette kapitlet har du laget statistikk med aggregatfunksjoner og GROUP BY, tegnet et stolpediagram med JavaScript og vurdert om diagrammer viser tallene ærlig.
Statistikk
Merk deg følgende:
- Aggregatfunksjoner regner ut én verdi fra mange rader.
WHEREvelger radene før de blir gruppert.GROUP BYgir én rad for hver gruppe.- Det som selger mest, er ikke alltid det mest populære. Tenk på hva du sammenligner.
- Et godt diagram har stolper som begynner på null, er sortert, har navnet ved stolpen og en tittel som sier hva leseren skal se.
| Kode | Betyr |
|---|---|
COUNT(*) |
antall rader |
COUNT(DISTINCT visning.id) |
antall forskjellige visninger |
SUM(pris), AVG(pris) |
summen og gjennomsnittet |
MIN(lengde), MAX(lengde) |
den minste og den største verdien |
ROUND(AVG(pris), 1) |
gjennomsnittet med én desimal |
COUNT(*) AS antall |
gir kolonnen navnet antall |
GROUP BY type |
én rad for hver billettype |
Oppgaver
Oppgave 21.1
Spørringen skal vise hvor mange billetter som er solgt hver dag, med den beste dagen først. Den har to feil. Rett feilene i boksen, og kjør.
Oppgave 21.2
FROM visningSELECT sal, COUNT(*) AS visningerGROUP BY sal;
Sett sammen kodelinjene til en spørring som viser hvor mange visninger det har vært i hver sal.
Oppgave 21.3
Skriv spørringer som svarer på spørsmålene til Kari.
- Hvor mye har kinoen tjent på hver film? Sorter med den største inntekten først.
- Hvor mye har kinoen tjent hver dag?
- Hvor mange barnebilletter er solgt til hver film?
- Hvilken sjanger har solgt flest billetter per visning?
Oppgave 21.4
Lag et stolpediagram med JavaScript som viser inntekten for hver sjanger. Følg reglene i tabellen i 21.5, og gi diagrammet en tittel som sier hva leseren skal se.
Oppgave 21.5
Forklar hvorfor en stolpe i et stolpediagram må begynne på null. Lag et eksempel med to tall der en akse som begynner på et annet tall, gir et helt feil inntrykk.
B-oppgaver
Oppgave 21.6
Undersøk HAVING. Skriv en spørring som bare viser filmene som har solgt mer enn 100 billetter. Forklar forskjellen på WHERE og HAVING.
Oppgave 21.7
Sal 1 har 80 plasser, og sal 2 har 45. Regn ut hvor stor andel av plassene som er solgt på hver visning, og finn de fem visningene med lavest andel. Hva vil du anbefale kinoen?
Oppgave 21.8
Lag en side med to diagrammer: billetter per film og billetter per visning. Skriv en kort tekst til Kari som forklarer hva hun bør legge merke til.
Oppgave 21.9
Undersøk strftime('%w', dato) i SQLite, som gir ukedagen som et tall fra 0, søndag, til 6, lørdag. Lag en spørring som viser gjennomsnittlig antall billetter per visning for hver ukedag, og lag et diagram av resultatet med ukedagene i riktig rekkefølge.