sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man filtrerar frågeresultat i PostgreSQL


Introduktion

För att arbeta med data i en databas måste du kunna hämta och rikta in specifika poster effektivt. Genom att använda filtreringssatser i dina frågor kan du lägga till specifika kriterier för att endast returnera de mest relevanta posterna.

I den här guiden kommer vi att ta en titt på några av de vanligaste filtreringsoperationerna som finns tillgängliga inom PostgreSQL och visa hur man använder dem för att begränsa fokus för dina uttalanden. Vi kommer att visa hur man testar mot egenskaper inom individuella poster med WHERE satser, hur man grupperar poster för att sammanfatta information med GROUP BY , hur man filtrerar grupper av poster med HAVING underklausul och hur man ställer in det maximala antalet returnerade rader med LIMIT klausul.



Använda WHERE sats för att definiera matchningskriterier

Ett av de vanligaste och allmänt användbara sätten att ange dina frågekrav är WHERE klausul. WHERE sats låter dig definiera faktiska sökkriterier för frågesatser genom att ange villkor som måste vara sanna för alla matchande poster.

VAR satser fungerar genom att definiera booleska uttryck som kontrolleras mot varje kandidatrad med data. Om resultatet av uttrycket är falskt kommer raden att tas bort från resultaten och kommer inte att returneras eller fortsätta till nästa steg av bearbetningen. Om resultatet av uttrycket är sant, uppfyller det kriterierna för sökningen och kommer att fortsätta för ytterligare bearbetning som en kandidatrad.

Den grundläggande syntaxen för WHERE klausul ser ut så här:

SELECT * FROM my_table WHERE <condition>;

kan vara vad som helst som resulterar i ett booleskt värde. I PostgreSQL är ett booleskt värde något av TRUE , FALSKT , eller NULL .

Villkor skapas ofta med en eller flera av följande operatorer:

  • = :lika med
  • > :större än
  • < :mindre än
  • >= :större än eller lika med
  • <= :mindre än eller lika med
  • <> eller != :inte lika
  • OCH :den logiska "och"-operatorn — förenar två villkor och returnerar TRUE om båda villkoren är TRUE
  • ELLER :logisk "eller"-operator — sammanfogar två villkor och returnerar TRUE om minst ett av villkoren är TRUE
  • IN :värdet finns i listan, serien eller intervallet som följer
  • MELLAN :värde finns inom intervallet de lägsta och högsta värdena som följer, inklusive
  • ÄR NULL :matchar om värdet är NULL
  • INTE :negerar det booleska värdet som följer
  • FINNS :frågan som följer innehåller resultat
  • GILLA :matchar mot ett mönster (med jokertecken % för att matcha 0 eller fler tecken och __ för att matcha ett enstaka tecken)
  • ILIKE :matchar mot ett mönster (med jokertecken % för att matcha 0 eller fler tecken och __ för att matcha ett enstaka tecken), skiftlägesokänslig
  • LIKER MED :matchar mot ett mönster med SQLs dialekt för reguljära uttryck
  • ~ :matchar mot ett mönster med POSIX reguljära uttryck, skiftlägeskänsliga
  • ~* :matchar mot ett mönster med POSIX reguljära uttryck, skiftlägesokänslig
  • !~ :matchar inte mot ett mönster som använder POSIX reguljära uttryck, skiftlägeskänsliga
  • !~* :matchar inte mot ett mönster som använder POSIX reguljära uttryck, skiftlägesokänslig

Även om listan ovan representerar några av de vanligaste testkonstruktionerna, finns det många andra operatorer som ger booleska resultat som kan användas tillsammans med en WHERE klausul.


Exempel som använder WHERE

En av de vanligaste och enklaste kontrollerna är för jämlikhet, med hjälp av = operatör. Här kontrollerar vi om varje rad i kunden tabellen har ett efternamn värde lika med Smith :

SELECT * FROM customer WHERE last_name = 'Smith';

Vi kan lägga till ytterligare villkor för att skapa sammansatta uttryck med logiska operatorer. Det här exemplet använder AND sats för att lägga till ett ytterligare test mot first_name kolumn. Giltiga rader måste uppfylla båda de angivna villkoren:

SELECT * FROM customer WHERE first_name = 'John' AND last_name = 'Smith';

På samma sätt kan vi kontrollera om något av en rad villkor är uppfyllda. Här kontrollerar vi rader från adressen tabell för att se om zip_code värdet är lika med 60626 eller grannskapet kolumn är lika med strängen "Rogers Park". Vi använder två enkla citattecken för att indikera att ett bokstavligt enstaka citattecken ska sökas efter:

SELECT * FROM address WHERE zip_code = '60626' OR neighborhood = 'Roger''s Park';

