PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да филтрирате резултатите от заявката в PostgreSQL


Въведение

За да работите с данни в база данни, трябва да можете ефективно да извличате и насочвате конкретни записи. Като използвате клаузи за филтриране във вашите заявки, можете да добавите конкретни критерии, за да върнете само най-подходящите записи.

В това ръководство ще разгледаме някои от най-често срещаните филтриращи операции, налични в PostgreSQL, и ще покажем как да ги използвате, за да стесните фокуса на вашите изявления. Ще покажем как да тестваме спрямо характеристики в отделни записи с WHERE клаузи, как да групирате записи заедно, за да обобщите информация с GROUP BY , как да филтрирате групи от записи с HAVING подклауза и как да зададете максималния брой върнати редове с LIMIT клауза.



Използване на WHERE клауза за дефиниране на критерии за съвпадение

Един от най-често срещаните и широко полезни начини да посочите изискванията на заявката си е WHERE клауза. WHERE клаузата ви позволява да дефинирате действителни критерии за търсене на изрази за заявка, като посочите условия, които трябва да са верни за всички съвпадащи записи.

WHERE клаузите работят чрез дефиниране на булеви изрази, които се проверяват спрямо всеки кандидат ред данни. Ако резултатът от израза е false, редът ще бъде премахнат от резултатите и няма да бъде върнат или да продължи към следващия етап на обработка. Ако резултатът от израза е верен, той отговаря на критериите за търсене и ще продължи за всяка по-нататъшна обработка като ред кандидат.

Основният синтаксис на WHERE клаузата изглежда така:

SELECT * FROM my_table WHERE <condition>;

<condition> може да бъде всичко, което води до булева стойност. В PostgreSQL булева стойност е всяка от TRUE , FALSE или NULL .

Условията често се формират с помощта на един или повече от следните оператори:

  • = :равно на
  • > :по-голямо от
  • < :по-малко от
  • >= :по-голямо или равно на
  • <= :по-малко или равно на
  • <> или != :не е равно
  • AND :логическият оператор "и" — свързва две условия и връща TRUE ако и двете условия са TRUE
  • OR :логически оператор "или" — свързва две условия и връща TRUE ако поне едно от условията е TRUE
  • IN :стойността се съдържа в списъка, сериите или диапазона, които следва
  • BETWEEN :стойността се съдържа в диапазона на минималните и максималните стойности, които следват, включително
  • IS NULL :съвпада, ако стойността е NULL
  • NOT :отрича булевата стойност, която следва
  • EXISTS :заявката, която следва, съдържа резултати
  • LIKE :съвпада с шаблон (използвайки заместващите знаци % за да съответства на 0 или повече знака и _ за да съответства на един знак)
  • ILIKE :съвпада с шаблон (използвайки заместващите знаци % за да съответства на 0 или повече знака и _ за да съвпадне с един знак), нечувствителни към главни букви
  • SIMILAR TO :съвпада с шаблон, използващ диалекта на регулярен израз на SQL
  • ~ :съвпада с шаблон, използващ POSIX регулярни изрази, чувствителен към главни букви
  • ~* :съвпада с шаблон, използващ POSIX регулярни изрази, без значение на малки и големи
  • !~ :не съвпада с шаблон, използващ POSIX регулярни изрази, чувствителен към главни букви
  • !~* :не съвпада с шаблон, използващ POSIX регулярни изрази, без значение на малки и големи

Докато горният списък представя някои от най-често срещаните тестови конструкции, има много други оператори, които дават булеви резултати, които могат да се използват във връзка с WHERE клауза.


Примери, използващи WHERE

Една от най-често срещаните и ясни проверки е за равенство, като се използва = оператор. Тук проверяваме дали всеки ред в customer таблицата има last_name стойност, равна на Smith :

SELECT * FROM customer WHERE last_name = 'Smith';

Можем да добавим допълнителни условия към това, за да създадем съставни изрази с помощта на логически оператори. Този пример използва AND клауза за добавяне на допълнителен тест срещу first_name колона. Валидни редове трябва да отговарят и на двете дадени условия:

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

