sql >> Databáze >  >> RDS >> PostgreSQL

Jak filtrovat výsledky dotazů v PostgreSQL


Úvod

Chcete-li pracovat s daty v databázi, musíte být schopni efektivně získávat a cílit konkrétní záznamy. Pomocí filtrovacích klauzulí ve svých dotazech můžete přidat konkrétní kritéria, abyste vrátili pouze ty nejrelevantnější záznamy.

V této příručce se podíváme na některé z nejběžnějších operací filtrování dostupných v PostgreSQL a předvedeme, jak je použít k zúžení zaměření vašich příkazů. Ukážeme si, jak testovat proti charakteristikám v rámci jednotlivých záznamů pomocí WHERE klauzule, jak seskupit záznamy dohromady pro shrnutí informací pomocí GROUP BY , jak filtrovat skupiny záznamů pomocí HAVING klauzule a jak nastavit maximální počet vrácených řádků pomocí LIMIT doložka.



Pomocí WHERE klauzule k definování kritérií shody

Jedním z nejběžnějších a obecně užitečných způsobů, jak uvést požadavky na dotaz, je WHERE doložka. WHERE klauzule umožňuje definovat skutečná kritéria vyhledávání pro příkazy dotazu zadáním podmínek, které musí být pravdivé pro všechny odpovídající záznamy.

WHERE klauzule fungují tak, že definují booleovské výrazy, které se kontrolují proti každému kandidátnímu řádku dat. Pokud je výsledek výrazu nepravdivý, řádek bude z výsledků odstraněn a nebude vrácen ani nebude pokračovat do další fáze zpracování. Pokud je výsledek výrazu pravdivý, splňuje kritéria vyhledávání a bude pokračovat dalším zpracováním jako kandidátní řádek.

Základní syntaxe WHERE klauzule vypadá takto:

SELECT * FROM my_table WHERE <condition>;

<condition> může být cokoliv, co má za následek booleovskou hodnotu. V PostgreSQL je booleovská hodnota jakákoli z TRUE , FALSE , nebo NULL .

Podmínky jsou často tvořeny pomocí jednoho nebo více následujících operátorů:

  • = :rovno
  • > :větší než
  • < :méně než
  • >= :větší nebo rovno
  • <= :menší nebo rovno
  • <> nebo != :nerovná se
  • AND :logický operátor "and" — spojí dvě podmínky a vrátí TRUE pokud jsou obě podmínky TRUE
  • OR :logický operátor "nebo" — spojí dvě podmínky a vrátí TRUE pokud je alespoň jedna z podmínek TRUE
  • IN :hodnota je obsažena v seznamu, řadě nebo rozsahu, který následuje
  • BETWEEN :hodnota je obsažena v rozsahu minimálních a maximálních hodnot, které následují, včetně
  • IS NULL :odpovídá, pokud je hodnota NULL
  • NOT :neguje logickou hodnotu, která následuje
  • EXISTS :následující dotaz obsahuje výsledky
  • ILIKE :odpovídá vzoru (pomocí zástupných znaků % aby odpovídalo 0 nebo více znakům a _ aby odpovídal jednomu znaku)
  • ILIKE :odpovídá vzoru (pomocí zástupných znaků % aby odpovídalo 0 nebo více znakům a _ pro shodu s jedním znakem), nerozlišují se malá a velká písmena
  • SIMILAR TO :odpovídá vzoru pomocí dialektu regulárních výrazů SQL
  • ~ :odpovídá vzoru pomocí regulárních výrazů POSIX, rozlišují se malá a velká písmena
  • ~* :odpovídá vzoru pomocí regulárních výrazů POSIX, nerozlišují se malá a velká písmena
  • !~ :neodpovídá vzoru používajícímu regulární výrazy POSIX, rozlišují se malá a velká písmena
  • !~* :neodpovídá vzoru používajícímu regulární výrazy POSIX, nerozlišují se malá a velká písmena

Zatímco výše uvedený seznam představuje některé z nejběžnějších testovacích konstrukcí, existuje mnoho dalších operátorů, které poskytují booleovské výsledky, které lze použít ve spojení s WHERE doložka.


Příklady pomocí WHERE

Jednou z nejběžnějších a nejpřímějších kontrol je rovnost pomocí = operátor. Zde zkontrolujeme, zda každý řádek v customer tabulka má last_name hodnota se rovná Smith :

SELECT * FROM customer WHERE last_name = 'Smith';

K tomu můžeme přidat další podmínky pro vytváření složených výrazů pomocí logických operátorů. Tento příklad používá AND klauzule pro přidání dalšího testu proti first_name sloupec. Platné řádky musí splňovat obě uvedené podmínky:

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