IN operatorn kan fungera som en jämförelse mellan ett antal värden, inslagna inom parentes. Om det finns en matchning med något av de givna värdena är uttrycket TRUE :

SELECT * FROM customer WHERE last_name IN ('Smith', 'Johnson', 'Fredrich');

Här kontrollerar vi mot ett strängmönster med LIKE . % fungerar som ett jokertecken som matchar noll eller fler tecken, så "Pete", "Peter" och alla andra strängar som börjar med "Pete" skulle matcha:

SELECT * FROM customer WHERE last_name LIKE 'Pete%';

Vi skulle kunna göra en liknande sökning med ~* operatorn för att söka efter matchningar med POSIX reguljära uttryck utan hänsyn till skiftläge. I det här fallet kontrollerar vi om värdet för last_name börjar med ett "d" och innehåller delsträngen "on", som skulle matcha namn som "Dickson", "Donald" och "Devon":

SELECT * FROM customer WHERE last_name ~* '^D.*on.*';

Vi kan kontrollera om ett gatunummer finns inom 4000-blocket med adresser med hjälp av BETWEEN och OCH operatörer för att definiera ett inkluderande intervall:

SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;

Här kan vi visa vilken kund som helst poster som har personnummer som inte är 9 siffror långa. Vi använder LENGTH() operatorn för att få antalet siffror i fältet och <> för att kontrollera ojämlikhet:

SELECT * FROM customer WHERE LENGTH(SSN) <> 9;



Använda GROUP BY klausul för att sammanfatta flera poster

GROUP BY klausul är ett annat mycket vanligt sätt att filtrera resultat genom att representera flera resultat med en enda rad. Den grundläggande syntaxen för GROUP BY klausul ser ut så här:

SELECT <columns> FROM some_table GROUP BY <columns_to_group>

När en GROUP BY sats läggs till i en sats, säger den till PostgreSQL att visa en enda rad för varje unikt värde för den givna kolumnen eller kolumnerna. Detta har några viktiga konsekvenser.

Sedan GROUP BY sats är ett sätt att representera flera rader som en enda rad, PostgreSQL kan bara exekvera frågan om den kan beräkna ett värde för var och en av kolumnerna som den har till uppgift att visa. Detta innebär att varje kolumn identifieras av SELECT del av uttalandet måste antingen vara:

  • ingår i GROUP BY klausul för att garantera att varje rad har ett unikt värde
  • abstrakt för att sammanfatta alla rader inom varje grupp

Praktiskt sett betyder det att alla kolumner i SELECT listan ingår inte i GROUP BY sats måste använda en aggregatfunktion för att producera ett enda resultat för kolumnen för varje grupp.


Exempel som använder GROUP BY

För exemplen i det här avsnittet, anta att vi har en tabell som heter pet som vi har definierat och fyllt i så här:

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 enklaste användningen av GROUP BY är att visa intervallet av unika värden för en enskild kolumn. För att göra det, använd samma kolumn i SELECT och GROUP BY . Här ser vi alla färger som används i tabellen:

SELECT color FROM pet GROUP BY color;
 color-------- black grey brown white orange(5 rows)

När du går bortom en enskild kolumn i SELECT kolumnlistan måste du antingen lägga till kolumnerna i GROUP BY sats eller använd en aggregatfunktion för att skapa ett enda värde för gruppen av rader som representeras.

Här lägger vi till typ till GROUP BY sats, vilket betyder att varje rad kommer att representera en unik kombination av typ och färg värden. Vi lägger också till ålder kolumn, sammanfattad med avg() funktion för att hitta medelåldern för var och en av grupperna:

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)

Aggregatfunktioner fungerar lika bra med en enda kolumn i GROUP BY klausul. Här hittar vi medelåldern för varje typ av djur:

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)

Om vi ​​vill visa den äldsta av varje typ av djur kan vi istället använda max() funktion på ålder kolumn. GROUP BY sats komprimerar resultaten i samma rader som tidigare, men den nya funktionen ändrar resultatet i den andra kolumnen:

SELECT type, max(age) AS oldest FROM pet GROUP BY type;
  type  | oldest--------+------- rabbit |     8 dog    |     7 cat    |     8(3 rows)



Använda HAVING sats för att filtrera grupper av poster

GROUP BY klausul är ett sätt att sammanfatta data genom att komprimera flera poster till en enda representativ rad. Men vad händer om du vill begränsa dessa grupper baserat på ytterligare faktorer?

HAVING satsen är en modifierare för GROUP BY klausul som låter dig specificera villkor som varje grupp måste uppfylla för att inkluderas i resultaten.

Den allmänna syntaxen ser ut så här:

SELECT <columns> FROM some_table GROUP BY <columns_to_group> HAVING <condition>