По същия начин можем да проверим дали е изпълнено някое от поредица от условия. Тук проверяваме редове от address таблица, за да видите дали zip_code стойността е равна на 60626 или на neighborhood колона е равна на низа "Roger's Park". Използваме две единични кавички, за да укажем, че трябва да се търси буквален единичен кавички:

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

IN операторът може да работи като сравнение между редица стойности, увити в скоби. Ако има съвпадение с някоя от дадените стойности, изразът е TRUE :

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

Тук проверяваме срещу модел на низ, използвайки LIKE . % работи като заместващ знак, съответстващ на нула или повече знака, така че "Pete", "Peter" и всеки друг низ, който започва с "Pete", ще съвпада:

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

Бихме могли да направим подобно търсене, използвайки ~* оператор за проверка за съвпадения, използвайки POSIX регулярни изрази, без да се съобразява с главния регистър. В този случай проверяваме дали стойността на last_name започва с "d" и съдържа поднизът "on", който би съвпадал с имена като "Диксън", "Доналд" и "Девон":

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

Можем да проверим дали номерът на улицата е в рамките на блока от 4000 адреси с помощта на BETWEEN и AND оператори за дефиниране на включващ диапазон:

SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;

Тук можем да покажем всеки customer записи, които имат социалноосигурителни номера, които не са дълги 9 цифри. Използваме LENGTH() оператор, за да получите броя на цифрите в полето и <> за да проверите за неравенство:

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



Използване на GROUP BY клауза за обобщаване на множество записи

GROUP BY клаузата е друг много често срещан начин за филтриране на резултати чрез представяне на множество резултати с един ред. Основният синтаксис на GROUP BY клаузата изглежда така:

SELECT <columns> FROM some_table GROUP BY <columns_to_group>

Когато GROUP BY клауза се добавя към израз, той казва на PostgreSQL да покаже един ред за всяка уникална стойност за дадена колона или колони. Това има някои важни последици.

Тъй като GROUP BY клаузата е начин за представяне на множество редове като един ред, PostgreSQL може да изпълни заявката само ако може да изчисли стойност за всяка от колоните, които има задача да покаже. Това означава, че всяка колона, идентифицирана с SELECT част от изявлението трябва да бъде или:

  • включен в GROUP BY клауза, за да се гарантира, че всеки ред има уникална стойност
  • Абстрахирано, за да се обобщят всички редове във всяка група

На практика това означава, че всички колони в SELECT списъкът не е включен в GROUP BY клаузата трябва да използва агрегатна функция, за да произведе единичен резултат за колоната за всяка група.


Примери, използващи GROUP BY

За примерите в този раздел да предположим, че имаме таблица, наречена pet които сме дефинирали и попълнили така:

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

Най-простото използване на GROUP BY е да се покаже диапазонът от уникални стойности за една колона. За да направите това, използвайте същата колона в SELECT и GROUP BY . Тук виждаме всички цветове, използвани в таблицата:

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

Докато преминавате отвъд една колона в SELECT списък с колони, трябва или да добавите колоните към GROUP BY клауза или използвайте агрегатна функция, за да произведете единична стойност за групата от представени редове.

Тук добавяме type към GROUP BY клауза, което означава, че всеки ред ще представлява уникална комбинация от type и color стойности. Добавяме и age колона, обобщена от avg() функция за намиране на средната възраст на всяка от групите:

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)

Агрегатните функции работят също толкова добре с една колона в GROUP BY клауза. Тук намираме средната възраст на всеки вид животно:

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)

Ако искаме да покажем най-старото от всеки тип животно, вместо това можем да използваме max() функция на age колона. GROUP BY клаузата свива резултатите в същите редове, както преди, но новата функция променя резултата в другата колона:

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



Използване на HAVING клауза за филтриране на групи от записи

GROUP BY клаузата е начин за обобщаване на данни чрез свиване на множество записи в един представителен ред. Но какво ще стане, ако искате да стесните тези групи въз основа на допълнителни фактори?

HAVING Клаузата е модификатор за GROUP BY клауза, която ви позволява да посочите условия, на които всяка група трябва да отговаря, за да бъде включена в резултатите.

Общият синтаксис изглежда така:

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

Операцията е много подобна на WHERE клауза, с разликата, че WHERE филтрира единични записи и HAVING филтрира групи от записи.


Примери, използващи HAVING

