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

Database: Bygdekinoen

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.

  1. Les spørringen, og gjett hvor mange rader resultatet får. Kjør.
  2. Fjern AS antall. Hva heter kolonnen nå?
  3. Tell bare barnebillettene. Skriv WHERE type = 'barn' på riktig sted.
  4. Hvor mye har kinoen tjent på honnørbilletter?
  5. 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

Database: Bygdekinoen

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.

  1. Kjør spørringen. Hvor lang er en film i gjennomsnitt?
  2. Rund av gjennomsnittet til hele minutter.
  3. Hva er gjennomsnittsprisen på en billett? Hvorfor er den ikke en av de tre prisene kinoen har?
  4. MAX(lengde) gir den største lengden, men ikke hvilken film det er. Skriv en spørring med ORDER BY og LIMIT som 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

Database: Bygdekinoen

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.

  1. Gjett hvor mange rader resultatet får. Kjør, og sjekk.
  2. Sorter resultatet etter inntekt, med den største først.
  3. 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.

Database: Bygdekinoen
  1. Kjør spørringen. Hvilken film har solgt flest billetter?
  2. Legg til COUNT(DISTINCT visning.id) AS visninger i SELECT. DISTINCT teller hver visning bare én gang. Hvor mange ganger er hver film vist?
  3. 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.
  4. 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;
  1. 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?
Database: Bygdekinoen
Spør KI

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.

  1. Les koden. Hvorfor deles antall billetter på storst?
  2. Lag mappen diagram med en side der du skriver av koden. Legg til alle de ti filmene fra resultatet i 21.3.
  3. Lag et diagram for antall billetter per klokkeslett, fra spørringen du skrev i 21.3 g).
  4. 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
  1. 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?
  2. Hva får du vite i diagram B som du ikke får vite i diagram A?
  3. 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?
  4. Finn et diagram i en avis eller på nettet. Bruk tabellen ovenfor til å vurdere det, og foreslå hvordan det kan bli bedre.
  5. 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.

Spør KI

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

Database: Bygdekinoen

Merk deg følgende:

  • Aggregatfunksjoner regner ut én verdi fra mange rader.
  • WHERE velger radene før de blir gruppert. GROUP BY gir é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

Database: Bygdekinoen

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 visning
  • SELECT sal, COUNT(*) AS visninger
  • GROUP 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.

Database: Bygdekinoen
  • 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.