Operationen är mycket lik WHERE klausul, med skillnaden att WHERE filtrerar enskilda poster och HAVING filtrerar grupper av poster.


Exempel som använder HAVING

Med samma tabell som vi introducerade i det förra avsnittet kan vi visa hur HAVING klausul fungerar.

Här grupperar vi raderna för husdjuret tabell efter unika värden i type kolumnen, hitta minimivärdet för ålder också. HAVING klausul filtrerar sedan resultaten för att ta bort alla grupper där åldern inte är högre än 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 det här exemplet grupperar vi raderna i pet efter deras färg. Vi filtrerar sedan de grupper som bara representerar en enda rad. Resultatet visar oss varje färg som visas mer än en gång:

SELECT color FROM pet GROUP BY color HAVING count(color) > 1;
 color------- black brown(2 rows)

Vi kan utföra en liknande fråga för att få kombinationerna av typ och färg att endast ett enda djur 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)



Använda LIMIT sats för att ställa in det maximala antalet poster

LIMIT klausulen erbjuder ett annat tillvägagångssätt för att minska de poster som din fråga returnerar. Istället för att eliminera rader med data baserat på kriterier inom själva raden, är LIMIT sats anger det maximala antalet poster som returneras av en fråga.

Den grundläggande syntaxen för LIMIT ser ut så här:

SELECT * FROM my_table LIMIT <num_rows> [OFFSET <num_rows_to_skip>];

Här är anger det maximala antalet rader som ska visas från den körda frågan. Detta används ofta tillsammans med ORDER BY satser för att få raderna med de mest extrema värdena i en viss kolumn. Till exempel, för att få de fem bästa poängen på ett prov kan en användare ORDER BY en poäng kolumn och sedan LIMIT resultaten till 5.

Medan LIMIT räknas från toppen av resultaten som standard, den valfria OFFSET nyckelordet kan användas för att förskjuta startpositionen den använder. I själva verket låter detta dig sidställa genom resultat genom att visa antalet resultat som definieras av LIMIT och lägg sedan till LIMIT nummer till OFFSET för att hämta följande sida.


Exempel som använder LIMIT

Vi kommer att använda pet tabell från tidigare för exemplen i detta avsnitt.

Som nämnts ovan, LIMIT kombineras ofta med en ORDER BY klausul för att uttryckligen definiera ordningen för raderna innan du delar upp det lämpliga numret. Här sorterar vi husdjuret poster enligt deras ålder , från äldst till yngst. Vi använder sedan LIMIT för att visa de 5 äldsta djuren:

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)

Utan en ORDER BY klausul, LIMIT kommer att göra urval på ett helt förutsägbart sätt. Resultaten som returneras kan påverkas av ordningen på posterna i tabellen eller av index. Detta är inte alltid en dålig sak.

Om vi ​​behöver en post för någon enskild hund i tabellen kan vi konstruera en fråga som denna. Tänk på att även om resultatet kan vara svårt att förutsäga, är detta inte ett slumpmässigt urval och bör inte användas som sådant:

SELECT * FROM pet WHERE type = 'dog' LIMIT 1;
 type | name | color | age | id------+------+-------+-----+---- dog  | Spot | brown |   3 |  1(1 row)

Vi kan använda OFFSET klausul för att paginera genom resultat. Vi inkluderar en ORDER BY klausul för att definiera en specifik ordning för resultaten.

För den första frågan begränsar vi resultaten utan att ange en OFFSET för att få de tre första yngsta bidragen:

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)

För att få nästa 3 yngsta kan vi lägga till numret som definieras i LIMIT till OFFSET för att hoppa över resultaten vi redan har hämtat:

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)

Om vi ​​lägger till LIMIT till OFFSET igen, vi får de kommande 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)

Detta låter oss hämta rader med data från en fråga i hanterbara bitar.




Slutsats

Det finns många sätt att filtrera och på annat sätt begränsa resultaten du får från frågor. Klausuler som WHERE och HAV utvärdera potentiella rader eller grupper av rader för att se om de uppfyller vissa kriterier. GROUP BY sats hjälper dig att sammanfatta data genom att gruppera poster som har ett eller flera kolumnvärden gemensamma. LIMIT klausulen ger användarna möjligheten att sätta ett hårt maximum för antalet poster som ska hämtas.

Genom att lära dig hur dessa klausuler kan tillämpas, individuellt eller i kombination, kan du extrahera specifik data från stora datamängder. Frågemodifierare och filter är viktiga för att omvandla data som finns i PostgreSQL till användbara svar.




  1. Hur man gör punkt-i-tid-återställning av MySQL- och MariaDB-data med ClusterControl

  2. Hur man skapar användare i Oracle och tilldelar privilegier

  3. Har inte databaslås! i android

  4. Hur man ignorerar fel med psql \copy meta-kommando