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

Клаузи за грижа:Всичко за SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY и LIMIT

SQL е език на базите данни и PostgreSQL е нашият избран. Често съхраняването на данни е само един от аспектите на процеса. Обикновено във всяко ориентирано към данни начинание вие ​​ще:преглеждате и четете данни, ще предприемате действия или внедрявате промени в данните, ще събирате информация за вземане на решения (аналитика) или ще манипулирате съхранените данни под някаква форма или начин.

SQL се състои от комбинация от ключови думи, команди и клаузи. SQL изглежда прост. Само няколко „лесни ' командва тук-там. Нищо страшно, нали?

Но SQL има повече, отколкото изглежда. SQL може да ви препъне в тези „лесни ' запитвания.

Едно предизвикателство (което трябва редовно да преразглеждам) е разбирането, че реда за изпълнение на SQL определено е различен от този на неговия синтаксис.

В тази публикация в блога посещавам на високо ниво основните SQL клаузи, които се прилагат към PostgreSQL. Има много диалекти на SQL, но интерпретацията на PostgreSQL е фокусът тук. (Някои характеристики на всяка клауза може много добре да се отнасят за други SQL диалекти.)

SQL клаузите формират основата за основни, често използвани команди и заявки. Като се има предвид това, разширени заявки и примери, използващи функции на прозореца, CTE, извлечени таблици и т.н., няма да бъдат обхванати в тази публикация.

Както ще видим, не всички клаузи са създадени равни. И все пак те работят в тандем, осигурявайки резултати от заявките безпроблемно (или не).

Позволете ми да поясня...

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

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

SELECT – Клаузата „избирателна“, използвана за запитване на базата данни

SELECT е една заета клауза. Има го навсякъде. Използва се повече от всички останали клаузи. Някои клаузи може да не са ви необходими изобщо. Не е толкова случаят с SELECT, тъй като това е задължителна клауза.

Клаузата SELECT обикновено се използва за запитване към базата данни, съдържаща (на основно ниво):

  1. Списък SELECT – колоните с данни, които искате.
  2. изходният(ите) набор(и) от данни – именуван в клаузата FROM. Таблици, изгледи, CTE и т.н. От тук идват данните.
  3. незадължителна клауза WHERE, използвана за филтриране на редове, предоставени от клаузата FROM.

(Клаузите FROM и WHERE ще бъдат обсъдени в съответните им раздели.)

В интерес на истината, бих казал, че клаузата SELECT е необходима в PostgreSQL за извличане на нещо. Но има командата TABLE, която връща всички редове и колони от таблица.

И все пак има разделение между двете. SELECT може да посочи отделни колони, но с командата TABLE всички колони се връщат.

ИЗБЕРЕТЕ акценти:

  • SELECT * е съкратена нотация и връща всички колони от източника на данни.
  • Въпреки че SELECT е синтактично наименуван като първа клауза (с изключение на тези заявки, използващи клауза WITH:не се обсъжда тук), тя не се изпълнява първа. По-специално, SELECT също не е последната клауза за изпълнение.
  • На израз (или която и да е колона) може да се даде референтно име или ALIAS в клаузата SELECT, с предупреждение. Тези имена могат да се използват в клаузите ORDER BY и GROUP BY, но не и в клаузите WHERE или HAVING.
  • Когато в заявката присъства клауза GROUP BY (или агрегатни функции), SELECT не трябва да назовава нито една негрупирана колона(и). Само тези колони в която и да е агрегатна функция(и) или тези, които са функционално зависими от групираната(и) колона(и).
  • Не само SELECT връща конкретни колони, но използването му се простира и до изрази INSERT и CREATE TABLE.
  • Клаузата SELECT далеч не е проста.

Вижте секцията за официална документация на PostgreSQL SELECT за задълбочено покритие.

ОТ – Предоставя източника на данни за заявката

FROM е предимно задължителна клауза. Наричам това „свободно ' поради наличната команда TABLE (спомената по-горе), която не изисква клаузата FROM.

След това отново можете да изберете произволни изрази, без именувана таблица в заявка SELECT. Но с TABLE това не е възможно.

Ето един пример в psql:

learning=> SELECT 2+2;
?column? 
----------
4
(1 row)

Но с ТАБЛИЦА:

learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^

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

Но ако имате нужда от действително съхранени данни, върнати освен прости изрази, ще ви трябва клаузата FROM. Без него няма данни, с които дори да се работи.

Следователно FROM е абсолютно задължителен за заявка за всякакви таблици.

В Postgres всички именувани таблици в клаузата FROM първо се свързват кръстосано (ако клауза WITH не присъства) в реда за изпълнение, който установява декартов продукт. Това има смисъл, тъй като имаме нужда от данни, с които да работим.

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