Използвайки същата таблица, която въведохме в последния раздел, можем да демонстрираме как HAVING клаузата работи.

Тук групираме редовете на pet таблица по уникални стойности в type колона, намирайки минималната стойност на age също така. HAVING клаузата след това филтрира резултатите, за да премахне всички групи, при които възрастта не е по-голяма от 1:

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

В този пример групираме редовете в pet по техния цвят. След това филтрираме групите, които представляват само един ред. Резултатът ни показва всеки цвят, който се появява повече от веднъж:

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

Можем да изпълним подобна заявка, за да получим комбинациите от type и color че само едно животно има:

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)



Използване на LIMIT клауза за задаване на максимален брой записи

LIMIT клаузата предлага различен подход за съкращаване на записите, които вашата заявка връща. Вместо да елиминира редове с данни въз основа на критерии в самия ред, LIMIT клаузата задава максималния брой записи, върнати от заявка.

Основният синтаксис на LIMIT изглежда така:

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

Тук <num_rows> показва максималния брой редове за показване от изпълнената заявка. Това често се използва във връзка с ORDER BY клаузи за получаване на редовете с най-екстремни стойности в определена колона. Например, за да получи петте най-добри точки на изпит, потребителят може да ORDER BY score колона и след това LIMIT резултатите до 5.

Докато LIMIT брои от горната част на резултатите по подразбиране, незадължителният OFFSET ключова дума може да се използва за компенсиране на началната позиция, която използва. Всъщност това ви позволява да ранжирате в страници чрез резултати, като показвате броя на резултатите, дефинирани от LIMIT и след това добавяне на LIMIT номер към OFFSET за да извлечете следната страница.


Примери, използващи LIMIT

Ще използваме pet таблица от по-рано за примерите в този раздел.

Както бе споменато по-горе, LIMIT често се комбинира с ORDER BY клауза за изрично дефиниране на подреждането на редовете, преди да изрежете съответното число. Тук сортираме pet записи според тяхната age , от най-възрастния до най-младия. След това използваме LIMIT за показване на първите 5 най-стари животни:

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)

Без ORDER BY клауза, LIMIT ще направи селекции по напълно предвидим начин. Върнатите резултати могат да бъдат осъществени по реда на записите в таблицата или чрез индекси. Това не винаги е лошо.

Ако имаме нужда от запис за някое едно dog в таблицата бихме могли да изградим заявка като тази. Имайте предвид, че макар резултатът да е труден за прогнозиране, това не е случаен избор и не трябва да се използва като такъв:

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

Можем да използваме OFFSET клауза за пагинация на резултатите. Включваме ORDER BY клауза за дефиниране на конкретен ред за резултатите.

За първата заявка ограничаваме резултатите, без да указваме OFFSET за да получите първите 3 най-млади записа:

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)

За да получим следващите 3 най-млади, можем да добавим числото, дефинирано в LIMIT към OFFSET за да пропуснете резултатите, които вече сме изтеглили:

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)

Ако добавим LIMIT към OFFSET отново ще получим следващите 3 резултата:

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)

Това ни позволява да извличаме редове данни от заявка на управляеми парчета.




Заключение

Има много начини за филтриране и по друг начин ограничаване на резултатите, които получавате от заявките. Клаузи като WHERE и HAVING оценете потенциалните редове или групи от редове, за да видите дали отговарят на определени критерии. GROUP BY клаузата ви помага да обобщите данните, като групирате заедно записи, които имат една или повече общи стойности на колони. LIMIT клаузата предлага на потребителите възможността да зададат твърд максимум за броя на записите за извличане.

Научаването как тези клаузи могат да се прилагат, поотделно или в комбинация, ще ви позволи да извлечете конкретни данни от големи набори от данни. Модификаторите и филтрите на заявки са от съществено значение за превръщането на данните, които живеят в PostgreSQL, в полезни отговори.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Индекс с няколко колони на 3 полета с хетерогенни типове данни

  2. Как мога да задам ограничение на размера за тип данни int в PostgreSQL 9.5

  3. Как да регистрирам PostgreSQL заявки?

  4. PSQLException:текущата транзакция е прекратена, командите се игнорират до края на блока на транзакцията

  5. Използване на jsonb_set() за актуализиране на конкретна стойност на jsonb масив