Podobně můžeme zkontrolovat, zda je splněna některá z řady podmínek. Zde kontrolujeme řádky z address tabulka, abyste viděli, zda zip_code hodnota je rovna 60626 nebo neighborhood sloupec se rovná řetězci "Roger's Park". Používáme dvě jednoduché uvozovky k označení, že by se měla hledat doslovná jednoduchá uvozovka:

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

IN operátor může fungovat jako srovnání mezi řadou hodnot, zabalených v závorkách. Pokud existuje shoda s některou z uvedených hodnot, výraz je TRUE :

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

Zde porovnáváme vzor řetězce pomocí ILIKE . % funguje jako zástupný znak odpovídající nule nebo více znakům, takže „Pete“, „Peter“ a jakýkoli jiný řetězec začínající „Pete“ by odpovídal:

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

Mohli bychom provést podobné vyhledávání pomocí ~* operátor pro kontrolu shody pomocí regulárních výrazů POSIX bez ohledu na velikost písmen. V tomto případě zkontrolujeme, zda je hodnota last_name začíná na „d“ a obsahuje podřetězec „on“, který by odpovídal jménům jako „Dickson“, „Donald“ a „Devon“:

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

Můžeme zkontrolovat, zda se číslo ulice nachází v bloku 4000 adres pomocí BETWEEN a AND operátory k definování inkluzivního rozsahu:

SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;

Zde můžeme zobrazit libovolného customer položky, které mají čísla sociálního zabezpečení, která nejsou dlouhá 9 číslic. Používáme LENGTH() operátor pro získání počtu číslic v poli a <> pro kontrolu nerovnosti:

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



Použití GROUP BY klauzule pro shrnutí více záznamů

GROUP BY klauzule je dalším velmi běžným způsobem filtrování výsledků reprezentováním více výsledků na jednom řádku. Základní syntaxe GROUP BY klauzule vypadá takto:

SELECT <columns> FROM some_table GROUP BY <columns_to_group>

Když GROUP BY klauzule přidána do příkazu, říká PostgreSQL, aby zobrazil jeden řádek pro každou jedinečnou hodnotu pro daný sloupec nebo sloupce. To má některé důležité důsledky.

Protože GROUP BY klauzule je způsob reprezentace více řádků jako jeden řádek, PostgreSQL může provést dotaz pouze tehdy, pokud dokáže vypočítat hodnotu pro každý ze sloupců, který má za úkol zobrazit. To znamená, že každý sloupec identifikován pomocí SELECT část příkazu musí být buď:

  • zahrnuto do GROUP BY klauzule, která zaručí, že každý řádek má jedinečnou hodnotu
  • abstrakce pro shrnutí všech řádků v každé skupině

Prakticky to znamená, že všechny sloupce v SELECT seznam není součástí GROUP BY klauzule musí používat agregační funkci k vytvoření jediného výsledku pro sloupec pro každou skupinu.


Příklady pomocí GROUP BY

Pro příklady v této sekci předpokládejme, že máme tabulku nazvanou pet které jsme definovali a naplnili takto:

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);

Nejjednodušší použití GROUP BY je zobrazení rozsahu jedinečných hodnot pro jeden sloupec. Chcete-li tak učinit, použijte stejný sloupec v SELECT a GROUP BY . Zde vidíme všechny barvy použité v tabulce:

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

Když se přesunete za jeden sloupec v SELECT sloupce, musíte buď přidat sloupce do GROUP BY klauzuli nebo použijte agregační funkci k vytvoření jediné hodnoty pro skupinu reprezentovaných řádků.

Zde přidáme type do GROUP BY klauzule, což znamená, že každý řádek bude představovat jedinečnou kombinaci type a color hodnoty. Přidáme také age sloupec shrnutý pomocí avg() funkce pro zjištění průměrného věku každé ze skupin:

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)

Agregační funkce fungují stejně dobře s jedním sloupcem v GROUP BY doložka. Zde najdeme průměrný věk každého druhu zvířat:

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)

Pokud chceme zobrazit nejstarší z každého druhu zvířat, mohli bychom místo toho použít max() funkce na age sloupec. GROUP BY klauzule sbalí výsledky do stejných řádků jako dříve, ale nová funkce změní výsledek v druhém sloupci:

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



Pomocí HAVING klauzule k filtrování skupin záznamů

GROUP BY klauzule je způsob, jak shrnout data sbalením více záznamů do jednoho reprezentativního řádku. Ale co když chcete tyto skupiny zúžit na základě dalších faktorů?

HAVING klauzule je modifikátor pro GROUP BY klauzule, která vám umožní specifikovat podmínky, které musí každá skupina splnit, aby byla zahrnuta do výsledků.

Obecná syntaxe vypadá takto:

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

Operace je velmi podobná WHERE klauzule, s tím rozdílem, že WHERE filtruje jednotlivé záznamy a HAVING filtruje skupiny záznamů.


