Lär dig SQL

Back to All Courses

Lesson 6

Enkla queries

by Ted Klein Bergman

SELECT-FROM-WHERE

Den kanske vanligaste kommandot är att fråga efter attribut från en tabell baserat på något villkor. Att göra ett sådant kommando kallas att göra en query. Syntaxen ser ut likt följande:

SELECT <attributes>
FROM   <table>
WHERE  <condition>;
  • SELECT väljer ut de attribut vi vill ha från det valda tabellen, exempelvis username eller content. Attributen i SELECT måste finnas i den tabell vi valt.

  • FROM säger vilken tabell vi vill använda i vår query, exempelvis users eller tweets.

  • WHERE sållar bort de attribut som inte matchar villkoret, exempelvis username = ‘foo’ eller tweet_id = 17. Likadant här, attributen måste finnas i den tabell vi valt. Det är valfritt om vi vill använda WHERE eller inte.

Säg att vi nu vill börja med att titta på alla användare vi har lagt till och alla deras attribut. Eftersom vi inte vill sålla bort några attribut kommer vi inte att använda WHERE. Efter SELECT ska vi då lista upp alla attribut vi vill ha. En genväg till detta är att använda asterisk *, vilket betyder “alla attribut”. Den tabell vi vill hämta ifrån är users.

SELECT *
FROM users;

Detta bör returnera hela tabellen users och alla attribut.

Ett exempel på en annan query kan vara att hämta användarnamnet på den användaren som har ID:et 3. D.v.s. att vi vill välja attributet user_id, från tabellen users, där user_id = 3.

SELECT username
FROM   users
WHERE  user_id = 3;

I detta fall får vi endast ett resultat istället för en hel tabell, då det bara är en användare med detta ID (eftersom ID:et är unik).

Om vi istället gör en query för att se vilka användare som är över 40 kommer fler användare returneras, då det är fler än en användare som är över 40 år (högst sannolikt). Vi kan dessutom ha flera attribut i SELECT, allt vi behöver göra är att skriva attributen med ett kommatecken emellan. Säg att vi vill veta användarnamnet och åldern på de användare som är över 40, då kan vi göra följande query:

SELECT username, age
FROM   users
WHERE  age > 40;

Uttryck i SELECT satsen

I vår SELECT sats behöver vi inte bara lista attribut, utan vi kan även ha matematiska uttryck. Exempelvis om vi skulle vilja skriva ut året som användarna var födda skulle vi kunna skriva:

SELECT username, 2018 - age
FROM   users;

Ett problem med detta är att PostgreSQL inte vet vad det ska ge den andra kolumnen för namn, så ett namn kommer genereras åt oss. Ifall vi själva vill namnge kolumnen kan vi göra det genom att skriva nyckelordet AS och sedan ett namn. Vi kan också ändra username till name på samma sätt.

SELECT username AS name, 2018 - age AS year_born
FROM   users;

Notera dock att detta inte ändrar username till name i själva tabellen, utan bara gör det i den returnerade tabellen. Notera också att beräkningen för att få fram när användarna är födda är inte direkt en precis beräkning.

I många fall kan man få dubbletter från sin query. Säg att vi vill veta åldrarna på våra användare. Högst troligt är att många användare har samma ålder, vilket gör att vår query kommer returnera samma ålder många gånger. För att råda bot på detta kan vi använda oss av nyckelordet DISTINCT, vilket tar bort alla dubbletter.

SELECT DISTINCT age
FROM users;

ORDER BY och LIMIT

I föregående query fick vi alla åldrar från våra användare, dock var detta resultat högst sannolikt osorterad. I vissa fall vill vi att resultatet ska vara sorterat. Vi kan åstadkomma detta med att sätta en ORDER BY sats efter vår query. Detta låter oss att sortera resultatet på ett eller flera attribut.

SELECT DISTINCT age
FROM users
ORDER BY age;

Om vi sorterar på flera attribut kommer resultat först att sorteras på det första attributet, och sedan på det andra attributet för alla tuples vars första attribut är lika.

Vi kan även specificera om vi vill att resultatet ska vara sorterat i stigande eller fallande ordning med nyckelorden ASC eller DESC. Om vi inte skriver något kommer resultatet att vara sorterad i stigande ordning. Så för att göra föregående query i fallande ordning skriver vi:

SELECT DISTINCT age
FROM users
ORDER BY age DESC;

Ibland vill vi kanske bara ha ett max antal resultat tillbaka. Då kan vi lägga till en LIMIT sats efter vår query där vi specificerar hur många tuples vi vill begränsa vårat resultat till. Vi kanske bara vill ha de 10 yngsta åldrarna. Då gör vi följande query:

SELECT DISTINCT age
FROM users
ORDER BY age
LIMIT 10;

Exercise

Som ni kanske kommer ihåg skapade vi tabellen users såhär:

CREATE TABLE users (
	user_id  INTEGER  PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
	username TEXT     NOT NULL CONSTRAINT invalid_username_length CHECK(LENGTH(username) BETWEEN {USERNAME_MIN_LENGTH} AND {USERNAME_MAX_LENGTH}),
	email    TEXT     UNIQUE NOT NULL CONSTRAINT invalid_email CHECK(email LIKE '%@%.%'),
	age      INTEGER  CONSTRAINT invalid_age CHECK(age BETWEEN {USER_MIN_AGE} AND {USER_MAX_AGE})
);

Skriv en query som returnerar:

  1. Namnen och emailen på de användare som har en email som slutar på '@kth.se'.

  2. Namnen och åldern på de 3 äldsta användarna, med äldst först och yngst sist.

  3. Namnen på de användare som inte har ett 'e' i sitt användarnamn.

  4. Namnen och åldern på de användare som inte var födda 40 år sedan.

Solution

  1. SELECT username, email FROM users WHERE email LIKE '%@kth.se';

  2. SELECT username, age FROM users ORDER BY age DESC LIMIT 3;

  3. SELECT username FROM users WHERE NOT username LIKE '%e%';

  4. SELECT username, age FROM users WHERE age - 40 <= 0;