Beregninger og konstante værdier

I SQL-sproget kan du indsætte konstante værdier som en kolonne, og du kan lave beregninger direkte i en forespørgsel. Beregninger og indsættelse af konstante kolonneværdier er nyttigt i flere situationer. Enten fordi der er krav om, at der leveres eksempelvis en pris med moms, men værdien er skrevet uden moms. Eller der kan være et ønske om, at alle rækker har en kolonne med en bestemt oplysning, f.eks. for at identificere data i forbindelse med samkøring af data fra flere kilder.

Når du ændrer en kolonnes oprindelige værdi eller indsætter en kolonne med konstant værdi, vil SQL Server ikke længere give dig navnet på kolonnen. Det er der umiddelbart to grunde til: For det første kan det give dataforvirring, hvis en kolonne har samme navn, men en ny værdi, og for det andet kan beregningen indeholde flere kolonner, og det er så ikke tydeligt hvilket kolonnenavn, der skal bruges. Derfor navngiver/omdøber jeg konsekvent kolonner, der laves beregninger på. Se mere om at omdøbe og navngive kolonner i denne lektion.

Sådan beregner du moms på priskolonne

Et ganske åbenlyst eksempel er at lave en momsberegning af priskolonnen i varetabellen. Momsen i Danmark (i skrivende stund) er 25%. Vi skal altså gange prisen med 1,25. Gangetegnet i SQL Server er *. Det skal ikke forveksles med * i forbindelse med visning af alle kolonner i en SELECT.

SELECT
  Varenr,
  Varebetegnelse,
  Pris PrisUdenMoms,
  Pris*1.25 PrisMedMoms
FROM Vare

Konstante værdier i en kolonne

Det kan være nødvendigt eller bare praktisk at have en eller flere kolonner med kontante værdier i. Det er supernemt, du skal bare skrive værdien som var det et felt. Tekstværdier skal skrives i apostroffer.

Dette eksempel skriver en kolonne med teksten Boblekuvert TILBUD og laver dertil en kolonne med værdien 50, som er den rabatprocent, der ydes. Selvfølgelig beregnes prisen også.

SELECT
  'Boblekuvert TILBUD' Tilbudsinformation,
  50 Rabatprocent,
  Varebetegnelse,
  Pris NormalprisUdenMoms,
  Pris*0.5 TilbudsprisUdenMoms
FROM Vare
WHERE Varenr LIKE 'BOBA%'

Tekstfelter kan også manipuleres

Du kan også manipulere tekstfelter, f.eks. ved at lægge en tekst til, eller bruge en tekstfunktion til at afkorte eller på anden måde ændre værdien. Her skriver vi Halv pris! foran varebetegnelsen.

SELECT
  'Boblekuvert TILBUD' Tilbudsinformation,
  'Halv pris! ' + Varebetegnelse Varebetegnelse,
  Pris NormalprisUdenMoms,
  Pris*0.5 TilbudsprisUdenMoms
FROM Vare
WHERE Varenr LIKE 'BOBA%'

Regnearter og funktioner

SQL Server kender de almindelige regnearter og har en masse indbyggede funktioner til forskellige formål. Denne forespørgsel viser de fire regnearter og eksempler på et par indbyggede funktioner.

  • SIGN(værdi): Viser fortegnet af værdien. -1 negativ, 0 nul, 1 positiv.
  • ROUND(værdi, antaldecimaler): afrunder værdien til det ønskede antal decimaler.
  • RAND(): viser et tilfældigt tal mellem 0 og 1. Bemærk, at der ikke beregnes en ny værdi i hver række!
SELECT
  Pris,
  Pris*2 Multiplikation,
  Pris/2 Division,
  Pris+2 Addition,
  Pris-0.2 Subtraktion,
  SIGN(Pris) FortegnPostiv,
  SIGN(-Pris) FortegnNegativ,
  SIGN(0) FortegnNul,
  ROUND(Pris/7, 4) Afrund4decimaler,
  ROUND(Pris/7, 2) Afrund2decimaler,
  RAND() Tilfældig
FROM Vare
WHERE Varenr LIKE 'BOBA%'

Prøv selv

  • I Ordrelinje-tabellen er der antal, pris og rabat (i kroner pr. enhed). Lav en kolonne, der viser totalen.
  • Lav en forespørgsel med en Varebetegnelse-kolonne, hvor varenummer skrives i parentes efter varebetegnelsen. Kolonnens navn skal stadig være Varebetegnelse.
  • Funktionen DATEDIFF beregner tidsrum mellem to datoer. Første parameter er enheden. Brug DATEDIFF(enhed, dato1, dato2) og GETDATE() til at finde ud af, hvor mange dage (parameter hedder d), der er siden ordrerne i Ordre-tabellen er oprettet.
    I løsningen i videoen er der også løsning på antal timer, uger og måneder.