Клаузата FROM приема редица специфични елементи. Ето само няколко (вижте документацията за връзки по-долу за пълния списък):

  • Име на таблица (очевидно имаме нужда от това).
  • ИЗГЛЕД.
  • Изявление SELECT (подзаявка).
  • Име на CTE (клауза WITH).
  • Тип JOIN – ако има такъв.
  • Функция (не знаех за това. Колко готино!!!)

ОТ акценти:

  • Въпреки че FROM е синтактично посочен като втора клауза в заявка SELECT, тя се изпълнява първа.
  • FROM предоставя (чрез зареждане) всички редове от всякакви таблици (реални или виртуални), посочени в нейната клауза.
  • Имената на таблици могат да бъдат с псевдоним в клаузата FROM (напр. FROM shoe AS s), но трябва да бъдат посочени от този ALIAS в хода на заявката напред.
  • FROM е задължителна клауза при запитване на таблици.

Вижте официалния раздел клауза на PostgreSQL FROM за задълбочено покритие.

WHERE – филтрира редове от източника(ите) на данни въз основа на условния израз(и) за булева валидация

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

Клаузата WHERE също има дълбока употреба с други SQL команди в допълнение към SELECT. А именно DML команди като INSERT (не директно, а чрез SELECT), UPDATE и DELETE.

Всъщност, без клауза WHERE, операторите UPDATE и DELETE вероятно ще засегнат всички целеви редове. Може би не е това, което сте възнамерявали (а!).

Агрегатните функции не могат да се използват в булевия условен израз на клаузата WHERE. Все още не е извършено групиране в реда за изпълнение. Следователно агрегатите не са налични (все още) за клаузата WHERE.

Оценката WHERE се основава на булева проверка с помощта на някой от операторите за сравнение. (Напр.>, <, =, <> и т.н....)

Клаузата WHERE няма достъп до имена на колони с псевдоним, изброени в клаузата SELECT. Тъй като клаузата SELECT е всъщност (не по синтаксис) изпълнени след клаузата WHERE, тези колони с псевдоним все още не са налични.

КЪДЕ акценти:

  • Агрегатните функции не са достъпни и не могат да се използват в булевата условна проверка на клауза WHERE. (Клаузата WHERE е вероятно отговорна за всички редове, предоставени за агрегиране на функции и групиране за изчисление.)
  • Колоните с псевдоним в клаузата SELECT не могат да бъдат посочени в клаузата WHERE.
  • Условната проверка на булев израз на клауза WHERE може да доведе до:true, false или NULL.
  • Всички редове, в които булевият израз на клауза WHERE се оценява на false или NULL, се премахват.
  • В клаузата WHERE могат да бъдат проверени множество булеви условия, като се използват ключовите думи И или ИЛИ.

Вижте официалната клауза WHERE на PostgreSQL за задълбочено покритие.

GROUP BY - Формуляри на групи

Това е незадължителна клауза.

Тази клауза създава един ред за избраните, който съдържа съвпадение на посочената групирана стойност на колоната.

GROUP BY може да бъде сложно, следователно смятам, че е уместно да включите този пасаж от документацията:

„Когато присъства GROUP BY или присъстват агрегатни функции, не е валидно списъчните изрази SELECT да се отнасят до негрупирани колони, освен в рамките на агрегатните функции или когато негрупираната колона е функционално зависима от групираните колони, тъй като иначе би имало повече от една възможна стойност за връщане за негрупирана колона. Съществува функционална зависимост, ако групираните колони (или тяхно подмножество) са първичният ключ на таблицата, съдържаща негрупираната колона."

GROUP BY акценти:

  • Postgres позволява групиране не само на колони от изходната таблица, но и на тези, изброени в списъка с колони SELECT. Това е малко по-различно от стриктния SQL.
  • При определени заявки GROUP BY може да имитира клаузата DISTINCT, като премахва дублиращи се стойности за колоната SELECT клауза.
  • Редът на колоните не е от значение за GROUP BY.
  • Тези колони, които не са насочени от клаузата GROUP BY, не могат да бъдат препращани освен в агрегати.
  • В много случаи можете да групирате върху ОСНОВЕН КЛЮЧ за тези функционално зависими колони на този ключ.
  • Групирането все още се извършва за заявки, използващи агрегатни функции при липса на клауза GROUP BY.

Вижте официалния раздел на PostgreSQL GROUP BY за задълбочено покритие.

HAVING - Филтри ГРУПИРА ПО колона(и) и агрегатни функции

Това е незадължителна клауза.

HAVING филтрира редове от набора от резултати с булева условна проверка точно като клаузата WHERE, с изключение на това, че филтрира тези редове, образувани от клаузата GROUP BY и/или агрегатните функции.

