Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
2
20230403
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Patryk Czarnik
20230403
Commits
c05bc5d8
Commit
c05bc5d8
authored
Apr 04, 2023
by
Patryk Czarnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Wykład z SQL - SELECT, WHERE, ORDER BY
parent
7ceaa977
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
523 additions
and
0 deletions
+523
-0
wyklad.sql
PC22-BazyDanych_Wstep/sql/zajecia/wyklad.sql
+523
-0
No files found.
PC22-BazyDanych_Wstep/sql/zajecia/wyklad.sql
0 → 100644
View file @
c05bc5d8
SELECT
*
FROM
employees
;
SELECT
*
FROM
countries
;
/* To jest komentarz blokowy
czyli taki, który może rozciągać się na wiele linii. */
-- To jest komentarz jednolinijkowy.
-- Zazwyczaj będziemy pisać komentarze przed instrukcją, którą opisujemy, np. tak:
-- To jest najprostsze zapytanie: odczytaj wszystko z tabeli countries:
SELECT
*
FROM
countries
;
--* Polecenia modyfikacji danych (DML) - podstawy *--
-- INSERT - wstawia zupełnie nowy rekord do tabeli (takie id nie może wcześniej występować)
INSERT
INTO
countries
(
country_id
,
country_name
,
region_id
)
VALUES
(
'PL'
,
'Poland'
,
1
);
-- Gdy podajemy nazwy kolumn do wstawienia, mamy prawo podać je w zmienionej kolejności lub niektóre pominąć.
-- Dla pominiętych przyjmowana jest wartość domyślna z definicji tabeli lub NULL.
-- (Można też jawnie wpisać DEFAULT lub NULL w miejsce wartości.)
INSERT
INTO
countries
(
country_name
,
country_id
)
VALUES
(
'San Escobar'
,
'Se'
);
-- Jeśli za tabelą nie podamy nazw kolumn, musimy wstawić wszystkie w tej samej kolejności jak w definicji tabeli.
INSERT
INTO
countries
VALUES
(
'CZ'
,
'Czech Republic'
,
1
);
SELECT
*
FROM
countries
ORDER
BY
country_id
;
-- UPDATE - modyfikacja istniejących danych
UPDATE
countries
SET
country_name
=
'Czechia'
WHERE
country_id
=
'CZ'
;
-- Przykład zmiany w wielu rekordach: programistom dajemy podwyżkę 10 tys. i ustawiamy prowizję na 10%
-- Nowa wartość może zależeć od dotychczasowej.
UPDATE
employees
SET
salary
=
salary
+
10000
,
commission_pct
=
0
.
1
WHERE
job_id
=
'IT_PROG'
;
SELECT
*
FROM
employees
ORDER
BY
employee_id
;
-- Cofnięcie tych zmian.
-- UPDATE employees SET salary = salary - 10000, comission_pct = NULL WHERE job_id = 'IT_PROG';
-- DELETE - usunięcie rekordów wskazanych za pomocą warunku WHERE
DELETE
FROM
countries
WHERE
country_id
IN
(
'PL'
,
'CZ'
,
'Se'
);
-- Uwaga: Brak WHERE spowoduje usunięcie wszystkich rekordów. Uwaga na zaznaczanie.
--* SELECT *--
/* Ogólna składnia polecenia SELECT:
SELECT kolumny
FROM tabele
WHERE warunek rekordów
GROUP BY kryteria grupowania
HAVING warunek grup
ORDER BY kryteria sortowania
...
Poszczególne części nazywa się "kaluzulami" (clause).
Na końcu można dopisywać różne niestandardowe rozszerzenia poszczególnych baz danych,
np. LIMIT / OFFSET w PostgreSQL.
*/
-- Sama klauzula SELECT określa kolumny, które mają znaleźć się w wyniku.
SELECT
first_name
,
last_name
,
salary
FROM
employees
;
-- Gdy wpiszemy *, to odczytamy wszystkie dostępne kolumny.
SELECT
*
FROM
employees
;
-- Teraz odczytamy wszystkie kolumny z obu tabel.
SELECT
*
FROM
employees
,
departments
;
-- A to odczyta trzy kolumny z employees, oraz wszystkie kolumny z departments.
SELECT
employees
.
first_name
,
employees
.
last_name
,
employees
.
salary
,
departments
.
*
FROM
employees
,
departments
;
-- Jeśli nazwy kolumn są jednoznaczne (tzn. znajdują się tylko w jednej z podanych tabel),
-- można nie pisać prefiksu z nazwą tabeli.
SELECT
first_name
,
last_name
,
salary
,
departments
.
*
FROM
employees
,
departments
;
SELECT
first_name
,
last_name
,
salary
,
department_name
FROM
employees
,
departments
;
-- Kolumna manager_id występuje w obu tabelach i teraz nie mogę jej odczytać bez podawania nazwy tabeli
-- BŁĄD
SELECT
manager_id
FROM
employees
,
departments
;
-- OK
SELECT
employees
.
manager_id
,
departments
.
manager_id
FROM
employees
,
departments
;
-- Jeśli chcę odczytać wszystkie kolumny z tabeli, a oprócz nich dodać jeszcze jakieś (np. wyliczane wyrażeniem),
-- to w Postgresie MOŻNA użyć symbolu * , a nie zadziałałoby to w Oracle
SELECT
*
,
lower
(
email
)
||
'@alx.pl'
as
prawdziwy_email
FROM
employees
;
-- W Oracle trzeba poprzedzić * nazwą tabeli.
SELECT
employees
.
*
,
lower
(
email
)
||
'@alx.pl'
as
prawdziwy_email
FROM
employees
;
-- W klauzuli SELECT można nie tylko wskazywać istniejące kolumny,
-- ale można też wpisywać wyrażenia, które coś obliczają.
SELECT
first_name
,
last_name
,
salary
,
12
*
salary
,
length
(
last_name
),
upper
(
first_name
||
' '
||
last_name
),
current_timestamp
,
2
+
2
FROM
employees
;
-- Wynikowym kolumnom można nadawać własne nazwy. To są tzw. aliasy kolumn.
-- Przy okazji: ciekawy, bardzo praktyczny, sposób formatowania kodu
SELECT
first_name
AS
imie
,
last_name
AS
nazwisko
,
salary
,
12
*
salary
AS
roczne_zarobki
,
length
(
last_name
)
AS
dlugosc_nazwiska
,
upper
(
first_name
||
' '
||
last_name
)
AS
kto_tam
,
current_timestamp
AS
czas
,
2
+
2
AS
wynik
FROM
employees
;
-- W praktyce najczęściej alias definiuje się za pomocą "Nazwy cytowanej",
-- aby zachować wielkoćć liter i aby można było użyć spacji i innych znaków:
SELECT
first_name
as
"Imię"
,
last_name
as
"Nazwisko"
,
salary
as
"Miesięczne zarobki"
,
12
*
salary
as
"Roczne zarobki"
FROM
employees
;
-- W Oracle obowiązkowe jest pisanie FROM.
-- To jest poprawne w PostgreSQL, SQLite, MySQL, ale nie w Oracle:
SELECT
2
+
2
;
SELECT
current_date
,
current_timestamp
,
random
();
-- W Oracle w sytuacjach, gdy chcemy coś wykonać bez odczytywania danych z tabel,
-- korzysta się z wirtualnej tabeli DUAL:
-- To nie działa w PostgreSQL
SELECT
2
+
3
,
current_date
,
current_timestamp
FROM
dual
;
-- Zobaczmy co ta tabela zawiera... :-)
-- SELECT * FROM dual;
-- DISTINCT powoduje pobranie danych bez powtórzeń:
SELECT
first_name
FROM
employees
;
SELECT
DISTINCT
first_name
FROM
employees
;
-- Jeśli zapytanie zwraca kilka kolumn, to unikalne mają być "krotki", czyli kombinacje wartości.
-- Np. teraz niektóre imiona się powtarzają, niektóre nazwiska się powtarzają,
-- ale nie ma osoby o identycznej kombinacji imienia i nazwiska.
SELECT
DISTINCT
first_name
,
last_name
FROM
employees
;
--* Klauzula WHERE *--
/* W WHERE podaje się warunek logiczny,
który dla każdego wiersza decyduje czy ten wiersz ma znaleźć się wśród wyników.
W warunku można odwoływać się do pól rekordu na podobnych zasadach jak w SELECT
(to się zmieni, gdy dojdziemy do grupowania).
Rozumując programistycznie, można sobie wyobrazić, że serwer bazodanowy czyta wszystkie rekordy z tabeli
i w pętli dla każdego rekordu sprawdza warunek.
Jednak zwn wydajność bazy danych dokonują różnych optymalizacji,
dzięki którym mogą szybciej znajdować rekordy spełniające warunek.
Zasadniczą rolę w przyspieszaniu wyszukiwania pełnią indeksy,
dzięki którym (w wielkim uproszczeniu) dla podanego kryterium baza od razu ma wskazane,
które rekordy należy odczytać - nie przegląda już pozostałych.
Indeksy spełnią swoją rolę, jeśli w warunku odwołujemy się do zindeksowanych kolumn lub wyrażeń.
*/
SELECT
*
FROM
employees
WHERE
salary
>=
10000
;
-- Uwaga dla programistów: sprawdzenie równości to po prostu pojedyncze =
SELECT
*
FROM
employees
WHERE
salary
=
10000
;
-- Uwaga dla programistów Javy: także dla napisów :-)
SELECT
*
FROM
employees
WHERE
last_name
=
'King'
;
-- Co więcej, nie tylko liczby, ale także napisy, daty itp. można porównywać na zasadzie mniejsze/większe i sortować.
SELECT
*
FROM
employees
WHERE
last_name
<=
'King'
;
-- Można używać porównań: < <= > >= =
-- Nierówne na dwa sposoby: != <>
SELECT
*
FROM
employees
WHERE
last_name
!=
'King'
;
SELECT
*
FROM
employees
WHERE
last_name
<>
'King'
;
-- Spójniki logiczne: AND, OR, NOT
-- Odczytaj te osoby, które zarabiają > 10 tys i jednocześnie mają na nazwisko King
-- AND - logiczne "i", koniunkcja, działa jak część wspólna zbiorów
SELECT
*
FROM
employees
WHERE
salary
>
10000
AND
last_name
=
'King'
;
-- OR - logiczne "lub", alternatywa, działa jak suma zbiorów
SELECT
*
FROM
employees
WHERE
salary
>
10000
OR
last_name
=
'King'
;
-- NOT - negacja, odwrócenie znaczenia warunku
SELECT
*
FROM
employees
WHERE
NOT
last_name
=
'King'
;
-- Wypiszmy osoby, które zarabiają od 5 do 10 tys.
SELECT
*
FROM
employees
WHERE
salary
>=
5000
AND
salary
<=
10000
;
-- Akurat jeśli chodzi o sprawdzanie przedziałów, można użyć operatora BETWEEN:
-- Zauważmy, ze BETWEEN opisuje przedziały obustronnie domknięte.
SELECT
*
FROM
employees
WHERE
salary
BETWEEN
5000
AND
10000
;
-- Wypisz pracowników o nazwiskach na litery od C do K
SELECT
*
FROM
employees
WHERE
last_name
BETWEEN
'C'
AND
'L'
;
-- Odczytajmy pracowników ze stanowisk ST_CLERK oraz ST_MAN
SELECT
*
FROM
employees
WHERE
job_id
=
'ST_CLERK'
OR
job_id
=
'ST_MAN'
;
-- Operator IN sprawdza czy wartość należy do zbioru.
-- Zbiór można podać w treści zapytania wymieniając wartości w nawiasach okrągłych:
SELECT
*
FROM
employees
WHERE
job_id
IN
(
'ST_CLERK'
,
'ST_MAN'
);
-- Ale operator IN może być też używany w połączeniu z podzapytaniem...
-- Zakładając, że posiadamy tabelę selected_jobs, można by tak:
/* SELECT * FROM employees
WHERE job_id IN (SELECT job FROM selected_jobs); */
-- Operator LIKE - sprawdzanie czy napis pasuje do wzorca
SELECT
*
FROM
employees
WHERE
job_id
LIKE
'ST%'
;
-- We wzorcach:
-- znak % oznacza dowolnej długości ciąg dowolnych znaków
-- znak _ oznacza pojedynczy dowolny znak
-- za pomocą symbolu \ można "wy-escape-ować" znaki specjalne, gdyby miały być faktyczną treścią
SELECT
*
FROM
employees
WHERE
job_id
LIKE
'ST
\_
%'
;
-- Wielkość liter MA znaczenie.
-- wszystkie nazwiska zaczynające się na K
SELECT
first_name
,
last_name
FROM
employees
WHERE
last_name
LIKE
'K%'
;
-- wszystkie nazwiska zaczynające się na K , a kończące się na g
SELECT
first_name
,
last_name
FROM
employees
WHERE
last_name
LIKE
'K%g'
;
-- druga litera nazwiska jest równa a
SELECT
*
FROM
employees
WHERE
last_name
LIKE
'_a%'
;
--! Specyfika PostgreSQL !--
-- W PostgreSQL istnieje dodatkowo ILIKE, który ignoruje wielkość liter
-- bez Oxfrord
SELECT
city
FROM
locations
WHERE
city
LIKE
'%o%o%'
;
-- zawiera Oxford
SELECT
city
FROM
locations
WHERE
city
ILIKE
'%o%o%'
;
-- wersja Oracle:
SELECT
city
FROM
locations
WHERE
lower
(
city
)
LIKE
'%o%o%'
;
-- Informacja nt SIMILAR TO oraz regexp_match
-- https://www.postgresql.org/docs/12/functions-matching.html
-- Uwaga! W WHERE nie można używać aliasów kolumn wprowadzonych w klauzuli SELECT:
-- Takie rzeczy mogą działać w niektórych innych bazach danych
-- (tych lajtowo podchodzących do standardów, np. SQLite :-) ), ale nie w PostgreSQL ani Oracle
-- BŁĄD!
SELECT
first_name
,
last_name
,
12
*
salary
AS
roczne
FROM
employees
WHERE
roczne
<=
100000
;
-- W Postgres (i Oracle) takie rzeczy - jeśli trzeba- realizuje się zapytaniami zagnieżdżonymi:
-- OK
SELECT
*
FROM
(
SELECT
first_name
,
last_name
,
12
*
salary
AS
roczne
FROM
employees
)
sub
WHERE
roczne
<=
100000
;
--* Temat NULL *--
-- Zobaczmy, że NULL nie jest zwykłą wartością, tylko powoduje dziwne zachowania, gdy się pojawia.
-- W tabeli employees istnieje kolumna commission_pct, która u niektórych pracowników zawiera liczbę,
-- a u pozostałych ma wartość NULL.
SELECT
*
FROM
employees
;
-- Gdy próbujemy odczytać pracowników, którzy mają prowizję równą NULL, to nie działa taki zapis,
-- dostaniemy puste wyniki:
SELECT
*
FROM
employees
WHERE
commission_pct
=
NULL
;
-- Odwrotny warunek też daje puste wyniki:
SELECT
*
FROM
employees
WHERE
commission_pct
!=
NULL
;
SELECT
*
FROM
employees
WHERE
NOT
(
commission_pct
=
NULL
);
-- Dla wartości NULL nieprawdą jest ani > , ani <
-- Ci, którzy nie uzyskują prowizji, nie pojawią się ani w jednej, ani w drugiej grupie:
SELECT
*
FROM
employees
WHERE
commission_pct
>
0
.
2
;
SELECT
*
FROM
employees
WHERE
commission_pct
<=
0
.
2
;
-- Aby sprawdzić czy jest jest równa NULL, czy nie, należy użyć wyspecjalizowanych operatorów IS (NOT) NULL
SELECT
*
FROM
employees
WHERE
commission_pct
IS
NULL
;
SELECT
*
FROM
employees
WHERE
commission_pct
IS
NOT
NULL
;
/* Praprzyczyną tego dziwnego zachowania jest fakt, iż na początku historii SQL uznano,
że NULL będzie oznaczał BRAK WIEDZY jaka jest wartość danego pola.
Czyli tak jakby w tym przykładzie wartość NULL znaczyła "nie wiadomo jaką prowizję uzyskuje pracownik".
Do takiego znaczenia wartości NULL dostosowano całą logikę i działanie operatorów.
W praktyce jednak często przyjmuje się, że NULL oznacza "pustą wartość".
Oznacza "wiemy, że czegoś nie ma", jest puste, zerowe, brak.
Tak jak w tym przykładzie, intencją autora tabeli employees było na pewno,
aby NULL w polu commission_pct znaczył "pracownik nie otrzymuje żadnej prowizji".
I tak jest zazwyczaj w praktyce.
Jednak logika SQL tak tego nie rozumie. Dla niej NULL oznacza "nie wiadomo".
Więcej na temat teorii można szukać pod hasłem "logika trójwartościowa SQL".
*/
-- Porównanie z NULLem daje wynik NULL
SELECT
1
=
NULL
;
-- Ale spójniki logiczne starają się robić swoje nawet jeśli czasami jest nieznana wartość.
SELECT
1
=
1
AND
2
=
NULL
;
SELECT
1
=
1
OR
2
=
NULL
;
-- Operacje arytmetyczne itp. , gdzie wewnątrz pojawia się NULL, dają wynik NULL.
SELECT
2
*
(
3
+
NULL
)
-
15
*
4
;
/* Gdy wykonujemy obliczenia, w których pojawia się wartość NULL,
to zazwyczaj wynikiem całego wyrażenia też jest NULL („null zaraża”).
Tutaj pewne uproszczenie: przyjmujemy, że prowizja jest liczona względem pensji,
a nie sprzedaży (której w tej bazie danych nie ma).
Dla każdego pracownika chcemy obliczyć jego wypłatę wraz z dodaną prowizją.
Przy poniższym zapisie wynikiem w ostatniej kolumnie
jest NULL u tych pracowników, którzy nie uzyskują prowizji.
*/
SELECT
first_name
,
last_name
,
salary
,
commission_pct
,
commission_pct
*
salary
-- prowizja kwotowo
,
salary
+
commission_pct
*
salary
-- kwota do wypłaty
FROM
employees
;
-- Aby zastąpić wartość NULL inną "konkretną" wartością, można użyć funkcji COALESCE
SELECT
first_name
,
last_name
,
salary
,
commission_pct
,
coalesce
(
commission_pct
*
salary
,
0
)
as
"kwota prowizji"
,
salary
+
coalesce
(
commission_pct
,
0
)
*
salary
as
"wypłata z prowizją"
FROM
employees
;
-- coalesce(wartosc1, wartosc2, ....) -- dowolnie wiele wartości po przecinku
-- zwraca pierwszą z wartości podanych jako parametry, która nie jest nullem (no chyba ze wszystkie są)
SELECT
coalesce
(
null
,
null
,
'bingo'
,
null
,
'kapusta'
)
FROM
dual
;
-- coalesce jest częścią standardu SQL i działa w większości baz danych
-- W praktyce najczęściej zapisuje się tak: coalesce(kolumna_ktora_moze_byc_null, wartosc_domyslna)
-- Nie ma obowiązku podstawiania zera.
SELECT
first_name
,
last_name
,
salary
,
commission_pct
,
coalesce
(
commission_pct
,
1234
)
FROM
employees
;
--! Specyfika Oracle !--
-- W Oraclu jest też funkcja nvl, która działa tak jak dwuargumentowy coalesce:
-- NVL(x, y): jeśli x nie jest nullem, to zwraca x, a jeśli x jest nullem, to zwraca y
SELECT
first_name
,
last_name
,
salary
,
commission_pct
,
nvl
(
commission_pct
*
salary
,
0
)
as
"kwota prowizji"
,
salary
+
nvl
(
commission_pct
,
0
)
*
salary
as
"wypłata z prowizją"
FROM
employees
;
-- Inne funkcje Oracla związane z obsługą NULL:
-- NVL2(x, y, z)
-- jeśli x nie jest NULL, to zwraca y
-- jeśli x jest NULLem, to zwraca z
SELECT
first_name
,
last_name
,
commission_pct
,
nvl2
(
commission_pct
,
'jest prowizja'
,
'brak prowizji'
)
FROM
employees
;
-- Na siłę można to wykorzystać do wyliczenia łącznej wypłaty:
SELECT
first_name
,
last_name
,
salary
,
commission_pct
,
nvl2
(
commission_pct
,
salary
*
(
1
+
commission_pct
),
salary
)
AS
"wypłata"
FROM
employees
;
-- NULLIF(x, y) -- o!, to działa też w PostgreSQL
-- jeśli x = y, to wynikiem jest NULL
-- jeśli x != y, to wynikiem jest x
SELECT
city
,
nullif
(
city
,
'Toronto'
)
FROM
locations
;
--* ORDER BY - sortowanie wyników *--
-- Zasadniczo podaje się kryterium, wg którego dane wynikowe zostaną posortowane.
SELECT
*
FROM
employees
ORDER
BY
salary
;
-- Domyślnie sortowanie jest rosnące.
-- Aby sortować malejąco, należy dopisać na końcu DESC
SELECT
*
FROM
employees
ORDER
BY
salary
DESC
;
-- Można też dopisać ASC dla rosnącego, ale nie trzeba, bo tak jest domyślnie.
SELECT
*
FROM
employees
ORDER
BY
salary
ASC
;
-- Dodatkowe opcje pozwalają określić miejsce wartości NULL.
-- Domyślnie NULL jest traktowany jak większy od wszystkich wartości
-- (tak jest w PostgreSQL i Oracle, zgodnie ze standardem; w MySQL i SQLite jest odwrotnie)
-- Przy sortowaniu rosnącym nulle będą na końcu.
SELECT
*
FROM
employees
ORDER
BY
commission_pct
;
SELECT
*
FROM
employees
ORDER
BY
commission_pct
ASC
;
-- Przy malejącym nulle będą na początku.
SELECT
*
FROM
employees
ORDER
BY
commission_pct
DESC
;
-- Za pomocą NULLS FIRST / NULLS LAST możemy jawnie podać gdzie mają być nulle
SELECT
*
FROM
employees
ORDER
BY
commission_pct
NULLS
FIRST
;
SELECT
*
FROM
employees
ORDER
BY
commission_pct
ASC
NULLS
FIRST
;
SELECT
*
FROM
employees
ORDER
BY
commission_pct
DESC
NULLS
FIRST
;
SELECT
*
FROM
employees
ORDER
BY
commission_pct
DESC
NULLS
LAST
;
-- Sortować można wg wielu kryteriów wymienionych po przecinku.
-- Np. sortujemy wg nazwiska, a jeśli nazwiska są jednakowe, to wg imienia:
SELECT
*
FROM
employees
ORDER
BY
last_name
,
first_name
;
-- Wtedy ASC i DESC dotyczą tylko ostatniego kryterium, przy którym są napisane.
-- Inaczej mówiąc ASC i DESC muszą być podane niezależnie dla każdego kryterium.
-- Przykład: rosnąco wg job_id, w obrębie każdej takiej grupy malejąco wg pensji,
-- a na końcu rosnąco wg nazwiska i imienia
SELECT
*
FROM
employees
ORDER
BY
job_id
,
salary
DESC
,
last_name
,
first_name
;
-- Dokładnie taki sam efekt:
SELECT
*
FROM
employees
ORDER
BY
job_id
ASC
,
salary
DESC
,
last_name
ASC
,
first_name
ASC
;
-- Co można wpisać jako kryterium?
-- nazwę kolumny
SELECT
*
FROM
employees
ORDER
BY
job_id
,
salary
DESC
;
-- dowolne wyrażenie, nawet takie, którego wyniku nigdzie nie wypisuję
SELECT
*
FROM
employees
ORDER
BY
length
(
first_name
||
last_name
);
-- przykład: wymieszaj dane losowo:
SELECT
*
FROM
employees
ORDER
BY
random
();
-- Wersja Oracle:
-- SELECT * FROM employees ORDER BY dbms_random.random();
-- Posortuj wg pensji z dodaną prowizją, tak jak liczyliśmy wcześniej
SELECT
first_name
,
last_name
,
salary
+
coalesce
(
commission_pct
,
0
)
*
10000
AS
"do wypłaty"
FROM
employees
ORDER
BY
salary
+
coalesce
(
commission_pct
,
0
)
*
10000
;
-- Można też podać alias kolumny
SELECT
first_name
,
last_name
,
salary
+
coalesce
(
commission_pct
,
0
)
*
10000
AS
"do wypłaty"
FROM
employees
ORDER
BY
"do wypłaty"
;
-- Lub numer kolumny licząc od 1
SELECT
first_name
,
last_name
,
salary
+
coalesce
(
commission_pct
,
0
)
*
10000
AS
"do wypłaty"
FROM
employees
ORDER
BY
3
DESC
;
SELECT
employee_id
,
first_name
,
last_name
,
job_id
,
salary
FROM
employees
ORDER
BY
4
,
5
DESC
,
3
,
2
;
-- LIMIT / OFFSET
-- W różnych bazach danych istnieją różne sposoby, aby zapytanie zwróciło tylko pierwszy rekord / X pierwszych rekordów.
-- W PostgreSQL służy do tego dodatkowa klauzula LIMIT / OFFSET dopsywana na końcu zapytania (za klauzulą ORDER BY).
-- To zwraca pierwsze 10 rekordów
SELECT
*
FROM
employees
ORDER
BY
salary
DESC
LIMIT
10
;
-- Używając OFFSET możemy pobierać następne grupy, np. "drugą dziesiątkę"
-- OFFSET pomija określoną liczbę rekordów i zaczyna zwracać pewną liczbę następnych
SELECT
*
FROM
employees
ORDER
BY
salary
DESC
LIMIT
10
OFFSET
10
;
-- Od rekordu 91 do samego końca:
SELECT
*
FROM
employees
ORDER
BY
salary
DESC
OFFSET
90
;
-- Używanie LIMIT / OFFSET bez sortowania jest poprawne technicznie,
-- ale ma mały sens logiczny.
-- Chyba, że w technicznym celu pobrania "próbki danych"...
SELECT
*
FROM
employees
LIMIT
10
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment