Lär dig SQL

Back to All Courses

Lesson 3

Syntax, datatyper och villkor

by Ted Klein Bergman

Syntax

Oftast när man skriver kod i SQL brukar det bara vara korta kommandon som avslutas med ett semikolon. Detta betyder att SQL är designat på ett sätt som skiljer sig från de flesta traditionella programmeringsspråk. Exempelvis gör SQL ingen skillnad på gemener och versaler. Det betyder att man kan skriva variabeln username som userName, USERNAME, uSeRnaME, eller vilken kombination av vilka små och stora bokstäver som helst. Det kommer tolkas likadant som username i alla fall.

SQL bryr sig inte heller om hur mycket whitespace (mellanslag, enterslag, tab, etc) som du använder dig av, så länge varje ord är separerat med minst ett whitespace. Nedanför har du tre exempel på ekvivalenta SQL-kommando. Texten som följer två bindestreck är en kommentar, ej kod.

-- Exempel 1
select username from users where age > 40;

-- Exempel 2
SELECT username
FROM   users
WHERE  age > 40; 

-- Exempel 3
SeLeCT        useRNAme
     frOm  USERS    
                                 WHEre agE             >
40
      ;

Vi kommer att använda oss av stilen i exempel 2. 

Exakt vad koden gör tar vi upp i senare kapitel, men för att göra koden så tydlig som möjligt kommer vi använda oss av ett par konventioner som underlättar läsandet av koden:

  1. Vi använder stora bokstäver för SQL-nyckelord (exempelvis SELECT eller FROM).

  2. Vi använd små bokstäver för attribut och tabeller (exempelvis username,age, users eller tweets).

  3. Vi bryter hellre upp kod i flera rader än att skriva alltför långa rader. Detta får man själv göra en bedömning av medan man skriver men en tumregel är att undvika rader som är över 80 karaktärer lång. Dock finns det undantag.

Det är viktigt att skriva kod som går att läsa. Skriv som om personen som måste läsa er kod har kort stubin och vet var ni bor.

Datatyper

Alla värden i en relationalsdatabas måste bestå av någon fundamental datatyp. Det finns många olika datatyper men man klarar sig långt på enbart ett få. Här är en kort lista av de vanligaste datatyperna som vi kommer använda oss av i resten av kursen.

  • INTEGER : Ett heltal.

  • REAL : Ett decimaltal (exempelvis 0.1)

  • CHAR(n) : En n lång sträng av karaktärer, varken längre eller kortare. Man kan ha kortare strängar men de blir vadderade med struntvärden för att skapa en n lång sträng. Om man bara skriver CHAR så är det ekvivalent som CHAR(1).

  • TEXT : En sträng av obestämd längd.

  • VARCHAR(n) : En sträng av karaktärer som är upp till n lång, men kan vara kortare. Att bara skriva VARCHAR är ekvivalent som TEXT.

  • BOOL : Ett sant eller falskt värde.

  • TIME : En tidpunkt. Detta kan ha många olika format men vi kommer använda oss av 'hh:mm:ss', exempelvis '13:19:22'.

  • DATE : Ett datum. Detta kan ha många olika format men vi kommer använda oss av 'yyyy-mm-dd', exempelvis '2017-12-24'.

  • TIMESTAMP : Både TIME och DATE. Vi kommer använda oss av formatet 'yyyy-mm-dd hh:mm:ss', exempelvis '2012-01-08 08:13:37'.

  • NULL : Avsaknaden av data.

För den som är intresserad i fler datatyper finns de här.

Villkor

Beroende på vilka datatyper man hanterar för tillfället finns olika sorters villkor man kan testa. SQL stödjer de vanliga matematiska operatorerna för att jämföra olika datatyper:

  • < : mindre än

  • > : större än

  • <= : mindre eller lika med

  • >= : större eller lika med

  • = : lika med

  • <> eller != : skiljt från (inte lika med)

Notera här en viktig skillnad från de flesta programmeringsspråk, nämligen att likhet testas med ett enkelt likhetstecken istället för dubbla. I SQL kan du inte tilldela värden med =. Det kan också vara viktigt att komma ihåg att skiljt från (inte lika med) kan skrivas <>, om du skulle läsa exempelkod någon annanstans.

För nummer jämförs, precis som i matematiken, talens storleksordning. För strängar och karaktärer jämförs de efter deras position i alfabetet (lexikografiskt ordning). TIME, DATE och DATETIME jämförs utefter tid, så vi kan avgöra om en tid är före eller efter en annan.

-- Några exempel (detta är inte riktig SQL-kod).
200 > 100  -- Sant
'a' < 'b'  -- Sant
'Hello' > 'Cello'  -- Sant
'Cello' > 'Cell'   -- Sant
'2018-01-05' > '2011-12-12'   -- Sant.  (Detta är DATE datatyper, inte strängar!)
'12:00:00' < '22:30:55'       -- Sant.  (Detta är TIME datatyper, inte strängar!)