Příklady pomocí HAVING

Pomocí stejné tabulky, kterou jsme představili v minulé sekci, můžeme demonstrovat, jak HAVING doložka funguje.

Zde seskupujeme řádky pet tabulky podle jedinečných hodnot v type a najděte minimální hodnotu age také. HAVING klauzule pak filtruje výsledky, aby odstranil všechny skupiny, kde věk není větší než 1:

SELECT type, min(age) AS youngest FROM pet GROUP BY type HAVING min(age) > 1;
  type  | youngest--------+---------- rabbit |        4 cat    |        4(2 rows)

V tomto příkladu seskupujeme řádky do pet podle jejich barvy. Potom filtrujeme skupiny, které představují pouze jeden řádek. Výsledek nám ukáže každou barvu, která se objeví více než jednou:

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

Můžeme provést podobný dotaz, abychom získali kombinace type a color že pouze jedno zvíře má:

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)



Použití LIMIT klauzule pro nastavení maximálního počtu záznamů

LIMIT klauzule nabízí jiný přístup k ořezávání záznamů, které váš dotaz vrátí. Spíše než odstranění řádků dat na základě kritérií v rámci samotného řádku, LIMIT klauzule nastavuje maximální počet záznamů vrácených dotazem.

Základní syntaxe LIMIT vypadá takto:

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

Zde <num_rows> označuje maximální počet řádků k zobrazení z provedeného dotazu. Toto se často používá ve spojení s ORDER BY klauzule k získání řádků s nejextrémnějšími hodnotami v určitém sloupci. Chcete-li například získat pět nejlepších skóre u zkoušky, může uživatel ORDER BY score a poté LIMIT výsledky do 5.

Zatímco LIMIT ve výchozím nastavení se počítá od začátku výsledků, volitelný OFFSET klíčové slovo lze použít ke kompenzaci výchozí pozice, kterou používá. Ve skutečnosti vám to umožňuje stránkovat výsledky zobrazením počtu výsledků definovaných LIMIT a poté přidání LIMIT číslo do OFFSET k načtení následující stránky.


Příklady pomocí LIMIT

Použijeme pet pro příklady v této sekci.

Jak je uvedeno výše, LIMIT se často kombinuje s ORDER BY klauzule k explicitnímu definování pořadí řádků před rozdělením příslušného počtu. Zde třídíme pet položky podle jejich age , od nejstarších po nejmladší. Potom použijeme LIMIT pro zobrazení 5 nejstarších zvířat:

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)

Bez ORDER BY klauzule, LIMIT provede výběr zcela předvídatelným způsobem. Vrácené výsledky mohou být ovlivněny pořadím položek v tabulce nebo indexy. To není vždy špatná věc.

Pokud potřebujeme záznam pro jakéhokoli jednotlivého dog v tabulce bychom mohli vytvořit dotaz takto. Mějte na paměti, že ačkoli může být obtížné předvídat výsledek, nejedná se o náhodný výběr a neměl by být jako takový používán:

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

Můžeme použít OFFSET klauzule pro stránkování výsledků. Zahrnujeme ORDER BY klauzule k definování konkrétního pořadí výsledků.

U prvního dotazu omezíme výsledky bez zadání OFFSET získat první 3 nejmladší příspěvky:

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)

Abychom získali další 3 nejmladší, můžeme přidat číslo definované v LIMIT na OFFSET přeskočit výsledky, které jsme již získali:

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)

Pokud přidáme LIMIT na OFFSET opět získáme další 3 výsledky:

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)

To nám umožňuje načíst řádky dat z dotazu ve spravovatelných blocích.




Závěr

Existuje mnoho způsobů, jak filtrovat a jinak omezit výsledky, které získáte z dotazů. Klauzule jako WHERE a HAVING vyhodnotit potenciální řádky nebo skupiny řádků a zjistit, zda splňují určitá kritéria. GROUP BY klauzule vám pomůže shrnout data seskupením záznamů, které mají jednu nebo více hodnot sloupců společných. LIMIT klauzule nabízí uživatelům možnost nastavit pevné maximum počtu záznamů k načtení.

Naučte se, jak lze tyto klauzule aplikovat, jednotlivě nebo v kombinaci, vám umožní extrahovat konkrétní data z velkých datových sad. Modifikátory dotazů a filtry jsou nezbytné pro přeměnu dat, která žijí v PostgreSQL, na užitečné odpovědi.




  1. Jak vyřešit chybu `prisma/klient se ještě neinicializoval` na Vercelu

  2. Oracle 10g přijímá 5místný rok v datu

  3. SQL Server REPLACE() vs TRANSLATE():Jaké jsou rozdíly?

  4. Skrytí skutečného ID databázového objektu v adresách URL