Dato og tid i SQL Server

I SQL Server skriver vi dato og klokkeslæt som tekst i et fastlagt format. Men dato og klokkeslæt opfører sig ikke altid som andre tekstfelter. I denne lektion lærer du at bruge dato og klokkeslæt i en WHERE-sætning og samtidig får du kortvarigt snuset til den logiske AND-operator, da den er en del af BETWEEN-operatoren.

Eksempler på datoer:

  • 22. april 2020: ‘2020-04-22’
  • 1. februar 1946: ‘1946-02-01’
  • 29. februar 2020: ‘2020-02-29’

Ovenstående datoer alle er gyldige, men hvis du taster en ugyldig dato, som f.eks. 29. februar i 2019 (som ikke er et skudår), får du en fejl fra SQL Server:

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
SQL Server kan ikke oversætte dato eller klokkeslæt til en gyldig værdi

Eksempler på klokkeslæt:

  • Timer, minutter ’11:05′
  • og sekunder ’11:05:25′
  • og millisekunder ’11:05:25.934′

Vi bruger 24-timers-ur:

  • Timer, minutter, sekunder ’21:14:58′

Dato og klokkeslæt på én gang adskilles af et mellemrum, 20. april 2020 kvart over syv om aftenen og nogle sekunder: ‘2020-04-20 19:15:25’ mere præcist med 354 millisekunder: ‘2020-04-20 19:15:25.354’.

Ugyldige klokkeslæt giver også samme fejl som ovenfor.

Find ordrer fra en bestemt dato

Et hurtigt kig i Ordre-tabellen giver os en kolonne med navnet Dato, som vi kan bruge til at finde rækker ud fra en bestemt dato. Find rækker, hvor ordredato er 20. april 2020.

SELECT * FROM Ordre
WHERE Dato = '2020-04-20'
Ordrer på en bestemt dato

Hvis du gerne vil se rækkerne oprettet alle andre datoer end 20. april 2020, har du sikkert gættet, at du kan anvende <> (ikke lig med):

SELECT * FROM Ordre
WHERE Dato <> '2020-04-20'
Ordrer på alle andre datoer

Sådan finder du rækker før og efter en dato

Når du fremover skal arbejde med datoer og klokkeslæt, er det ofte ud fra at ønske om at se rækker, som er oprettet før eller efter en bestemt dato. I den sammenhæng bruger du > og < til at afgøre dette.

Større end betyder, at datoen ligger efter. Læs denne sætning som: Dato er større end (altså senere end, længere ude i fremtiden end) 20. april 2020:

SELECT * FROM Ordre
WHERE Dato > '2020-04-20'
Datoer senere end findes med “større end”

Helt som forventet bruger du mindre end, til at finde værdier i fortiden: Dato er mindre end (altså tidligere end, længere tilbage i fortiden end) 20. april 2020:

SELECT * FROM Ordre
WHERE Dato < '2020-04-20'
Datoer tidligere end findes med “mindre end”

Brug ikke LIKE med dato og klokkeslæt

Det er fristende at opfatte datoer som ren tekst lagret i databasen. Men sådan er det ikke. Selv om du skriver dato og klokkeslæt i apostroffer, bliver værdien oversat og lagret som et felt af typen datetime i SQL Server.

LIKE-operatoren fungerer ikke som forventet med jokertegn på datoer.

Følgende kan altså ikke bruges til at finde Ordre oprettet i april 2020:

SELECT * FROM Ordre
WHERE Dato LIKE '2020-04-%'
LIKE sammen med datoer dur ikke, resultatet er tomt – bemærk, at det ikke er en fejl!

Der er andre måder at løse denne problemstilling på med dato- og tid-funktionerne eller BETWEEN-operator, som du kan se herunder.

Perioder kan findes med BETWEEN

Det er ganske naturligt at have et ønske om at se rækker, som har en start- og slutdato i en given periode. BETWEEN-operatoren er god at kende, da det er nemt at forstå, når du læser SQL, at dato skal ligge mellem to angivne værdier. Alternativet til at bruge BETWEEN er at sammenligne med >= og <=. Bemærk, at BETWEEN inkluderer begge datoer i resultatet.

SELECT * FROM Ordre
WHERE Dato BETWEEN '2020-04-19' AND '2020-04-21'
BETWEEN giver alle datoer i perioden, inklusive start- og slutdato

Prøv selv

  • Find ordrer oprettet før eller på 21. april 2020.
  • Find ordrer oprettet efter 21. april 2020.
  • Find ordrer oprettet før kl. 19 d. 21. april 2020.
  • Find ordrer oprettet mellem 17. april og 19. april (begge inklusive)
  • Find ordrer oprettet mellem 17. april og 20. april (begge eksklusive)
    I videoen kan du se alternative løsninger til de to sidste opgaver.