Inleiding
Om met gegevens in een database te werken, moet u specifieke records effectief kunnen ophalen en targeten. Door filterclausules in uw zoekopdrachten te gebruiken, kunt u specifieke criteria toevoegen om alleen de meest relevante records te retourneren.
In deze handleiding zullen we enkele van de meest voorkomende filterbewerkingen die beschikbaar zijn in PostgreSQL bekijken en laten zien hoe u ze kunt gebruiken om de focus van uw uitspraken te verkleinen. We zullen laten zien hoe u kunt testen op kenmerken binnen individuele records met WHERE
clausules, hoe records te groeperen om informatie samen te vatten met GROUP BY
, hoe u groepen records filtert met de HAVING
subclausule, en hoe het maximum aantal geretourneerde rijen in te stellen met de LIMIT
clausule.
De WHERE
gebruiken clausule om matchcriteria te definiëren
Een van de meest gebruikelijke en algemeen bruikbare manieren om uw vraagvereisten aan te geven, is de WHERE
clausule. De WHERE
Met de clausule kunt u werkelijke zoekcriteria voor query-instructies definiëren door voorwaarden op te geven die waar moeten zijn voor alle overeenkomende records.
WHERE
clausules werken door het definiëren van booleaanse expressies die worden gecontroleerd aan de hand van elke kandidaat-rij met gegevens. Als het resultaat van de expressie onwaar is, wordt de rij uit de resultaten verwijderd en niet geretourneerd of doorgegaan naar de volgende verwerkingsfase. Als het resultaat van de uitdrukking waar is, voldoet het aan de criteria van de zoekopdracht en wordt het verder verwerkt als kandidaat-rij.
De basissyntaxis van de WHERE
clausule ziet er als volgt uit:
SELECT * FROM my_table WHERE <condition>;
De <condition>
kan alles zijn dat resulteert in een booleaanse waarde. In PostgreSQL is een booleaanse waarde een van TRUE
, FALSE
, of NULL
.
Voorwaarden worden vaak gevormd met behulp van een of meer van de volgende operatoren:
=
:gelijk aan>
:groter dan<
:minder dan>=
:groter dan of gelijk aan<=
:kleiner dan of gelijk aan<>
of!=
:niet gelijkAND
:de logische "en" operator — voegt twee voorwaarden samen en retourneertTRUE
als beide voorwaardenTRUE
zijnOR
:logische operator "of" — voegt twee voorwaarden samen en retourneertTRUE
als ten minste één van de voorwaardenWHERE
isIN
:waarde is opgenomen in de lijst, reeks of reeks die volgtBETWEEN
:waarde is opgenomen in het bereik van de minimum- en maximumwaarden die volgen, inclusiefIS NULL
:komt overeen als waardeNULL
isNOT
:negeert de booleaanse waarde die volgtEXISTS
:de volgende zoekopdracht bevat resultatenLIKE
:komt overeen met een patroon (met de jokertekens%
overeenkomen met 0 of meer tekens en_
overeenkomen met een enkel teken)ILIKE
:komt overeen met een patroon (met de jokertekens%
overeenkomen met 0 of meer tekens en_
overeenkomen met een enkel teken), niet hoofdlettergevoeligSIMILAR TO
:komt overeen met een patroon met behulp van SQL's reguliere expressiedialect~
:komt overeen met een patroon met POSIX-reguliere expressies, hoofdlettergevoelig~*
:komt overeen met een patroon met POSIX-reguliere expressies, niet hoofdlettergevoelig!~
:komt niet overeen met een patroon dat POSIX-reguliere expressies gebruikt, hoofdlettergevoelig!~*
:komt niet overeen met een patroon dat POSIX-reguliere expressies gebruikt, niet hoofdlettergevoelig
Hoewel de bovenstaande lijst enkele van de meest voorkomende testconstructies vertegenwoordigt, zijn er veel andere operators die booleaanse resultaten opleveren die kunnen worden gebruikt in combinatie met een WHERE
clausule.
Voorbeelden met WHERE
Een van de meest voorkomende en eenvoudige controles is voor gelijkheid, met behulp van de =
exploitant. Hier controleren we of elke rij in de customer
tabel heeft een last_name
waarde gelijk aan Smith
:
SELECT * FROM customer WHERE last_name = 'Smith';
We kunnen hier extra voorwaarden aan toevoegen om samengestelde expressies te maken met behulp van logische operatoren. Dit voorbeeld gebruikt de AND
clausule om een extra test toe te voegen tegen de first_name
kolom. Geldige rijen moeten aan beide gegeven voorwaarden voldoen:
SELECT * FROM customer WHERE first_name = 'John' AND last_name = 'Smith';
Op dezelfde manier kunnen we controleren of aan een aantal voorwaarden is voldaan. Hier controleren we rijen van het address
tabel om te zien of de zip_code
waarde is gelijk aan 60626 of de neighborhood
kolom is gelijk aan de string "Roger's Park". We gebruiken twee enkele aanhalingstekens om aan te geven dat er naar een letterlijk enkel aanhalingsteken moet worden gezocht:
SELECT * FROM address WHERE zip_code = '60626' OR neighborhood = 'Roger''s Park';
De IN
operator kan werken als een vergelijking tussen een aantal waarden tussen haakjes. Als er een overeenkomst is met een van de gegeven waarden, is de uitdrukking TRUE
:
SELECT * FROM customer WHERE last_name IN ('Smith', 'Johnson', 'Fredrich');
Hier controleren we aan de hand van een tekenreekspatroon met LIKE
. De %
werkt als een jokerteken dat overeenkomt met nul of meer tekens, dus "Pete", "Peter" en elke andere tekenreeks die begint met "Pete" komt overeen met:
SELECT * FROM customer WHERE last_name LIKE 'Pete%';
We zouden een soortgelijke zoekopdracht kunnen uitvoeren met de ~*
operator om te controleren op overeenkomsten met behulp van POSIX-reguliere expressies zonder rekening te houden met hoofdletters. In dit geval controleren we of de waarde van last_name
begint met een "d" en bevat de substring "on", die overeenkomt met namen als "Dickson", "Donald" en "Devon":
SELECT * FROM customer WHERE last_name ~* '^D.*on.*';
We kunnen controleren of een huisnummer binnen het 4000 adressenblok valt met behulp van de BETWEEN
en AND
operators om een inclusief bereik te definiëren:
SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;
Hier kunnen we elke customer
. weergeven vermeldingen met burgerservicenummers die niet langer zijn dan 9 cijfers. We gebruiken de LENGTH()
operator om het aantal cijfers in het veld en de <>
. te krijgen om te controleren op ongelijkheid:
SELECT * FROM customer WHERE LENGTH(SSN) <> 9;
De GROUP BY
gebruiken clausule om meerdere records samen te vatten
De GROUP BY
clausule is een andere veel voorkomende manier om resultaten te filteren door meerdere resultaten met een enkele rij weer te geven. De basissyntaxis van de GROUP BY
clausule ziet er als volgt uit:
SELECT <columns> FROM some_table GROUP BY <columns_to_group>
Wanneer een GROUP BY
clausule wordt toegevoegd aan een instructie, vertelt het PostgreSQL om een enkele rij weer te geven voor elke unieke waarde voor de gegeven kolom of kolommen. Dit heeft enkele belangrijke implicaties.
Sinds de GROUP BY
clausule een manier is om meerdere rijen als een enkele rij weer te geven, kan PostgreSQL de query alleen uitvoeren als het een waarde kan berekenen voor elk van de kolommen die het moet weergeven. Dit betekent dat elke kolom geïdentificeerd door de SELECT
een deel van de verklaring moet ofwel zijn:
- opgenomen in de
GROUP BY
clausule om te garanderen dat elke rij een unieke waarde heeft - samengevoegd om alle rijen binnen elke groep samen te vatten
Praktisch gesproken betekent dit dat alle kolommen in de SELECT
lijst niet opgenomen in de GROUP BY
clausule moet een aggregatiefunctie gebruiken om een enkel resultaat voor de kolom voor elke groep te produceren.
Voorbeelden met GROUP BY
Stel voor de voorbeelden in deze sectie dat we een tabel hebben met de naam pet
die we als volgt hebben gedefinieerd en ingevuld:
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);
Het eenvoudigste gebruik van GROUP BY
is om het bereik van unieke waarden voor een enkele kolom weer te geven. Gebruik hiervoor dezelfde kolom in SELECT
en GROUP BY
. Hier zien we alle kleuren die in de tabel worden gebruikt:
SELECT color FROM pet GROUP BY color;
color-------- black grey brown white orange(5 rows)
Als u verder gaat dan een enkele kolom in de SELECT
kolommenlijst, moet u ofwel de kolommen toevoegen aan de GROUP BY
clausule of gebruik een aggregatiefunctie om een enkele waarde te produceren voor de groep rijen die wordt weergegeven.
Hier voegen we type
. toe naar de GROUP BY
clausule, wat betekent dat elke rij een unieke combinatie van type
. zal vertegenwoordigen en color
waarden. We voegen ook de age
. toe kolom, samengevat door de avg()
functie om de gemiddelde leeftijd van elk van de groepen te vinden:
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)
Samengevoegde functies werken net zo goed met een enkele kolom in de GROUP BY
clausule. Hier vinden we de gemiddelde leeftijd van elk type dier:
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)
Als we de oudste van elk type dier willen weergeven, kunnen we in plaats daarvan de max()
. gebruiken functie op de age
kolom. De GROUP BY
clausule vouwt de resultaten samen in dezelfde rijen als voorheen, maar de nieuwe functie wijzigt het resultaat in de andere kolom:
SELECT type, max(age) AS oldest FROM pet GROUP BY type;
type | oldest--------+------- rabbit | 8 dog | 7 cat | 8(3 rows)
De HAVING
gebruiken clausule om groepen records te filteren
De GROUP BY
clausule is een manier om gegevens samen te vatten door meerdere records in een enkele representatieve rij samen te vouwen. Maar wat als u deze groepen wilt verkleinen op basis van aanvullende factoren?
De HAVING
clausule is een modifier voor de GROUP BY
clausule waarmee u voorwaarden kunt specificeren waaraan elke groep moet voldoen om in de resultaten te worden opgenomen.
De algemene syntaxis ziet er als volgt uit:
SELECT <columns> FROM some_table GROUP BY <columns_to_group> HAVING <condition>
De bewerking lijkt erg op de WHERE
clausule, met het verschil dat WHERE
filtert afzonderlijke records en HAVING
filtert groepen records.
Voorbeelden met HAVING
Met behulp van dezelfde tabel die we in de laatste sectie hebben geïntroduceerd, kunnen we demonstreren hoe de HAVING
clausule werkt.
Hier groeperen we de rijen van de pet
tabel op unieke waarden in het type
kolom, het vinden van de minimumwaarde van age
ook. De HAVING
clausule filtert vervolgens de resultaten om groepen te verwijderen waarvan de leeftijd niet groter is dan 1:
SELECT type, min(age) AS youngest FROM pet GROUP BY type HAVING min(age) > 1;
type | youngest--------+---------- rabbit | 4 cat | 4(2 rows)
In dit voorbeeld groeperen we de rijen in pet
door hun kleur. Vervolgens filteren we de groepen die slechts één rij vertegenwoordigen. Het resultaat toont ons elke kleur die meer dan eens voorkomt:
SELECT color FROM pet GROUP BY color HAVING count(color) > 1;
color------- black brown(2 rows)
We kunnen een vergelijkbare zoekopdracht uitvoeren om de combinaties van type
. te krijgen en color
dat slechts één dier heeft:
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)
De LIMIT
gebruiken clausule om het maximum aantal records in te stellen
De LIMIT
clausule biedt een andere benadering voor het verkleinen van de records die uw query retourneert. In plaats van rijen met gegevens te elimineren op basis van criteria binnen de rij zelf, is de LIMIT
clausule stelt het maximum aantal records in dat door een query wordt geretourneerd.
De basissyntaxis van LIMIT
ziet er zo uit:
SELECT * FROM my_table LIMIT <num_rows> [OFFSET <num_rows_to_skip>];
Hier, de <num_rows>
geeft het maximale aantal rijen aan dat van de uitgevoerde query moet worden weergegeven. Dit wordt vaak gebruikt in combinatie met ORDER BY
clausules om de rijen met de meest extreme waarden in een bepaalde kolom te krijgen. Om bijvoorbeeld de vijf beste scores op een examen te behalen, kan een gebruiker ORDER BY
een score
kolom en dan LIMIT
de resultaten naar 5.
Terwijl LIMIT
telt standaard vanaf de bovenkant van de resultaten, de optionele OFFSET
trefwoord kan worden gebruikt om de startpositie die het gebruikt te compenseren. Hiermee kunt u in feite door resultaten bladeren door het aantal resultaten weer te geven dat is gedefinieerd door LIMIT
en vervolgens de LIMIT
. toe te voegen nummer naar de OFFSET
om de volgende pagina op te halen.
Voorbeelden met LIMIT
We gebruiken de pet
tabel van eerder voor de voorbeelden in deze sectie.
Zoals hierboven vermeld, LIMIT
wordt vaak gecombineerd met een ORDER BY
om de volgorde van de rijen expliciet te definiëren voordat het juiste nummer wordt gesneden. Hier sorteren we de pet
inzendingen volgens hun age
, van oudste naar jongste. We gebruiken dan LIMIT
om de top 5 oudste dieren weer te geven:
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)
Zonder een ORDER BY
clausule, LIMIT
maakt selecties op een volledig voorspelbare manier. De geretourneerde resultaten kunnen worden uitgevoerd door de volgorde van de items in de tabel of door indexen. Dit is niet altijd een slechte zaak.
Als we een record nodig hebben voor een enkele dog
in de tabel kunnen we een query als deze maken. Houd er rekening mee dat hoewel het resultaat moeilijk te voorspellen kan zijn, dit geen willekeurige selectie is en niet als zodanig mag worden gebruikt:
SELECT * FROM pet WHERE type = 'dog' LIMIT 1;
type | name | color | age | id------+------+-------+-----+---- dog | Spot | brown | 3 | 1(1 row)
We kunnen de OFFSET
. gebruiken clausule om door resultaten te bladeren. We voegen een ORDER BY
. toe clausule om een specifieke volgorde voor de resultaten te definiëren.
Voor de eerste zoekopdracht beperken we de resultaten zonder een OFFSET
. op te geven om de eerste 3 jongste inzendingen te krijgen:
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)
Om de volgende 3 jongste te krijgen, kunnen we het nummer toevoegen dat is gedefinieerd in LIMIT
naar de OFFSET
om de resultaten die we al hebben opgehaald over te slaan:
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)
Als we de LIMIT
. toevoegen naar de OFFSET
nogmaals, we krijgen de volgende 3 resultaten:
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)
Hierdoor kunnen we rijen met gegevens uit een zoekopdracht ophalen in hanteerbare brokken.
Conclusie
Er zijn veel manieren om de resultaten die u van zoekopdrachten krijgt te filteren en anderszins te beperken. Clausules zoals WHERE
en HAVING
potentiële rijen of groepen rijen evalueren om te zien of ze aan bepaalde criteria voldoen. De GROUP BY
clausule helpt u gegevens samen te vatten door records te groeperen die een of meer kolomwaarden gemeen hebben. De LIMIT
clausule biedt gebruikers de mogelijkheid om een hard maximum in te stellen voor het aantal op te halen records.
Door te leren hoe deze clausules afzonderlijk of in combinatie kunnen worden toegepast, kunt u specifieke gegevens uit grote datasets extraheren. Query-modifiers en filters zijn essentieel om de gegevens die in PostgreSQL leven om te zetten in bruikbare antwoorden.