SQL to język baz danych, a PostgreSQL to nasz wybrany. Często przechowywanie danych jest tylko jednym z aspektów tego procesu. Zazwyczaj w każdym przedsięwzięciu skoncentrowanym na danych będziesz:przeglądać i odczytywać dane, podejmować działania lub wprowadzać zmiany na danych, gromadzić informacje dotyczące podejmowania decyzji (analizy) lub manipulować przechowywanymi danymi w jakiejś formie lub w jakiś sposób.
SQL składa się z kombinacji słów kluczowych, poleceń i klauzul. SQL wydaje się prosty. Tylko kilka „łatwych .” komendy tu i tam. Nic wielkiego, prawda?
Ale SQL to coś więcej niż na pierwszy rzut oka. SQL może wpaść na te „łatwe .” ' zapytania.
Jednym z wyzwań (do którego muszę regularnie powracać) jest zrozumienie, że kolejność wykonywania SQL jest zdecydowanie inna niż jego składnia.
W tym wpisie na blogu omówię na wysokim poziomie główne klauzule SQL, które dotyczą PostgreSQL. Istnieje wiele dialektów SQL, ale w centrum uwagi znajduje się interpretacja PostgreSQL. (Niektóre cechy każdej klauzuli bardzo dobrze mogą odnosić się do innych dialektów SQL.)
Klauzule SQL stanowią podstawę podstawowych, często używanych poleceń i zapytań. Mając to na uwadze, zaawansowane zapytania i przykłady wykorzystujące funkcje okna, CTE, tabele pochodne itp. nie zostaną omówione w tym poście.
Jak zobaczymy, nie wszystkie klauzule są sobie równe. Jednak działają one w tandemie, dostarczając wyniki zapytania bezproblemowo (lub nie).
Pozwólcie, że wyjaśnię...
W poście na blogu będę co jakiś czas wspominać o nakazie egzekucji, ponieważ dotyczy to wielu klauzul. Ale jest to uogólnione.
Według mojego zrozumienia, optymalizator najczęściej wybiera i decyduje o najlepszym planie zapytania do wykonania.
SELECT — „Wybredna” klauzula używana do przeszukiwania bazy danych
SELECT to jedna zajęta klauzula. To jest wszędzie. Używany częściej niż wszystkie inne klauzule. Pewne klauzule, których możesz wcale nie potrzebować. Nie tak bardzo w przypadku SELECT, ponieważ jest to obowiązkowa klauzula.
Klauzula SELECT jest zwykle używana do odpytywania bazy danych, zawierającej (na podstawowym poziomie):
- Lista WYBIERZ – Kolumny danych, które chcesz.
- źródłowe zestawy danych — wymienione w klauzuli FROM. Tabele, widoki, CTE itp. Stąd pochodzą dane.
- opcjonalna klauzula WHERE używana do filtrowania wierszy dostarczonych przez klauzulę FROM.
(Klauzule FROM i WHERE zostaną omówione w odpowiednich sekcjach).
Prawdę mówiąc, powiedziałbym, że klauzula SELECT jest wymagana w PostgreSQL, aby cokolwiek pobrać. Ale jest też polecenie TABLE, które zwraca wszystkie wiersze i kolumny z tabeli.
Jednak istnieje między nimi separacja. SELECT może określać poszczególne kolumny, ale w przypadku polecenia TABLE zwracane są wszystkie kolumny.
WYBIERZ najważniejsze informacje:
- SELECT * jest notacją skróconą i zwraca wszystkie kolumny ze źródeł danych.
- Chociaż SELECT jest nazwana pod względem składni jako pierwsza klauzula (z wyjątkiem zapytań używających klauzuli WITH:nie omówiono tutaj), nie jest ona wykonywana jako pierwsza. Warto zauważyć, że SELECT również nie jest ostatnią klauzulą do wykonania.
- Wyrażeniu (lub dowolnej kolumnie) można nadać nazwę referencyjną lub ALIAS w klauzuli SELECT z zastrzeżeniem. Te nazwy mogą być używane w klauzulach ORDER BY i GROUP BY, ale nie w klauzulach WHERE lub HAVING.
- Gdy w zapytaniu występuje klauzula GROUP BY (lub funkcje agregujące), polecenie SELECT nie powinno nazywać żadnych niezgrupowanych kolumn. Tylko te kolumny w dowolnych funkcjach agregujących lub te funkcjonalnie zależne od zgrupowanych kolumn.
- SELECT nie tylko zwraca określone kolumny, ale jego użycie obejmuje również instrukcje INSERT i CREATE TABLE.
- Klauzula SELECT nie jest prosta.
Szczegółowe informacje można znaleźć w oficjalnej sekcji dokumentacji klauzuli PostgreSQL SELECT.
FROM — zapewnia źródła danych dla zapytania
FROM to w większości klauzula obowiązkowa. Nazywam to „luźno ' ze względu na dostępne polecenie TABLE (wspomniane powyżej), które nie wymaga klauzuli FROM.
Z drugiej strony możesz wybrać dowolne wyrażenia bez nazwanej tabeli w zapytaniu SELECT. Jednak w przypadku TABLE nie jest to możliwe.
Oto przykład w psql:
learning=> SELECT 2+2;
?column?
----------
4
(1 row)
Ale z TABELĄ:
learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^
Niektóre dialekty SQL umożliwiają nawet nazywanie nieistniejącej tabeli, aby złagodzić brak rzeczywistej tabeli w klauzuli FROM. Jednak w PostgreSQL, jak widać z powyższego prostego zapytania, nie jest to wymagane.
Ale jeśli potrzebujesz rzeczywistych przechowywanych danych zwróconych poza prostymi wyrażeniami, będziesz potrzebować klauzuli FROM. Bez niego nie ma nawet danych, na których można by operować.
Dlatego FROM jest absolutnie wymagane do odpytywania dowolnych tabel.
W Postgresie wszystkie nazwane tabele w klauzuli FROM są najpierw łączone krzyżowo (jeśli nie występuje klauzula WITH) w kolejności wykonania, która ustanawia produkt kartezjański. Ma to sens, ponieważ potrzebujemy danych do pracy.
Dokumentacja FROM tutaj również zauważa, że zazwyczaj ten zestaw danych jest redukowany do niewielkiej liczby wierszy poprzez obecny warunek klauzuli WHERE.
Klauzula FROM przyjmuje szereg określonych elementów. Oto tylko kilka (pełna lista znajduje się w dokumentacji z linkami poniżej):
- Nazwa tabeli (oczywiście jej potrzebujemy).
- WIDOK.
- Instrukcja SELECT (podzapytanie).
- Nazwa CTE (klauzula Z).
- Rodzaj DOŁĄCZENIA – jeśli istnieje.
- Funkcja (nie byłem tego świadomy. Jak fajnie!!!)
OD najciekawszych miejsc:
- Chociaż FROM jest syntaktycznie wymieniona jako druga klauzula w zapytaniu SELECT, jest wykonywana jako pierwsza.
- FROM zapewnia (poprzez ładowanie) wszystkich wierszy z dowolnych tabel (rzeczywistych lub wirtualnych) wymienionych w klauzuli.
- Nazwy tabel mogą mieć aliasy w klauzuli FROM (np. FROM butów AS), ale muszą być przywoływane przez ten ALIAS w trakcie całego zapytania.
- FROM jest obowiązkową klauzulą podczas odpytywania tabel.
Zapoznaj się z sekcją Oficjalnej klauzuli PostgreSQL FROM, aby uzyskać szczegółowe informacje.
GDZIE — odfiltrowuje wiersze ze źródeł danych na podstawie wyrażeń warunkowych walidacji logicznych
WHERE jest klauzulą opcjonalną. Jednak, gdy jest obecny w zapytaniu, jego obowiązkiem jest usunięcie tych rekordów dostarczonych przez klauzulę FROM, które nie przejdą jej warunkowej kontroli logicznej.
Klauzula WHERE ma również głębokie zastosowanie z innymi poleceniami SQL oprócz SELECT. Mianowicie polecenia DML, takie jak INSERT (nie bezpośrednio, ale przez SELECT), UPDATE i DELETE.
W rzeczywistości bez klauzuli WHERE instrukcje UPDATE i DELETE prawdopodobnie wpłyną na wszystkie wiersze docelowe. Być może nie to, co zamierzałeś (Hej!).
Funkcji agregujących nie można używać w logicznym wyrażeniu warunkowym klauzuli WHERE. Żadne grupowanie nie miało jeszcze miejsca w kolejności wykonania. Dlatego agregaty nie są (jeszcze) dostępne dla klauzuli WHERE.
Ocena WHERE opiera się na sprawdzeniu logicznym przy użyciu dowolnego z operatorów porównania. (np.>, <, =, <> itd…)
Klauzula WHERE nie może uzyskać dostępu do nazw kolumn z aliasami wymienionych w klauzuli SELECT. Ponieważ klauzula SELECT jest właściwie (nie pod względem składni) wykonywane po klauzuli WHERE, te kolumny z aliasami nie są jeszcze dostępne.
GDZIE podkreśla:
- Funkcje agregujące nie są dostępne i nie mogą być używane w warunkowym sprawdzaniu logicznym klauzuli WHERE. (Klauzula WHERE jest prawdopodobnie odpowiedzialna za wszelkie wiersze dostarczane do funkcji agregujących i grupujących do obliczeń.)
- Kolumny z aliasami w klauzuli SELECT nie mogą być przywoływane w klauzuli WHERE.
- Warunkowe sprawdzenie wyrażenia logicznego WHERE może spowodować:prawda, fałsz lub NULL.
- Wszystkie wiersze, w których wyrażenie logiczne WHERE ma wartość false lub NULL, są usuwane.
- Wiele warunków logicznych można sprawdzić w klauzuli WHERE, wykorzystując słowa kluczowe AND lub OR.
Zapoznaj się z oficjalną sekcją klauzuli WHERE PostgreSQL, aby uzyskać szczegółowe informacje.
GRUPA WEDŁUG — Grupy formularzy
Jest klauzulą opcjonalną.
Ta klauzula tworzy pojedynczy wiersz dla wybranych, który zawiera dopasowanie określonej wartości zgrupowanej kolumny.
GROUP BY może być trudne, dlatego uważam za stosowne zamieścić ten fragment z dokumentacji:
„Gdy występuje funkcja GROUP BY lub jakiekolwiek funkcje agregujące, wyrażenia listy SELECT nie mogą odwoływać się do niezgrupowanych kolumn, z wyjątkiem funkcji agregujących lub gdy niezgrupowana kolumna jest funkcjonalnie zależna od zgrupowanych kolumn, ponieważ w przeciwnym razie nie byłoby więcej niż jedna możliwa wartość do zwrócenia dla niezgrupowanej kolumny. Zależność funkcjonalna istnieje, jeśli zgrupowane kolumny (lub ich podzbiór) są kluczem podstawowym tabeli zawierającej niezgrupowaną kolumnę."
GRUPA WEDŁUG wyróżnienia:
- Postgres umożliwia grupowanie nie tylko kolumn z tabeli źródłowej, ale także tych wymienionych na liście kolumn SELECT. Różni się to nieco od ścisłego SQL.
- W niektórych zapytaniach GROUP BY może naśladować klauzulę DISTINCT, usuwając zduplikowane wartości dla kolumny klauzuli SELECT.
- Kolejność kolumn nie ma znaczenia dla GROUP BY.
- Do kolumn, które nie są objęte klauzulą GROUP BY, nie można się odwoływać, z wyjątkiem agregatów.
- W wielu przypadkach możesz pogrupować na KLUCZ PODSTAWOWY dla tych funkcjonalnie zależnych kolumn tego klucza.
- Grupowanie jest nadal przeprowadzane dla zapytań wykorzystujących funkcje agregujące w przypadku braku klauzuli GROUP BY.
Zobacz oficjalną sekcję klauzuli PostgreSQL GROUP BY, aby uzyskać szczegółowe informacje.
HAVING - Filtry GROUP BY Kolumny i funkcje agregujące
Jest klauzulą opcjonalną.
HAVING filtruje wiersze z zestawu wyników za pomocą logicznej kontroli warunkowej, podobnie jak klauzula WHERE, z wyjątkiem tego, że filtruje wiersze utworzone przez klauzulę GROUP BY i/lub funkcje agregujące.
POSIADAJĄC najważniejsze informacje:
- Klauzula HAVING może odwoływać się do tych kolumn nazwanych w funkcjach agregujących (nawet tych, które nie są pogrupowane) oprócz dowolnych kolumn GROUP BY.
- HAVING jest odpowiedzialny za eliminowanie wierszy po zastosowaniu funkcji agregujących lub grupowania.
- Możesz odwoływać się do kolumn niezagregowanych w klauzuli HAVING, chociaż nie ma to większego sensu.
- Chociaż klauzula HAVING jest wielokrotnie używana w połączeniu z klauzulą GROUP BY, można jej używać samodzielnie. Wyniki zapytania są formowane w pojedynczą grupę tych kolumn tylko w funkcjach agregujących.
Zapoznaj się z oficjalną sekcją klauzuli PostgreSQL HAVING, aby uzyskać szczegółowe informacje.
ORDER BY — miara kolejności nielosowa
Jest klauzulą opcjonalną.
Użyj ORDER BY, gdy potrzebujesz konkretnego zamówienia. W przeciwnym razie baza danych może (i będzie) zwracać wyniki w dowolnej kolejności.
Nawet jeśli wyniki wydają się być pozornie uporządkowane, nie jest to gwarantowane.
Nie daj się zwieść. Użyj ORDER BY.
Dostępne są dwa wzorce zamawiania. Albo kolejność ASC (rosnąca) albo DESC (malejąca), przy czym ASC jest domyślnym.
Jeśli zestaw wyników ma zawierać wartości NULL, mogą one być również użyte w kolejności w następujący sposób:określenie NULLS LAST powoduje ich (NULL) sortowanie po wartościach innych niż NULL, podczas gdy żądanie NULLS FIRST jest odwrotne.
Najważniejsze cechy ORDER BY:
- Wyrażenia sortujące to dowolne z tych, które byłyby dozwolone na liście SELECT zapytania.
- PostgreSQL pozwala na tworzenie kolumn ORDER BY nieobecnych w klauzuli SELECT, podczas gdy niektóre dialekty SQL tego nie robią.
- Wyniki zapytania są kapryśne i nie gwarantują, że będą przypominać jakikolwiek wzorzec lub kolejność, chyba że zostanie użyta klauzula ORDER BY.
- ORDER BY i klauzula LIMIT (patrz następna sekcja) świetnie łączą się w celu określenia „Top ' zestaw wyników wierszy. (np. 5 dni o najwyższej sprzedaży, 5 par butów o najniższej sprzedaży, najlepszy sprzedawca w tym kwartale)
- Wyniki można uporządkować według numeru pozycji kolumny na liście SELECT, ale określona liczba nie może być większa niż liczba pozycji na liście z klauzulą SELECT. Innymi słowy, jeśli klauzula SELECT zawiera tylko 2 pozycje, ORDER BY 3 spowoduje błąd.
- Każde pojedyncze wyrażenie jest uporządkowane tylko według swojej wymienionej opcji. (np. ORDER BY col_1 DESC, col_2 DESC to nie to samo co ORDER BY col_1, col_2 DESC)
Zobacz oficjalną sekcję klauzuli PostgreSQL ORDER BY, aby uzyskać szczegółowe informacje.
Pobierz oficjalny dokument już dziś Zarządzanie i automatyzacja PostgreSQL za pomocą ClusterControlDowiedz się, co musisz wiedzieć, aby wdrażać, monitorować, zarządzać i skalować PostgreSQLPobierz oficjalny dokumentLIMIT — pobierz określoną liczbę wierszy z wyników zapytania
LIMIT jest klauzulą opcjonalną.
LIMIT faktycznie składa się z 2 podrozdziałów, przy czym OFFSET jest drugim z nich.
Jeśli podano wartość dla części PRZESUNIĘCIE klauzuli, wiersze zestawu wyników są zwracane po pomijam tę liczbę wierszy.
Ważna sekcja w dokumentacji do odnotowania:
„Planer zapytań bierze pod uwagę LIMIT podczas generowania planu zapytań, więc jest bardzo prawdopodobne, że otrzymasz różne plany (przynoszące różne kolejność wierszy) w zależności od tego, czego używasz dla LIMIT i PRZESUNIĘCIA. Dlatego używając różnych wartości LIMIT/OFFSET, aby wybrać różne podzbiory wyników zapytania dadzą niespójne wyniki, chyba że wymusisz przewidywalną kolejność wyników za pomocą ORDER BY. To nie jest błąd; jest to nieodłączna konsekwencja faktu, że SQL nie obiecuje dostarczyć wyników zapytania w określonej kolejności chyba że ORDER BY jest używane do ograniczenia zamówienia."
LIMIT podkreśla:
- LIMIT może prawdopodobnie zwrócić mniej wierszy niż zdefiniowana liczba, jeśli samo zapytanie generuje mniej wierszy w zestawie wyników. Innymi słowy, nie miałoby to wpływu na liczbę zwracanych wierszy.
- Składnia LIMIT ALL jest akceptowalna i ma taki sam efekt, jak nieuwzględnianie w ogóle klauzuli LIMIT.
- Chociaż liczba wierszy „x” jest pomijana z powodu klauzuli OFFSET, nie jest to „obejście ' dla jakiegokolwiek wzrostu wydajności, ponieważ są one nadal obliczane dla planu zapytań na serwerze.
- OFFSET 0 jest równoznaczne z całkowitym wyłączeniem klauzuli OFFSET.
Zapoznaj się z sekcją Oficjalna Klauzula LIMIT PostgreSQL, aby uzyskać szczegółowe informacje.
Interpretacja głównych klauzul SQL w PostgreSQL jest sama w sobie. Niezależnie od tego, w jaki sposób PostgreSQL zdecyduje się je zaimplementować, czy nie, są one podstawą zapytań SQL, a znajomość ich indywidualnych cech (i niuansów) może przynieść korzyści tylko użytkownikom idącym naprzód.
Chociaż na temat każdej z tych klauzul napisano tomy artykułów, książek, dokumentacji i postów na blogach, mam nadzieję, że ten ogólny przegląd będzie dla Ciebie zrozumiały i pouczający.
Dziękuję za przeczytanie.