Vi kan också testa flera villkor samtidigt genom att binda ihop dem med AND eller OR. Om vi vill att flera villkor ska vara uppfyllda använder vi AND och om vi vill endast något av villkoren ska vara uppfyllt använder vi OR. Vi kan också använda oss av NOT för att omvandla True till False och vice versa.

5 = 5 AND '08:10:35' < '13:13:37'  -- Sant.
5 = 5  OR '08:10:35' < '13:13:37'  -- Sant.
5 != 5 AND '08:10:35' < '13:13:37' -- Falskt.
5 != 5 OR  '08:10:35' < '13:13:37' -- Sant.
NOT 5 = 5  -- Falskt.
NOT 5 != 5 -- Sant.

Det kan vara svårt att se i de exempel ovan vad som är strängar och vad som är tidsdatatyper. Detta är för att tidsdatatyper representeras som en sträng, fast med ett specifikt format. När man skriver kod på riktigt jämför man aldrig konstanter på detta sätt, utan man jämför en variabel med en konstant. Eftersom man vet typen på variabeln kommer man även veta om konstanten behandlas som en sträng eller tidsdatatyp.

BETWEEN

Ett lite snyggare sätt att skriva villkor som tittar om ett tal x är inom ett spann [a, b] (exempelvis  x >= a AND x <= b), är att använda sig av BETWEEN. Detta fungerar även för strängar och tidsdatatyper. Notera att ändpunkterna är inkluderade.

5 BETWEEN 3 AND 6        -- Sant.
7 BETWEEN 3 AND 6        -- Falskt.
'c' BETWEEN 'a' AND 'd'  -- Sant.
5 BETWEEN 5 AND 6        -- Sant.

Vi kan även kontrollera det omvända, det vill säga om ett tal inte är inom ett spann, genom att skriva NOT framför. Detta är då ekvivalent som x < a OR x > b.

3 NOT BETWEEN 5 AND 8        -- Sant.
7 NOT BETWEEN 3 AND 6        -- Falskt.
'c' NOT BETWEEN 'a' AND 'd'  -- Falskt.

Unknown

I många programmeringsspråk resulterar jämförelser till antingen sant eller falskt, men i SQL kan en jämförelse även resultera i UNKNOWN. Detta händer om vi försöker jämföra något med ett NULL värde. Även att jämföra NULL = NULL kommer också resultera i UNKNOWN. På grund av detta finns ett par uttryckt som vi kan använda för att få fram ett sant eller falskt värde från ett NULL värde.

  • <expression> IS DISTINCT FROM <expression>: Testar likhet ( = ), men behandlar NULL som ett eget tal.

  • <expression> IS NOT DISTINCT FROM <expression>: Testar skillnad ( != ), men behandlar NULL som ett eget tal.

  • <expression> IS NULL : Testar om expression är NULL.

  • <expression> IS NOT NULL : Testar om expression inte är NULL.

<expression> står i detta fall står för ett uttryck som kan antingen vara ett enda värde eller ett matematiskt uttryck som resulterar i ett värde.

5 IS DISTINCT FROM NULL      		  -- Sant.
NULL IS DISTINCT FROM NULL   	      -- Falskt.
'Hello' IS NOT DISTINCT FROM 'Hello'  -- Sant.
10 IS DISTINCT FROM NULL  			  -- Falskt.

Pattern matching

För strängar kan vi använda oss av pattern matching med hjälp av nyckelordet LIKE. Med det kan vi använda oss av två specialtecken för att jämföra strängar utefter specifika mönster.

  1. % : Matcha alla sekvenser av noll eller flera tecken

  2. _ : Matcha precis ett tecken

'abc' LIKE 'ab_'  -- Sant
'abx' LIKE 'ab_'  -- Sant
'tbx' LIKE '_b_'  -- Sant
'abc' LIKE 'abc_' -- Falskt
'abc' LIKE '%'    -- Sant
'abc' LIKE 'a%'   -- Sant
'abc' LIKE '%bc'  -- Sant
'abc' LIKE 'abc%' -- Sant
'abc' LIKE '%x'   -- Falskt

Exercise

Vad kommer följande uttryck resultera i? TRUE, FALSE eller UNKNOWN?

'Good morning' < 'Good night'

'2011-02-08 22:00:20' > '2011-01-08 23:33:54'

1024 != NULL

'Good morning' LIKE 'Good _'

'NULL' IS DISTINCT FROM NULL

500 > 400 AND 400 > 500

'Hello' LIKE 'H_ll_'

'Extraordinary' LIKE '%x%'

NULL IS NOT DISTINCT FROM 500

Solution

  1. TRUE

  2. TRUE

  3. UNKNOWN

  4. FALSE

  5. TRUE

  6. FALSE

  7. TRUE

  8. TRUE

  9. FALSE

Exercise

Vilka datatyper bör du använda för dessa attribut?

  1. ålder

  2. födelsedag

  3. förnamn

  4. kod (med siffror och bokstäver på 4 tecken).

  5. är_student (sant eller falskt).

Solution

  1. INTEGER

  2. DATE

  3. VARCHAR(255) (255 är slumpmässigt valt. Så länge talet är stort nog att täcka i princip alla fall är det okej)

  4. CHAR(4)

  5. BOOL