Introduktion
For at arbejde med data i en database skal du være i stand til at hente og målrette specifikke poster effektivt. Ved at bruge filtreringsklausuler i dine forespørgsler kan du tilføje specifikke kriterier for kun at returnere de mest relevante poster.
I denne vejledning vil vi tage et kig på nogle af de mest almindelige filtreringsoperationer, der er tilgængelige i PostgreSQL, og demonstrere, hvordan du bruger dem til at indsnævre fokus i dine udsagn. Vi vil vise, hvordan man tester mod karakteristika i individuelle poster med WHERE
klausuler, hvordan man grupperer poster sammen for at opsummere information med GROUP BY
, hvordan man filtrerer grupper af poster med HAVING
underklausul, og hvordan man indstiller det maksimale antal returnerede rækker med LIMIT
klausul.
Brug af WHERE
klausul til at definere matchkriterier
En af de mest almindelige og generelt nyttige måder at angive dine forespørgselskrav på er WHERE
klausul. WHERE
klausul lader dig definere faktiske søgekriterier for forespørgselsudsagn ved at angive betingelser, der skal være sande for alle matchende poster.
HVOR
klausuler fungerer ved at definere booleske udtryk, der kontrolleres mod hver kandidatrække af data. Hvis resultatet af udtrykket er falsk, vil rækken blive fjernet fra resultaterne og vil ikke blive returneret eller fortsætte til næste behandlingstrin. Hvis resultatet af udtrykket er sandt, opfylder det kriterierne for søgningen og vil fortsætte til enhver yderligere behandling som en kandidatrække.
Den grundlæggende syntaks for WHERE
klausul ser sådan ud:
SELECT * FROM my_table WHERE <condition>;
kan være alt, der resulterer i en boolsk værdi. I PostgreSQL er en boolesk værdi en hvilken som helst af TRUE
, FALSK
eller NULL
.
Betingelser dannes ofte ved hjælp af en eller flere af følgende operatorer:
=
:lig med> :større end
<
:mindre end>=
:større end eller lig med<=
:mindre end eller lig med<> eller
!=
:ikke ensOG
:den logiske "og"-operator — forbinder to betingelser og returnererTRUE
hvis begge betingelser erTRUE
ELLER
:logisk "eller"-operator — forbinder to betingelser og returnererTRUE
hvis mindst en af betingelserne erTRUE
IN
:værdien er indeholdt i listen, serien eller området, der følgerMELLEM
:værdi er indeholdt inden for intervallet de minimums- og maksimumværdier, der følger, inklusiveER NULL
:matcher, hvis værdien erNULL
IKKE
:negerer den boolske værdi, der følgerFINDER
:den følgende forespørgsel indeholder resultaterLIKE
:matcher mod et mønster (ved hjælp af jokertegnene%
for at matche 0 eller flere tegn og_
for at matche et enkelt tegn)ILIKE
:matcher mod et mønster (ved hjælp af jokertegnene%
for at matche 0 eller flere tegn og_
for at matche et enkelt tegn), ufølsom mellem store og små bogstaverLIGER MED
:matcher mod et mønster ved hjælp af SQL's regulære udtryksdialekt~
:matcher mod et mønster ved hjælp af regulære POSIX-udtryk, der skelnes mellem store og små bogstaver~*
:matcher mod et mønster ved hjælp af regulære POSIX-udtryk, ufølsom mellem store og små bogstaver!~
:stemmer ikke overens med et mønster ved hjælp af regulære POSIX-udtryk, der skelnes mellem store og små bogstaver!~*
:stemmer ikke overens med et mønster ved hjælp af regulære POSIX-udtryk, uafhængig af store og små bogstaver
Selvom ovenstående liste repræsenterer nogle af de mest almindelige testkonstruktioner, er der mange andre operatorer, der giver booleske resultater, som kan bruges sammen med en WHERE
klausul.
Eksempler, der bruger WHERE
En af de mest almindelige og ligefremme kontroller er lighed ved at bruge =
operatør. Her tjekker vi, om hver række i kunden
tabellen har en efternavn
værdi lig med Smith
:
SELECT * FROM customer WHERE last_name = 'Smith';
Vi kan tilføje yderligere betingelser til dette for at skabe sammensatte udtryk ved hjælp af logiske operatorer. Dette eksempel bruger AND
klausul for at tilføje en yderligere test mod fornavn
kolonne. Gyldige rækker skal opfylde begge de givne betingelser:
SELECT * FROM customer WHERE first_name = 'John' AND last_name = 'Smith';
På samme måde kan vi kontrollere, om nogen af en række betingelser er opfyldt. Her tjekker vi rækker fra adressen
tabel for at se, om zip_code
værdien er lig med 60626 eller kvarteret
kolonne er lig med strengen "Rogers Park". Vi bruger to enkelte anførselstegn for at angive, at der skal søges efter et bogstaveligt enkelt citat:
SELECT * FROM address WHERE zip_code = '60626' OR neighborhood = 'Roger''s Park';
IN
operator kan fungere som en sammenligning mellem en række værdier, pakket ind i parentes. Hvis der er et match med nogen af de givne værdier, er udtrykket TRUE
:
SELECT * FROM customer WHERE last_name IN ('Smith', 'Johnson', 'Fredrich');
Her tjekker vi mod et strengmønster ved hjælp af LIKE
. %
fungerer som et jokertegn, der matcher nul eller flere tegn, så "Pete", "Peter" og enhver anden streng, der begynder med "Pete" ville matche:
SELECT * FROM customer WHERE last_name LIKE 'Pete%';
Vi kunne lave en lignende søgning ved at bruge ~*
operatør for at kontrollere for match ved hjælp af POSIX regulære udtryk uden hensyn til store og små bogstaver. I dette tilfælde kontrollerer vi, om værdien af last_name
begynder med et "d" og indeholder understrengen "on", som ville matche navne som "Dickson", "Donald" og "Devon":
SELECT * FROM customer WHERE last_name ~* '^D.*on.*';
Vi kan kontrollere, om et gadenummer er inden for 4000-blokken af adresser ved hjælp af BETWEEN
og OG
operatører til at definere et inkluderende område:
SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;
Her kan vi vise enhver kunde
poster, der har personnumre, der ikke er 9 cifre. Vi bruger LENGTH()
operatør for at få antallet af cifre i feltet og
SELECT * FROM customer WHERE LENGTH(SSN) <> 9;
Brug af GROUP BY
klausul for at opsummere flere poster
GROUP BY
klausul er en anden meget almindelig måde at filtrere resultater på ved at repræsentere flere resultater med en enkelt række. Den grundlæggende syntaks for GROUP BY
klausul ser sådan ud:
SELECT <columns> FROM some_table GROUP BY <columns_to_group>
Når en GROUP BY
klausul føjes til en sætning, fortæller den PostgreSQL at vise en enkelt række for hver unik værdi for den eller de givne kolonner. Dette har nogle vigtige konsekvenser.
Siden GROUP BY
klausul er en måde at repræsentere flere rækker på som en enkelt række, PostgreSQL kan kun udføre forespørgslen, hvis den kan beregne en værdi for hver af de kolonner, den har til opgave at vise. Det betyder, at hver kolonne identificeres med SELECT
del af erklæringen skal enten være:
- inkluderet i
GROUP BY
klausul for at garantere, at hver række har en unik værdi - abstrakt for at opsummere alle rækkerne i hver gruppe
Rent praktisk betyder det, at alle kolonner i SELECT
listen ikke inkluderet i GROUP BY
klausul skal bruge en aggregeret funktion til at producere et enkelt resultat for kolonnen for hver gruppe.
Eksempler, der bruger GROUP BY
For eksemplerne i dette afsnit, antag, at vi har en tabel kaldet kæledyr
som vi har defineret og udfyldt sådan:
CREATE TABLE pet ( id SERIAL PRIMARY KEY, type TEXT, name TEXT, color TEXT, age INT);INSERT INTO pet (type, name, color, age) VALUES('dog', 'Spot', 'brown', 3),('dog', 'Rover', 'black', 7),('dog', 'Sally', 'brown', 1),('cat', 'Sabrina', 'black', 8),('cat', 'Felix', 'white', 4),('cat', 'Simon', 'orange', 8),('rabbit', 'Buttons', 'grey', 4),('rabbit', 'Bunny', 'brown', 8),('rabbit', 'Briony', 'brown', 6);
Den enkleste brug af GROUP BY
er at vise rækken af unikke værdier for en enkelt kolonne. For at gøre det skal du bruge den samme kolonne i SELECT
og GRUPPER EFTER
. Her ser vi alle de farver, der er brugt i tabellen:
SELECT color FROM pet GROUP BY color;
color-------- black grey brown white orange(5 rows)
Når du bevæger dig ud over en enkelt kolonne i SELECT
kolonnelisten, skal du enten tilføje kolonnerne til GROUP BY
klausul eller brug en aggregeret funktion til at producere en enkelt værdi for gruppen af rækker, der repræsenteres.
Her tilføjer vi type
til GROUP BY
klausul, hvilket betyder, at hver række vil repræsentere en unik kombination af type
og farve
værdier. Vi tilføjer også alder
kolonne, opsummeret med avg()
funktion til at finde gennemsnitsalderen for hver af grupperne:
SELECT type, color, avg(age) AS average_age FROM pet GROUP BY type, color;
type | color | average_age--------+--------+-------------------- rabbit | brown | 7.0000000000000000 cat | black | 8.0000000000000000 rabbit | grey | 4.0000000000000000 dog | black | 7.0000000000000000 dog | brown | 2.0000000000000000 cat | orange | 8.0000000000000000 cat | white | 4.0000000000000000(7 rows)
Aggregerede funktioner fungerer lige så godt med en enkelt kolonne i GROUP BY
klausul. Her finder vi gennemsnitsalderen for hver type dyr:
SELECT type, avg(age) AS average_age FROM PET GROUP BY type;
type | average_age--------+-------------------- rabbit | 6.0000000000000000 dog | 3.6666666666666667 cat | 6.6666666666666667(3 rows)
Hvis vi vil vise den ældste af hver type dyr, kunne vi i stedet bruge max()
funktion på alder
kolonne. GROUP BY
klausul skjuler resultaterne i de samme rækker som før, men den nye funktion ændrer resultatet i den anden kolonne:
SELECT type, max(age) AS oldest FROM pet GROUP BY type;
type | oldest--------+------- rabbit | 8 dog | 7 cat | 8(3 rows)
Brug af HAVING
klausul for at filtrere grupper af poster
GROUP BY
klausul er en måde at opsummere data ved at skjule flere poster i en enkelt repræsentativ række. Men hvad hvis du vil indsnævre disse grupper baseret på yderligere faktorer?
HAVING
klausul er en modifikator for GROUP BY
klausul, der lader dig specificere betingelser, som hver gruppe skal opfylde for at blive inkluderet i resultaterne.
Den generelle syntaks ser således ud:
SELECT <columns> FROM some_table GROUP BY <columns_to_group> HAVING <condition>
Operationen ligner meget WHERE
klausul, med forskellen at WHERE
filtrerer enkelte poster og HAVING
filtrerer grupper af poster.
Eksempler, der bruger HAVING
Ved at bruge den samme tabel, som vi introducerede i sidste afsnit, kan vi demonstrere, hvordan HAVING
klausul virker.
Her grupperer vi rækkerne af kæledyret
tabel efter unikke værdier i type
kolonne for at finde minimumsværdien for alder
såvel. HAVING
klausul filtrerer derefter resultaterne for at fjerne grupper, hvor alderen ikke er større end 1:
SELECT type, min(age) AS youngest FROM pet GROUP BY type HAVING min(age) > 1;
type | youngest--------+---------- rabbit | 4 cat | 4(2 rows)
I dette eksempel grupperer vi rækkerne i kæledyr
efter deres farve. Vi filtrerer derefter de grupper, der kun repræsenterer en enkelt række. Resultatet viser os hver farve, der vises mere end én gang:
SELECT color FROM pet GROUP BY color HAVING count(color) > 1;
color------- black brown(2 rows)
Vi kan udføre en lignende forespørgsel for at få kombinationerne af type
og farve
at kun et enkelt dyr har:
SELECT type, color FROM pet GROUP BY type, color HAVING count(color) = 1;
type | color--------+-------- cat | black rabbit | grey dog | black cat | orange cat | white(5 rows)
Brug af LIMIT
klausul for at indstille det maksimale antal poster
LIMIT
klausul tilbyder en anden tilgang til at nedskære de poster, din forespørgsel returnerer. I stedet for at fjerne rækker af data baseret på kriterier i selve rækken, er LIMIT
klausul angiver det maksimale antal poster, der returneres af en forespørgsel.
Den grundlæggende syntaks for LIMIT
ser sådan ud:
SELECT * FROM my_table LIMIT <num_rows> [OFFSET <num_rows_to_skip>];
Her er
angiver det maksimale antal rækker, der skal vises fra den udførte forespørgsel. Dette bruges ofte sammen med ORDER BY
klausuler for at få rækkerne med de mest ekstreme værdier i en bestemt kolonne. For f.eks. at få de fem bedste karakterer på en eksamen kan en bruger ORDER BY
en score
kolonne og derefter LIMIT
resultaterne til 5.
Mens LIMIT
tæller fra toppen af resultaterne som standard, den valgfri OFFSET
nøgleord kan bruges til at udligne den startposition, den bruger. Faktisk giver dette dig mulighed for at paginere gennem resultater ved at vise antallet af resultater defineret af LIMIT
og derefter tilføje LIMIT
nummer til OFFSET
for at hente den følgende side.
Eksempler, der bruger LIMIT
Vi bruger kæledyret
tabel fra tidligere for eksemplerne i dette afsnit.
Som nævnt ovenfor, LIMIT
er ofte kombineret med en ORDER BY
klausul for eksplicit at definere rækkefølgen af rækkerne, før det passende nummer opdeles. Her sorterer vi kæledyret
poster i henhold til deres alder
, fra ældste til yngste. Vi bruger derefter LIMIT
for at vise top 5 ældste dyr:
SELECT * FROM pet ORDER BY age DESC LIMIT 5;
type | name | color | age | id--------+---------+--------+-----+---- cat | Simon | orange | 8 | 6 cat | Sabrina | black | 8 | 4 rabbit | Bunny | brown | 8 | 8 dog | Rover | black | 7 | 2 rabbit | Briany | brown | 6 | 9(5 rows)
Uden en ORDER BY
klausul, LIMIT
vil foretage valg på en fuldstændig forudsigelig måde. De returnerede resultater kan påvirkes af rækkefølgen af indtastningerne i tabellen eller af indekser. Dette er ikke altid en dårlig ting.
Hvis vi har brug for en registrering for en enkelt hund
i tabellen kunne vi konstruere en forespørgsel som denne. Husk, at selvom resultatet kan være svært at forudsige, er dette ikke et tilfældigt udvalg og bør ikke bruges som sådan:
SELECT * FROM pet WHERE type = 'dog' LIMIT 1;
type | name | color | age | id------+------+-------+-----+---- dog | Spot | brown | 3 | 1(1 row)
Vi kan bruge OFFSET
klausul for at paginere gennem resultater. Vi inkluderer en ORDER BY
klausul for at definere en specifik rækkefølge for resultaterne.
For den første forespørgsel begrænser vi resultaterne uden at angive en OFFSET
for at få de første 3 yngste bidrag:
SELECT * FROM pet ORDER BY age LIMIT 3;
type | name | color | age | id------+-------+-------+-----+---- dog | Sally | brown | 1 | 3 dog | Spot | brown | 3 | 1 cat | Felix | white | 4 | 5(3 rows)
For at få de næste 3 yngste kan vi tilføje tallet defineret i LIMIT
til OFFSET
for at springe de resultater over, vi allerede har hentet:
SELECT * FROM pet ORDER BY age LIMIT 3 OFFSET 3;
type | name | color | age | id --------+---------+-------+-----+---- rabbit | Buttons | grey | 4 | 7 rabbit | Briany | brown | 6 | 9 dog | Rover | black | 7 | 2(3 rows)
Hvis vi tilføjer LIMIT
til OFFSET
igen, vi får de næste 3 resultater:
SELECT * FROM pet ORDER BY age LIMIT 3 OFFSET 6;
type | name | color | age | id--------+---------+--------+-----+---- cat | Simon | orange | 8 | 6 rabbit | Bunny | brown | 8 | 8 cat | Sabrina | black | 8 | 4(3 rows)
Dette lader os hente rækker af data fra en forespørgsel i håndterbare bidder.
Konklusion
Der er mange måder at filtrere og på anden måde begrænse de resultater, du får fra forespørgsler. Klausuler som WHERE
og HAR
evaluere potentielle rækker eller grupper af rækker for at se, om de opfylder bestemte kriterier. GROUP BY
klausul hjælper dig med at opsummere data ved at gruppere poster, der har en eller flere kolonneværdier til fælles. LIMIT
klausul giver brugerne mulighed for at sætte et hårdt maksimum på antallet af poster, der skal hentes.
At lære, hvordan disse klausuler kan anvendes, individuelt eller i kombination, vil give dig mulighed for at udtrække specifikke data fra store datasæt. Forespørgselsmodifikatorer og filtre er afgørende for at omdanne de data, der findes i PostgreSQL, til nyttige svar.