ИМАТЕ акценти:

  • Клаузата HAVING може да препраща към тези колони, наречени в агрегатни функции (дори тези, които не са групирани) в допълнение към колоните GROUP BY.
  • HAVING отговаря за елиминирането на редове след прилагане на обобщени функции или групиране.
  • Можете да препращате към неагрегирани колони в клаузата HAVING, въпреки че това няма много голяма полза.
  • Въпреки че клаузата HAVING се използва много пъти във връзка с клаузата GROUP BY, можете да я използвате самостоятелно. Резултатите от заявката се формират в една група от тези колони само в агрегатни функции.

Вижте официалния раздел на PostgreSQL HAVING за задълбочено покритие.

ПОРЪЧКА ПО – Мярка за ред извън произволност

Това е незадължителна клауза.

Използвайте ORDER BY, когато имате нужда от конкретна поръчка. В противен случай базата данни може (и ще) връща резултати в произволен ред.

Дори ако резултатите изглеждат в някакъв ред, това не е гарантирано.

Не се заблуждавайте. Използвайте ORDER BY.

Има два налични модела за поръчка. Или ASC (възходящ), или DESC (низходящ) ред, като ASC е по подразбиране.

Ако вашият набор от резултати трябва да включва NULL стойности, те също могат да се използват в подреждането, както следва:указването на NULLS LAST ги кара (NULL) да се сортират след не-NULL, докато изискването на NULLS FIRST е обратното.

ПОРЪЧАЙТЕ ПО акценти:

  • Изразите за сортиране са всеки от тези, които биха били разрешени в списъка SELECT на заявката.
  • PostgreSQL ви позволява да ORDER BY колони, които не присъстват в клаузата SELECT, където някои SQL диалекти не го правят.
  • Резултатите от заявките са капризни и не е гарантирано, че приличат на шаблон или поръчка, освен ако не се използва клауза ORDER BY.
  • ORDER BY и клаузата LIMIT (вижте следващия раздел) са чудесно комбинирани за определяне на „Най-горе ' набор от резултати от редове. (напр. 5 дни с най-висока разпродажба, 5 най-ниско продавани чифта обувки, топ продавач през това тримесечие)
  • Можете да подредите резултатите по позиционен номер на колона в списъка SELECT, но посоченият номер не трябва да бъде по-голям от броя на елементите в посочения списък с клаузи SELECT. С други думи, ако клаузата SELECT има само 2 елемента, тогава ORDER BY 3 ще доведе до грешка.
  • Всеки отделен израз се подрежда само според изброената опция. (напр. ORDER BY col_1 DESC, col_2 DESC не е същото като ORDER BY col_1, col_2 DESC)

Вижте официалния раздел ORDER BY на PostgreSQL за задълбочено покритие.

Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книга

LIMIT – Извличане на конкретен брой редове от резултатите от заявката

LIMIT е незадължителна клауза.

LIMIT всъщност се състои от 2 подклаузи, като OFFSET е втората от тях.

Ако е предоставена стойност за частта OFFSET на клаузата, редовете за набор от резултати се връщат след пропускане на този брой редове.

Важен раздел в документацията, който трябва да се отбележи:

„Инструментът за планиране на заявки взема предвид LIMIT при генериране на план за заявка, така че е много вероятно да получите различни планове (да дадете различни редове на редове) в зависимост от това какво използвате за LIMIT и OFFSET. По този начин, като използвате различни стойности LIMIT/OFFSET, за да изберете различни подмножества на резултат от заявка ще дадат непоследователни резултати, освен ако не наложите предсказуемо подреждане на резултатите с ORDER BY. Това не е грешка; това е присъща последица от факта, че SQL не обещава да достави резултатите от заявка в конкретен ред освен ако ORDER BY не се използва за ограничаване на поръчката."

LIMIT акценти:

  • LIMIT може да върне по-малко редове от дефинираното число, ако самата заявка генерира по-малко редове в набора от резултати. С други думи, това няма да окаже влияние върху броя на върнатите редове.
  • Синтаксисът LIMIT ALL е приемлив и има същия ефект като липсата на клауза LIMIT изобщо.
  • Въпреки че броят на редовете „x“ е пропуснат поради клауза OFFSET, това не е „заобиколно решение ' за всякакво увеличение на производителността, тъй като те все още се изчисляват за плана на заявката в сървъра.
  • OFFSET 0 е еквивалентно на това, че изобщо не се включва клауза OFFSET.

Вижте официалната клауза LIMIT на PostgreSQL за задълбочено покритие.

Интерпретацията на PostgreSQL на основните SQL клаузи е собствена. Независимо от това как PostgreSQL избере да ги приложи или не, те са основополагащи за SQL заявките и запознаването с техните индивидуални характеристики (и нюанси) може само да е от полза за потребителите, които продължават напред.

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

Благодаря ви, че прочетохте.


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

  2. Ограничение на размера на типа данни JSON в PostgreSQL

  3. PostgreSQL Създаване на схема

  4. Грешки в еволюцията на Heroku

  5. Как да използвате Joda-Time с java.sql.Timestamp