Show Menu
Cheatography

składania SQL z zapytaniami

SQL DML (Data Manipu­lation Language)

SELECT
SELECT * FROM tabela;
INSERT
INSERT INTO tabela (kolumna1, kolumna2) VALUES ('wart­ość1', 'warto­ść2');
UPDATE
UPDATE tabela SET kolumna1 = 'nowa_­war­tość' WHERE warunek;
DELETE
DELETE FROM tabela WHERE warunek;
DML umożliwia manipu­lację danymi w bazie danych, obejmuje operacje takie jak wstawi­anie, modyfi­kow­anie, usuwanie i pobieranie danych z bazy.

SQL DQL (Data Query Language)

SELECT
SELECT kolumna1, kolumna2 FROM tabela WHERE warunek;
DISTINCT
SELECT DISTINCT kolumna FROM tabela;
ORDER BY
SELECT kolumna1, kolumna2 FROM tabela ORDER BY kolumna1 ASC;
GROUP BY
SELECT kolumna, COUNT(*) FROM tabela GROUP BY kolumna;
DQL służy do pobierania danych z bazy danych, umożliwia formuł­owanie zapytań, które pozwalają na selekcję i wyszuk­iwanie określ­onych danych z tabel. SQL DQL oferuje również inne funkcje, takie jak filtro­wanie danych za pomocą warunków, łączenie tabel, operatory logiczne i wiele innych. DQL umożliwia elastyczne i precyzyjne pobieranie danych z bazy danych.

SQL DDL (Data Definition Language)

CREATE (TABLE, DATABASE, ...)
CREATE TABLE tabela (   
kolumna1 typ_da­nych,
kolumna2 typ_da­nych,
...
);
CREATE VIEW
CREATE VIEW widok AS 
SELECT kolumna1, kolumna2
FROM tabela
WHERE warunek;
ALTER TABLE (ADD, DROP, ALTER)
ALTER TABLE tabela 
ADD kolumna typ_da­nych;
DROP (TABLE, DATABASE, ...)
DROP TABLE tabela;
DDL służy do defini­owania struktury i organi­zacji bazy danych. DDL umożliwia tworzenie, modyfi­kację i usuwanie obiektów bazy danych, takich jak tabele, widoki, indeksy, sekwencje itp. SQL DDL oferuje również inne instru­kcje, takie jak tworzenie indeksów, sekwencji, ograniczeń integr­aln­ości, procedur składo­wanych i wiele innych. DDL umożliwia defini­owanie struktury i organi­zacji bazy danych, co jest kluczowe dla tworzenia i zarząd­zania danymi w systemach baz danych.

SQL DCL (Data Control Language)

GRANT
używana do udzielania uprawnień użytko­wnikom w bazie danych
GRANT SELECT, INSERT ON tabela TO użytko­wnik;
REVOKE
używana do cofania uprawnień użytko­wnikom w bazie danych
REVOKE DELETE ON tabela FROM użytko­wnik;
GRANT ROLE
używana do nadawania roli użytko­wnikowi w bazie danych
GRANT rola TO użytko­wnik;
COMMIT
używana do zatwie­rdzania transa­kcji, czyli trwałego zapisania zmian wprowa­dzonych w bazie danych
COMMIT;
DCL odpowiada za kontrolę dostępu do bazy danych, obejmuje instrukcje umożli­wiające zarząd­zanie uprawn­ieniami użytko­wników, zabezp­iec­zeniami i transa­kcjami w bazie danych. SQL DCL jest ważnym elementem zarząd­zania bazą danych, umożli­wiając kontrolę dostępu, zabezp­iec­zenia i trwałość danych. DCL zapewnia mechanizmy niezbędne do zarząd­zania uprawn­ieniami użytko­wników oraz zabezp­ieczeń w celu ochrony danych w bazie.

SQL TCL (Trans­act­ional Control Language)

COMMIT
używana do zatwie­rdzania bieżącej transa­kcji, co oznacza trwałe zapisanie wprowa­dzonych zmian w bazie danych
COMMIT;
ROLLBACK
jest używana do wycofy­wania bieżącej transa­kcji, czyli cofania wprowa­dzonych zmian do stanu poprze­dniego
ROLLBACK;
SAVEPOINT
używana do tworzenia punktu zapisu w trakcie trwania transakcji
SAVEPOINT punkt_­zapisu;
RELEASE SAVEPOINT
używana do usunięcia punktu zapisu utworz­onego za pomocą instrukcji SAVEPOINT
RELEASE SAVEPOINT punkt_­zapisu;
TCL obejmuje instrukcje do zarząd­zania transa­kcjami w bazie danych. TCL umożliwia rozpoc­zyn­anie, zatwie­rdzanie i wycofy­wanie transakcji oraz zarząd­zanie punktami zapisu. SQL TCL zapewnia kontrolę nad transa­kcjami w bazie danych, umożli­wiając rozpoc­zyn­anie, zatwie­rdzanie i wycofy­wanie zmian. Dzięki instru­kcjom TCL można zapewnić spójność i integr­alność danych oraz zarządzać punktami zapisu w celu odtwor­zenia stanu transakcji w przypadku potrzeby.

Widoki (Views)

Widoki (ang. views) to wirtualne tabele utworzone na podstawie wyników zapytań SQL. Są to logiczne reprez­entacje danych, które można wykorz­ystać do uprosz­czenia złożonych zapytań, ukrycia szczegółów implem­ent­acy­jnych i zapewn­ienia dostępu do odpowi­ednich danych dla różnych użytko­wników.

Widoki są tworzone na podstawie istnie­jących tabel lub innych widoków, a ich struktura jest defini­owana przez zapytanie SELECT. Po utworzeniu widoku można odwoływać się do niego tak, jakby był to zwykła tabela w bazie danych.

CREATE VIEW SalesR­eport AS

SELECT ProductID, SUM(Qu­antity * Price) AS TotalSales

FROM Sales

WHERE OrderDate BETWEEN '2022-­01-01' AND '2022-­12-31'

GROUP BY ProductID;


SELECT * FROM SalesR­eport;

Łączenie zbiorów (tabel)

UNION
łączy wyniki dwóch zapytań SELECT i zwraca unikalne wiersze. Kolumny w obu zapyta­niach muszą być zgodne pod względem liczby i typów danych
SELECT column1, 
column2
FROM table1
UNION
SELECT column1, column2
FROM table2;
UNION ALL
wykonuje łączenie wyników zapytań bez usuwania duplikatów
SELECT column1, 
column2
FROM table1
WHERE condition
UNION ALL
SELECT column1,
column2
FROM table2
WHERE condition;
INTERSECT
zwraca tylko te wiersze, które występują jednoc­ześnie w wynikach obu zapytań SELECT
SELECT column1, 
column2
FROM table1
INTERSECT
SELECT column1,
column2
FROM table2;
EXCEPT (lub MINUS)
zwraca tylko te wiersze, które występują w wyniku pierwszego zapytania SELECT, ale nie występują w wyniku drugiego zapytania SELECT
SELECT column1, 
column2
FROM table1
EXCEPT
SELECT column1,
column2
FROM table2;

Łączenie tabel

JOIN (INNER JOIN)
SELECT Orders.Or­derID, 
Custom­ers.Cu­sto­merName
FROM Orders
INNER JOIN Customers
ON Orders.Cu­sto­merID = Custom­ers.Cu­sto­merID;
LEFT JOIN
SELECT Custom­ers.Cu­sto­mer­Name, 
Orders.Or­derID
FROM Customers
LEFT JOIN Orders
ON Custom­ers.Cu­sto­merID = Orders.Cu­sto­merID;
RIGHT JOIN
SELECT Custom­ers.Cu­sto­mer­Name, 
Orders.Or­derID
FROM Customers
RIGHT JOIN Orders
ON Custom­ers.Cu­sto­merID = Orders.Cu­sto­merID;
FULL JOIN
SELECT Custom­ers.Cu­sto­mer­Name, 
Orders.Or­derID
FROM Customers
FULL JOIN Orders
ON Custom­ers.Cu­sto­merID = Orders.Cu­sto­merID;
Zagnie­żdżone zapytania (subqu­eries)
SELECT * 
FROM Table1
WHERE Column1 IN (
SELECT Column1
FROM Table2
WHERE Column2 = 'wartość'
);
Warunki złączenia (JOIN condit­ions) w klauzuli WHERE
SELECT * 
FROM Table1,
Table2
WHERE Table1.Co­lumn1 = Table2.Co­lumn1;
Funkcje skalarne
SELECT Table1.Co­lumn1, 
Table1.Co­lumn2, (
SELECT Column3
FROM Table2
WHERE Table2.Co­lumn1 = Table1.Co­lumn1) AS Column3
FROM Table1;
CROSS JOIN
SELECT * 
FROM Table1
CROSS JOIN Table2;
NATURAL JOIN (autom­aty­cznie łączy dwie tabele na podstawie wspólnych nazw kolumn)
SELECT * 
FROM Table1
NATURAL JOIN Table2;

Funkcje okna (window functions)

Funkcje okna (window functions) w SQL umożli­wiają przepr­owa­dzenie obliczeń na grupach wierszy, zwanych "­okn­ami­", wewnątrz wynikowego zestawu danych. Pozwalają na wykony­wanie zaawan­sow­anych operacji agrega­cyj­nych, rankin­gowych i analit­ycznych w kontekście określ­onych grup wierszy. Oto kilka kluczowych informacji na temat funkcji okna wraz z przykł­adami:

1. Składnia:
Funkcje okna są zwykle wywoływane za pomocą specjalnej składni, która zawiera nawiasy okrągłe wokół funkcji oraz klauzulę OVER, która określa, na jakiej podstawie powinna być obliczana funkcja okna.

Przykład:
SELECT order_id, custom­er_id, order_­total, SUM(or­der­_total)

OVER (PARTITION BY custom­er_id) AS sum_or­der­_total

FROM orders;


Rezultat:

order_id | custom­er_id | order_­total | sum_or­der­_total
------­---­---­---­---­---­---­---­---­---­---­---­---­---­---­-----
1 | 101 | 50.00 | 150.00
2 | 101 | 75.00 | 150.00
3 | 102 | 100.00 | 250.00
4 | 103 | 200.00 | 200.00
5 | 103 | 50.00 | 200.00

2. PARTITION BY:
Klauzula PARTITION BY w funkcji okna służy do podziału wynikowego zestawu danych na grupy, na podstawie których funkcje okna są obliczane. Każda grupa otrzymuje niezależne obliczenia funkcji okna.

Przykład:
SELECT column1, column2, AVG(co­lumn3) 

OVER (PARTITION BY column1, column2) AS avg_co­lumn3

FROM table;


W tym przykł­adzie AVG() jest funkcją okna, która oblicza średnią wartości column3 dla każdej kombinacji unikalnych wartości column1 i column2.

3. ORDER BY:
Klauzula ORDER BY w funkcji okna służy do określenia porządku sortowania w obrębie każdej grupy wierszy. Określa to, na podstawie których kolumn mają być obliczane funkcje okna.

Przykład:
SELECT column1, column2, RANK() 

OVER (PARTITION BY column1 

ORDER BY column2 DESC) AS rank_c­olumn2

FROM table;


4. Funkcje okna vs group by
Funkcje okna są bardziej elasty­cznym narzęd­ziem, które pozwala na wykony­wanie obliczeń na grupach wierszy w obrębie wynikowego zestawu danych, zachowując jednoc­ześnie pełną strukturę wynikową. Klauzula GROUP BY jest bardziej odpowi­ednia, gdy chcesz dokonać agregacji danych i otrzymać zreduk­owany wynik dla każdej grupy.

Bardziej zaawan­sowane funkcje agregujące

RANK() / DENSE_­RANK() / ROW_NU­MBER()
Przypisuje wartość rankingu, gęstego rankingu lub numeru wiersza do każdego wiersza w wynikach zapytania
SELECT kolumna, 
RANK() OVER
(ORDER BY kolumna DESC) AS Rank
FROM tabela;
NTILE()
Dzieli zestaw danych na równą liczbę grup i przypisuje numer grupy do każdego wiersza
SELECT kolumna, 
NTILE(4) OVER
(ORDER BY kolumna) AS GroupN­umber
FROM tabela;
CUME_D­IST()
Oblicza kumula­cyjną wartość dystry­bucji dla danego wiersza w zestawie danych
SELECT kolumna, 
CUME_D­IST() OVER
(ORDER BY kolumna) AS Cumula­tiv­eDi­str­ibution
FROM tabela;
FIRST_­VALUE() / LAST_V­ALUE()
Zwraca pierwszą lub ostatnią wartość z określonej kolumny w ramach grupy
SELECT kolumna, 
FIRST_­VAL­UE(­kol­umna)
OVER (PARTITION BY inna_k­olumna
ORDER BY kolejn­a_k­olumna) AS FirstValue
FROM tabela;
LAG() / LEAD()
Zwraca wartość z poprze­dniego lub następnego wiersza w zestawie danych
SELECT kolumna, 
LAG(ko­lumna)
OVER (ORDER BY kolejn­a_k­olumna) AS Previo­usValue
FROM tabela;
NTH_VA­LUE()
Zwraca wartość z określ­onego wiersza w określonym oknie, gdzie numer wiersza jest podany
NTH_VA­LUE­(co­lumn, n) 
OVER (PARTITION BY ...)

row_nu­mber() / rank() / dense_­rank()

ntile(n)

percen­t_r­ank() / cume_d­ist()

first_­val­ue(­expr) / last_v­alu­e(expr)

nth_va­lue­(expr, n)

lead() / lag()

lead(expr, offset, default) - the value for the row offset rows after the current; offset and default are optional; default values: offset = 1, default = NULL
lag(expr, offset, default) - the value for the row offset rows before the current; offset and default are optional; default values: offset = 1, default = NULL

Funkcje WITHIN GROUP

Wyrażenie "­WITHIN GROUP" jest często używane w kontekście funkcji agregu­jących do określania porządku sortowania w wynikach agregacji. Pozwala na kontrolę kolejności sortowania wartości w grupie. Within Group jest szczeg­ólnie przydatne, gdy chcemy kontro­lować kolejność sortowania wartości wewnątrz grupy w wyniku agregacji i dostosować je do naszych wymagań.

- STRING­_AGG, która łączy wartości w jednym łańcuchu znaków, zdefin­iowanym separa­torem.

Przykład:

SELECT custom­er_id, STRING­_AG­G(o­rde­r_id, ', ' ORDER BY order_id) WITHIN GROUP
(ORDER BY order_id) AS order_list

FROM orders

GROUP BY custom­er_id;


Wynik:

+-----­---­---­---­---­+--­---­---­------+
| custom­er_id | order_list |
+-----­---­---­---­---­+--­---­---­------+
| 1001 | 1, 2 |
| 1002 | 3, 4, 5 |
+-----­---­---­---­---­+--­---­---­---­------+

- PERCEN­TIL­E_C­ONT():

SELECT job_title, PERCEN­TIL­E_C­ONT­(0.5) WITHIN GROUP (ORDER BY salary) 

AS median­_salary

FROM employees

GROUP BY job_title;


wynik:
+-----­---­---­---­-+-­---­---­---­---­----+
| job_title | median­_salary |
+-----­---­---­---­-+-­---­---­---­---­----+
| Manager | 5500.00 |
| Developer | 4000.00 |
| Analyst | 3500.00 |
+-----­---­---­---­-+-­---­---­---­---­----+

-PERCE­NTI­LE_­DISC() - służy do obliczania wartości procen­tylowej dyskre­tnego dla określonej grupy danych. Wartość procen­tylowa dyskretna to wartość danych, która odpowiada określ­onemu percen­tylowi.

SELECT PERCEN­TIL­E_D­ISC­(0.75) 

WITHIN GROUP (ORDER BY score) 

AS percen­til­e_value

FROM scores;


+-----­---­---­------+
| percen­til­e_value |
+-----­---­---­------+
| 85 |
+-----­---­---­------+

select

percen­til­e_d­isc­(ar­ray­[0.1, 0.5, 0.9])

within group (order by liczba­_pa­saz­erow) as

kwantyle from wnioski


- PERCEN­TIL­E_D­ISC() vs PERCEN­TIL­E_C­ONT()
Funkcja PERCEN­TIL­E_D­ISC() zwraca dyskretną wartość danych, która odpowiada określ­onemu percen­tylowi. Oznacza to, że wartość procen­tylowa jest jedną z istnie­jących wartości w zbiorze danych. Na przykład, jeśli mamy zbiór liczb [1, 2, 3, 4, 5], to wartość procen­tylowa dyskretna dla 75% będzie wynosić 4, ponieważ 4 jest jedną z wartości w zbiorze.

Funkcja PERCEN­TIL­E_C­ONT() zwraca wartość procen­tylową ciągłą, która jest interp­olacją między wartoś­ciami w zbiorze danych. Oznacza to, że wartość procen­tylowa może być wartością, która nie występuje w zbiorze danych. Na przykład, dla zbioru liczb [1, 2, 3, 4, 5], wartość procen­tylowa ciągła dla 75% może wynosić 4.75, co oznacza interp­olację między 4 a 5 na podstawie proporcji.

- MODE() - służy do znalez­ienia trybu (wartości, która występuje najczę­ściej) w zestawie danych. Oto przykład użycia funkcji MODE() wraz z wynikami

SELECT category, MODE() WITHIN GROUP (ORDER BY category) 

AS mode_c­ategory

FROM products

GROUP BY category;


+-----­---­--+­---­---­---­---­-----+
| category | mode_c­ategory |
+-----­---­--+­---­---­---­---­-----+
| Electr­onics | Electr­onics |
| Clothing | Clothing |
| Books | Books |
+-----­---­--+­---­---­---­---­-----+

Statys­tyczne funkcje agregujące

CORR(d­epe­ndent, indepe­ndent)
Oblicza współc­zynnik korelacji między dwiema zmiennymi
SELECT CORR(s­ales, advert­ising) AS correl­ation 
FROM sales_­data;
COVAR_­POP() / COVAR_­SAMP()
Oblicza kowari­ancję między dwiema zmiennymi
SELECT COVAR_­POP­(in­come, expend­iture) AS covariance 
FROM financ­ial­_data;
STDDEV­_POP() / STDDEV­_SAMP() / STDDEV()
Oblicza odchylenie standa­rdowe danych
SELECT STDDEV­_PO­P(t­emp­era­ture) AS popula­tio­n_s­tddev, 
STDDEV­_SA­MP(­tem­per­ature) AS sample­_st­ddev,
STDDEV­(te­mpe­rature) AS stddev
FROM weathe­r_data;
VAR_POP() / VAR_SAMP() / VARIANCE()
Oblicza wariancję danych
SELECT VAR_PO­P(s­ales) AS population_variance,
VAR_SA­MP(­sales) AS sample_variance,
VARIAN­CE(­sales) AS variance
FROM sales_­data;
REGR_I­NTE­RCEPT()
Oblicza wartość punktu przecięcia linii regresji liniowej
SELECT REGR_I­NTE­RCE­PT(­sales, advert­ising) AS intercept 
FROM sales_­data;
REGR_S­LOPE()
Oblicza współc­zynnik nachylenia linii regresji liniowej.
SELECT REGR_S­LOP­E(s­ales, advert­ising) AS slope 
FROM sales_­data;

Operatory

- Operator IN: Operator IN służy do porówn­ywania wartości z jednym lub więcej wyników podzap­ytania. Zwraca prawdę (true), jeśli wartość znajduje się w wynikach podzap­ytania, w przeciwnym razie zwraca fałsz (false).
Przykład:
SELECT column1

FROM table1

WHERE column2 IN (SELECT column3 FROM table2);


- Operator NOT IN, który wykonuje negację operatora IN. Operator NOT IN zwraca prawdę (true), jeśli wartość nie znajduje się w wynikach podzap­ytania.
Przykład:
SELECT column1

FROM table1

WHERE column2 NOT IN (1, 2, 3);


- Operator = / <> (NOT EQUAL): Operator = służy do porówn­ywania równości między dwiema wartoś­ciami. Operator <> (lub !=) sprawdza, czy wartości są różne od siebie.
Przykład:
SELECT column1

FROM table1

WHERE column2 = 'value';


SELECT column1

FROM table1

WHERE column2 <> 'value';


- Operator EXISTS: Operator EXISTS sprawdza, czy podzap­ytanie zwraca jakiek­olwiek wiersze. Jeśli podzap­ytanie zwraca wyniki, to operator EXISTS zwraca prawdę (true), w przeciwnym razie zwraca fałsz (false). Operator EXISTS jest często stosowany do sprawd­zania istnienia rekordów w innej tabeli.
Przykład:
SELECT column1

FROM table1

WHERE EXISTS (SELECT column2 FROM table2 WHERE column2 = table1.co­lumn3);


- Operator ANY / ALL: Operator ANY porównuje wartość z wynikami podzap­ytania przy użyciu określ­onego operatora porównania (np. >, <, =). Operator ANY zwraca prawdę (true), jeśli porównanie jest prawdziwe dla co najmniej jednego wyniku podzap­ytania. Operator ALL zwraca prawdę (true), jeśli porównanie jest prawdziwe dla wszystkich wyników podzap­ytania.
Przykład:
SELECT column1

FROM table1

WHERE column2 > ANY (SELECT column3 FROM table2);


SELECT column1

FROM table1

WHERE column2 = ALL (SELECT column3 FROM table2);


- Operator BETWEEN: Operator BETWEEN służy do porówn­ywania wartości w określonym zakresie. Sprawdza, czy wartość znajduje się pomiędzy dwiema innymi wartoś­ciami. Może być używany w klauzuli WHERE.
Przykład:
SELECT column1

FROM table1

WHERE column2 BETWEEN 10 AND 20;


- Operator LIKE: Operator LIKE jest używany do porówn­ywania wartości z wyrażeniem regularnym lub wzorcem. Często stosuje się go w klauzuli WHERE w celu wyszuk­iwania wzorców w tekście.
Przykład:
SELECT column1

FROM table1

WHERE column2 LIKE 'A%';


- Operator ILIKE jest używany w niektórych systemach baz danych (np. Postgr­eSQL) i działa podobnie jak operator LIKE, ale jest nieczuły na wielkość liter. Operator ILIKE porównuje wartości z wyrażeniem regularnym lub wzorcem, ignorując różnice w wielkości liter.

Przykład:
SELECT column1

FROM table1

WHERE column2 ILIKE 'a%';


- Operator IS NULL / IS NOT NULL: Operator IS NULL służy do sprawd­zania, czy wartość w kolumnie jest pusta (NULL). Operator IS NOT NULL sprawdza, czy wartość nie jest pusta.
Przykład:
SELECT column1

FROM table1

WHERE column2 IS NULL;

Transakcje SQL

Transakcje SQL to sekwencje operacji, które muszą być wykonane jako całość - albo wszystkie zostaną zatwie­rdzone i zapisane w bazie danych, albo żadna z nich zostanie zapisana. Transakcje są używane do zapewn­ienia spójności danych i utrzymania integr­alności bazy danych.

W SQL transakcje są zazwyczaj używane w kontekście operacji na bazie danych, takich jak wprowa­dzanie zmian, aktual­izacja danych, czytanie i zapisy­wanie danych. Oto podstawowe pojęcia związane z transa­kcjami SQL:

1. BEGIN/­START TRANSA­CTION: Rozpoczyna nową transa­kcję.

BEGIN TRANSA­CTION;


2. COMMIT: Zatwierdza transakcję i wprowadza wszystkie jej zmiany do bazy danych.

COMMIT;


3. ROLLBACK: Anuluje transakcję i cofa wszystkie jej zmiany, przywr­acając bazę danych do stanu przed rozpoc­zęciem transa­kcji.

ROLLBACK;


4. SAVEPOINT: Utworzenie punktu kontro­lnego w trakcie transa­kcji, który można użyć do późnie­jszego przywr­ócenia transakcji do określ­onego stanu.

SAVEPOINT savepo­int­_name;


5. RELEASE SAVEPOINT: Usuwa określony punkt kontrolny utworzony w trakcie transa­kcji.

RELEASE SAVEPOINT savepo­int­_name;


6. ROLLBACK TO SAVEPOINT: Cofa transakcję do określ­onego punktu kontro­lnego, usuwając wszystkie zmiany po tym punkcie.

ROLLBACK TO SAVEPOINT savepo­int­_name;


Transakcje SQL zapewniają spójność danych w przypadku błędów, awarii systemu lub konfliktów jednoc­zesnego dostępu do danych. Pozwalają również na grupowanie operacji w większe jednostki logiczne i wprowa­dzanie zmian do bazy danych w kontro­lowany sposób.

Warto zauważyć, że nie wszystkie systemy bazodanowe obsługują transakcje w taki sam sposób, a składnia i zachowanie mogą się różnić. Należy skonsu­ltować się z dokume­ntacją systemu bazoda­nowego, którego używasz, aby uzyskać szczeg­ółowe informacje na temat transakcji SQL w danym systemie.

Najpro­stszą transkacją w SQL Server jest pojedyncza instrukcja modyfi­kacji danych.
UPDATE Person.Ad­dress

SET Addres­sLine1 = 'Prosta 51'

WHERE AddressID = 1


Transakcje z wieloma operacjami (Explicit Transa­ctions)
BEGIN TRANSA­CTION

UPDATE Person.Ad­dress

SET Addres­sLine1 = 'Prosta 51'

WHERE AddressID = 1

UPDATE Person.Ad­dress

SET Addres­sLine1= 'Przyo­kopowa 31'

WHERE AddressID = 2`
COMMIT TRANSA­CTION`

Procedury, funkcje i triggery

Procedury, funkcje i triggery są elementami języka SQL, które pozwalają na defini­owanie i wykony­wanie niesta­nda­rdowych operacji i logiki w bazie danych. Oto ich krótkie opisy:

1. Procedury:
- Procedury to zbiorcze instrukcje SQL, które są zdefin­iowane i przech­owywane w bazie danych.
- Procedury mogą przyjmować parametry wejściowe, wykonywać operacje na danych, a następnie zwracać wyniki lub modyfi­kować dane w bazie.
- Procedury mogą być wywoływane przez inne zapytania SQL lub programy aplika­cyjne.
- Przykład:

CREATE PROCEDURE GetCus­tom­erO­rders

    @custo­merId INT

AS

BEGIN

    SELECT * FROM Orders WHERE CustomerId = @custo­merId;

END;


2. Funkcje:
- Funkcje są podobne do procedur, ale różnią się sposobem użycia i zwracanymi wartoś­ciami.
- Funkcje zwracają wartość, która może być wykorz­ystana w zapyta­niach SQL, wyraże­niach lub instru­kcjach.
- Mogą być wykorz­yst­ywane jako część zapytań SELECT, warunków WHERE, wyrażeń CASE itp.
- Funkcje mogą być skalarnymi funkcjami (zwrac­ające pojedynczą wartość) lub funkcjami tabela­ryc­znymi (zwrac­ające tabelę wynikową).
- Przykład:

CREATE FUNCTION GetOrd­erTotal

    (@orderId INT)

RETURNS DECIMA­L(10, 2)

AS

BEGIN

    DECLARE @total DECIMA­L(10, 2);

    SELECT @total = SUM(Qu­antity * Price) FROM OrderItems WHERE OrderId = @orderId;

    RETURN @total;

END;


3. Triggery:
- Triggery są automa­tyc­znymi reakcjami na zdarzenia lub operacje w bazie danych, takie jak wstawi­anie, aktual­izacja lub usuwanie danych.
- Trigger to blok kodu SQL, który jest wywoływany w odpowiedzi na określone zdarzenie.
- Triggery mogą być defini­owane dla tabel i urucha­miane przed lub po wykonaniu określ­onych operacji.
- Mogą być wykorz­yst­ywane do wprowa­dzania logiki biznes­owej, sprawd­zania warunków, synchr­oni­zacji danych itp.
- Przykład:

CREATE TRIGGER Update­Ord­erTotal

ON OrderItems

AFTER INSERT, UPDATE, DELETE

AS

BEGIN

    UPDATE Orders

    SET TotalA­mount = (SELECT SUM(Qu­antity * Price) FROM OrderItems WHERE OrderId =
insert­ed.O­rd­erId)

    FROM Orders INNER JOIN inserted ON Orders.Or­derId = insert­ed.O­rd­erId;

END;


Procedury, funkcje i triggery są potężnymi narzęd­ziami w SQL, które pozwalają na tworzenie bardziej zaawan­sow­anych operacji, logiki biznesowej i automa­tyzacji w bazach danych. Ich zastos­owanie zależy od konkre­tnych wymagań i scenar­iuszy w projekcie bazoda­nowym.

* "­@" przed nazwą oznacza, że jest to nazwa parametru wejści­owego funkcji.

sprawd­zanie typów danych

- Aby sprawdzić typy danych w tabeli, można skorzystać z polecenia DESCRIBE lub DESC. Oto przykład:
DESCRIBE tabela;

Lub
DESC tabela;

To polecenie wyświetli informacje o strukturze tabeli, w tym nazwy kolumn, typy danych, rozmiary kolumn itp.

- Altern­aty­wnie, można również skorzystać z zapytania SHOW COLUMNS FROM tabela, które również zwróci informacje o typach danych w tabeli. Oto przykład:
SHOW COLUMNS FROM tabela;

Oba te polecenia zwrócą wyniki, które przeds­tawiają typy danych dla każdej kolumny w tabeli, wraz z innymi inform­acjami takimi jak nazwy kolumn, klucze główne, atrybuty null itp.

- Aby sprawdzić typ danych na konkretnej kolumnie w tabeli, można użyć polecenia DESCRIBE z podaniem nazwy kolumny. Oto przykład:
DESCRIBE tabela nazwa_­kol­umny;


Na przykład, jeśli chcemy sprawdzić typ danych kolumny "­imi­e" w tabeli "­uzy­tko­wni­cy", użyjemy polecenia:
DESCRIBE uzytko­wnicy imie;

Polecenie to zwróci informacje dotyczące typu danych dla określonej kolumny, takie jak typ danych, rozmiar, atrybuty null itp.

SELECT a SELECT ''

Różnica między SELECT FROM tabela a SELECT '' FROM tabela polega na tym, jak zostaną zwrócone dane.

- SELECT * FROM tabela: Wykonanie tego zapytania zwróci wszystkie kolumny (wszystkie dane) z tabeli. Każda kolumna zostanie zwrócona jako oddzielna kolumna wynikowa. Przykład:
CREATE TABLE osoba (

  id INT,

  imie VARCHA­R(50),

  nazwisko VARCHA­R(50)

);


INSERT INTO osoba (id, imie, nazwisko)

VALUES (1, 'John', 'Doe'),

       (2, 'Jane', 'Smith');


SELECT * FROM osoba;


Wynik:

| id | imie | nazwisko |
|----|­---­---­|--­---­-----|
| 1 | John | Doe |
| 2 | Jane | Smith |

- SELECT '*' FROM tabela: Wykonanie tego zapytania zwróci pojedynczą kolumnę, w której każdy wiersz będzie zawierał tekst '' (gwiaz­dkę). Oznacza to, że nie zostaną zwrócone rzeczy­wiste dane z tabeli, tylko powtórzony znak '', tyle razy, ile jest wierszy w tabeli. Przykład:
CREATE TABLE osoba (

  id INT,

  imie VARCHA­R(50),

  nazwisko VARCHA­R(50)

);


INSERT INTO osoba (id, imie, nazwisko)

VALUES (1, 'John', 'Doe'),

       (2, 'Jane', 'Smith');


SELECT '*' FROM osoba;


Wynik:

| '*' |
|-----|
| '*' |
| '*' |

Jak widać, w drugim przypadku zwracane są tylko powtórzone gwiazdki, nie uwzglę­dniając rzeczy­wistych danych z tabeli.

Należy pamiętać, że SELECT '*' FROM tabela może mieć zastos­owanie w niektórych specja­lnych przypa­dkach, np. jako szybka metoda sprawd­zenia, czy tabela zawiera dane, ale nie jest to typowe użycie przy wybieraniu rzeczy­wistych danych z tabeli.

operator LIKE

W operatorze
LIKE
w języku SQL można używać różnych wzorców. Oto kilka najczę­ściej stosow­anych wzorców wraz z ich opisem:

1.
%
(znak procentu):
Symbol
%
odpowiada dowolnej liczbie znaków (również zero znaków). Może być używany na początku, na końcu lub w środku wzorca. Przykłady:
-
'%abc'
- pasuje do ciągów, które kończą się na 'abc'
-
'abc%'
- pasuje do ciągów, które zaczynają się od 'abc'
-
'%abc%'
- pasuje do ciągów, które zawierają 'abc' gdziek­olwiek

2.
_
(podkr­eśl­nik):
Symbol
_
odpowiada dokładnie jednemu znakowi. Może być używany na początku, na końcu lub w środku wzorca. Przykłady:
-
'a_'
- pasuje do dwuzna­kowych ciągów, które zaczynają się od 'a'
-
'_bc'
- pasuje do dwuzna­kowych ciągów, które kończą się na 'bc'
-
'_b_'
- pasuje do trzyzn­akowych ciągów, które mają 'b' na drugiej pozycji

3.
[]
(klasy znaków):
Klasy znaków pozwalają na określenie zbioru dopusz­cza­lnych znaków w danej pozycji. Przykłady:
-
'a[bc]d'
- pasuje do ciągów, które mają 'a', a następnie 'b' lub 'c', a potem 'd'
-
'[0-9]abc'
- pasuje do ciągów, które mają cyfrę od 0 do 9, a następnie 'abc'

4.
[^]
(negacja klasy znaków):
Negacja klasy znaków oznacza dopaso­wanie znaku, który nie jest w podanym zbiorze. Przykład:
-
'a[^bc]d'
- pasuje do ciągów, które mają 'a', a następnie znak, który nie jest 'b' ani 'c', a potem 'd'

Te wzorce można również łączyć i zagnie­żdżać, aby tworzyć bardziej zaawan­sowane wyrażenia dopaso­wania w operatorze
LIKE
. Warto pamiętać, że składnia i dostępność wzorców mogą się nieco różnić w zależności od używanej bazy danych.

W zwykłym operatorze LIKE w języku SQL nie ma wbudowanej składni [a-z], która reprez­entuje zakres liter od "­a" do "­z" (czyli wszystkie małe litery w alfabecie angiel­skim). Operator LIKE obsługuje jedynie proste wzorce z wykorz­yst­aniem symboli % i _, oraz klasy znaków [].

Jednak w niektórych bazach danych, takich jak PostgreSQL i MySQL, można użyć wyrażeń regula­rnych wraz z operatorem REGEXP lub RLIKE do bardziej zaawan­sow­anych dopasowań, w tym zakresów liter.

Przykład z użyciem wyrażeń regula­rnych w Postgr­eSQL:

SELECT column­_name

FROM table_name

WHERE column­_name ~ '^[a-z]$';


Przykład z użyciem wyrażeń regula­rnych w MySQL:

SELECT column­_name

FROM table_name

WHERE column­_name REGEXP '^[a-z]$';


W powyższych przykł­adach wyrażenie regularne ^[a-z]$ oznacza dopaso­wanie jednej małej litery od "­a" do "­z" w kolumnie. Uwaga, że składnia i obsługa wyrażeń regula­rnych mogą się różnić w zależności od konkretnej bazy danych.

Wzorce takie jak % i _ wciąż mają takie same znaczenie w przypadku operatora ILIKE. Jednak operatory klasy znaków [ ] i [^ ] nie będą działać w dokładnie ten sam sposób jak w przypadku operatora LIKE. Zachowanie tych wzorców w kontekście ILIKE zależy od konkretnej bazy danych.

is null = '', not null, <> ''

W przypadku pustych wartości (NULL) w języku SQL, operator
IS NULL
jest używany do sprawd­zania, czy wartość w kolumnie jest pusta (NULL), a operator
IS NOT NULL
jest używany do sprawd­zania, czy wartość w kolumnie nie jest pusta (nie jest NULL).

Natomiast porównanie pustej wartości z pustym ciągiem znaków
"­"
(empty string) jest czymś innym. Pusty ciąg znaków
"­"
jest traktowany jako niepusty (non-NULL) ciąg, ale nie ma żadnej zawart­ości. Oznacza to, że porównanie
=
z pustym ciągiem znaków nie jest równoważne z operatorem
IS NULL
.

Przykład:

SELECT column­_name

FROM table_name

WHERE column­_name = '';


W powyższym przykł­adzie,
column­_name = ''
porównuje wartość w kolumnie
column­_name
z pustym ciągiem znaków
''
. To sprawdzi, czy wartość jest pustym ciągiem, ale nie sprawdzi, czy jest NULL.

Podobnie, porównanie
<>
z pustym ciągiem znaków nie jest równoważne z operatorem
IS NOT NULL
. Porównanie
<>
z pustym ciągiem znaków sprawdzi, czy wartość w kolumnie jest różna od pustego ciągu znaków, ale nadal może zawierać wartość NULL.

Jeśli chcesz sprawdzić, czy wartość w kolumnie jest pusta lub NULL, powinieneś nadal używać operatorów
IS NULL
lub
IS NOT NULL
.

Wniosek: Porównanie pustego ciągu znaków
''
nie jest równoważne z operatorem
IS NULL
, a porównanie
<> ''
nie jest równoważne z operatorem
IS NOT NULL
. Dlatego zaleca się używanie operatorów
IS NULL
i
IS NOT NULL
do sprawd­zania pustych wartości w SQL.

Funkcje agregujące z groupby a w funkcji okna

Użycie funkcji agregu­jących z klauzulą
GROUP BY
i w funkcjach okna ma kilka istotnych różnic:

1. Działanie na grupach: Użycie funkcji agregu­jących z klauzulą
GROUP BY
pozwala na grupowanie danych na podstawie określ­onych kolumn i obliczanie agregatów dla każdej grupy. Wyniki są podzielone na grupy, a funkcje agregujące są obliczane dla każdej grupy osobno.

Przykład:
SELECT depart­ment, SUM(sa­lary) AS total_­salary

FROM employees

GROUP BY depart­ment;


Użycie funkcji okna, z drugiej strony, nie grupuje danych w taki sposób. Funkcje okna obliczają wartości dla każdego wiersza w wyniku, niezal­eżnie od grupow­ania. Funkcje okna działają na całym zbiorze wynikowym i nie powodują podziału na grupy.

Przykład:
SELECT employ­ee_id, last_name, salary, SUM(sa­lary) 

OVER (PARTITION BY depart­ment) AS total_­salary

FROM employees;


W powyższym przykł­adzie, funkcja okna
SUM
jest używana do obliczania sumy wynagr­odzenia dla każdego pracownika w ramach danego depart­amentu, ale nie powoduje to podziału na grupy.

2. Zakres obliczeń: Użycie funkcji agregu­jących z klauzulą
GROUP BY
ogranicza wyniki do grup, dla których obliczone są agregaty. Każda grupa jest reprez­ent­owana przez jeden wiersz wynikowy.

W przypadku funkcji okna, wynikowe wiersze odpowi­adają wszystkim wierszom z wyniku zapytania, a funkcje okna obliczają wartości na podstawie określ­onych okien (partycji) i kolejności sortow­ania. Wynik zwracany przez funkcje okna zachowuje wszystkie wiersze, a nie tworzy jednego wiersza na grupę.

3. Składnia zapytania: Użycie funkcji agregu­jących z klauzulą
GROUP BY
wymaga wyraźnego określenia kolumn, które mają być uwzglę­dnione w grupow­aniu. Natomiast użycie funkcji okna odbywa się za pomocą odpowi­edniej składni w ramach klauzuli
SELECT
, bez koniec­zności podawania klauzuli
GROUP BY
.

Przykład:
SELECT depart­ment, AVG(sa­lary) AS avg_salary

FROM employees

GROUP BY depart­ment;


SELECT employ­ee_id, last_name, salary, AVG(sa­lary) 

OVER (PARTITION BY depart­ment) AS avg_salary

FROM employees;


W przypadku funkcji okna, nie ma potrzeby podawania kolumny
department
w klauzuli
SELECT
. Funkcja okna jest wywoływana bezpoś­rednio w zapytaniu
SELECT
, a wynik jest automa­tycznie obliczany dla każdego wiersza.

Podsum­owując, użycie funkcji agregu­jących z klauzulą
GROUP BY
jest skonce­ntr­owane na grupowaniu danych i obliczaniu agregatów dla poszcz­egó­lnych grup, podczas gdy funkcje okna działają na poziomie pojedy­nczego wiersza i pozwalają na obliczanie wartości w ramach zdefin­iow­anych okien i kolejności sortowania bez podziału na grupy. Ostateczny wybór między tymi podejś­ciami zależy od wymagań zapytania i oczeki­wanych wyników.

Tabela DUAL

Tabela "­DUA­L" jest specjalną tabelą w niektórych bazach danych, takich jak Oracle, która jest często używana do wykony­wania zapytań testowych, testowania wyrażeń SQL lub pobierania wartości bez odwoły­wania się do rzeczy­wistych tabel w bazie danych.

Tabela "­DUA­L" zawiera tylko jedną kolumnę o nazwie "­DUM­MY" i jedno zawsze jedno wiersz o wartości "­X" lub "­Y". Ta tabela jest zawsze dostępna w bazie danych i nie wymaga jej tworzenia.

Przykład użycia tabeli "­DUA­L":

SELECT 'Hello, World!' AS message FROM DUAL;


W tym przykł­adzie wykonujemy prosty zapytanie, które zwraca wartość 'Hello, World!' jako kolumnę "­mes­sag­e". Ponieważ nie potrze­bujemy się odwoływać do żadnej konkretnej tabeli, używamy tabeli "­DUA­L" jako źródła danych. Zapytanie to zwróci tylko jeden wiersz z jedną kolumną.

Tabela "­DUA­L" jest szczeg­ólnie przydatna w przypa­dkach, gdy chcemy wykonać prosty testowy zapytanie, przete­stować składnię SQL lub wygene­rować wartości stałe bez koniec­zności odwoły­wania się do istnie­jących tabel w bazie danych.

Warto jednak zaznaczyć, że nie wszystkie bazy danych obsługują tabelę "­DUA­L" jako domyślną tabelę specjalną. Niektóre bazy danych, takie jak MySQL czy SQL Server, nie mają wbudowanej tabeli "­DUA­L". W takich przypa­dkach można użyć innego podejścia, na przykład używając instrukcji
SELECT
bez odwoły­wania się do jakiej­kolwiek tabeli, lub tworząc tymczasową tabelę do testowania zapytań.

Pseudo kolumny

Pseudo­-ko­lumny to specjalne kolumny dostępne w języku SQL, które zawierają dodatkowe informacje na temat danych lub kontekstu zapytania. Pseudo­-ko­lumny nie są fizycznymi kolumnami w tabeli, ale są dostępne do użycia w zapyta­niach SQL. Poniżej przeds­tawiam kilka popula­rnych pseudo­-ko­lumn:

1.
ROWNUM
(Oracle) lub
ROW_NU­MBER()
(inny dialekt SQL):
Ta pseudo­-ko­lumna zawiera numer porządkowy wiersza w zbiorze wynikowym. Jest szczeg­ólnie przydatna przy ograni­czaniu wyników zapytania do określonej liczby wierszy lub wykony­waniu paginacji.

Przykład:
SELECT ROWNUM, first_­name, last_name

FROM employees

WHERE ROWNUM <= 10;


2.
ROWID
(Oracle) lub
CTID
(Postg­reSQL):
Ta pseudo­-ko­lumna zawiera unikalny identy­fikator wiersza w tabeli. Jest używana głównie do bezpoś­red­niego odwoły­wania się do konkre­tnych wierszy w celu aktual­izacji lub usunięcia.

Przykład:
UPDATE employees

SET salary = 5000

WHERE ROWID = 'AAABB­BCCC';


3.
SYSDATE
(Oracle) lub
CURREN­T_T­IME­STAMP
(inny dialekt SQL):
Ta pseudo­-ko­lumna zawiera aktualną datę i czas na serwerze bazy danych.

Przykład:
SELECT order_id, order_­date, SYSDATE AS curren­t_date

FROM orders;


4.
LEVEL
(Oracle) lub
GENERATION
(inny dialekt SQL):
Ta pseudo­-ko­lumna jest używana w zapyta­niach rekure­ncy­jnych lub do określenia poziomu hierarchii w zapyta­niach związanych z drzewem.

Przykład:
SELECT employ­ee_id, last_name, LEVEL

FROM employees

START WITH employ­ee_id = 1

CONNECT BY PRIOR employ­ee_id = manage­r_id;


5.
OBJECT_ID
(Oracle): Pseudo­-ko­lumna
OBJECT_ID
jest używana w Oracle Database do zwracania identy­fik­atora obiektu bazy danych. Może być używana w zapyta­niach dotycz­ących metadanych lub dostępu do informacji o konkretnym obiekcie bazy danych, takim jak tabela, widok, procedura, itp.

Przykład:
SELECT object­_name, object­_type

FROM all_ob­jects

WHERE object_id = 12345;


6.
OBJECT­_VALUE
(Oracle): Pseudo­-ko­lumna
OBJECT­_VALUE
jest używana w Oracle XML DB do zwracania wartości XML dla obiektu XML w bazie danych. Może być stosowana w zapyta­niach, które operują na danych XML przech­owy­wanych w bazie danych Oracle.

Przykład:
SELECT object_id, object­_value

FROM xml_table;


7.
ORA_ROWSCN
(Oracle): Pseudo­-ko­lumna
ORA_ROWSCN
jest używana w Oracle Database do zwracania System Change Number (SCN) dla wiersza. SCN jest unikalnym identy­fik­atorem przypi­sanym do każdego wiersza w bazie danych i może być używany do monito­rowania zmian i śledzenia historii danych.

Przykład:
SELECT rowid, ora_rowscn

FROM my_table;


8.
XMLDATA
(Oracle): Pseudo­-ko­lumna
XMLDATA
jest używana w Oracle XML DB do zwracania danych XML w formacie XMLType. Może być stosowana w zapyta­niach, które operują na danych XML przech­owy­wanych w bazie danych Oracle.

Przykład:
SELECT xmldata

FROM xml_table;


9.
CURRVAL
i
NEXTVAL
(Oracle): Pseudo­-ko­lumny
CURRVAL
i
NEXTVAL
są używane w Oracle Database w połączeniu z sekwen­cjami (seque­nces) do pobierania bieżącej lub następnej wartości sekwencji.
CURRVAL
zwraca bieżącą wartość sekwencji, podczas gdy
NEXTVAL
zwraca następną wartość sekwencji.

Przykład:
SELECT my_seq­uen­ce.N­EXTVAL

FROM dual;


10.
CONNEC­T_B­Y_I­SCYCLE
(Oracle): Pseudo­-ko­lumna
CONNEC­T_B­Y_I­SCYCLE
jest używana w Oracle Database w kontekście zapytań związanych z drzewami (
CONNECT BY
) do oznacz­enia, czy wystąpił cykl w hierar­chii. Zwraca wartość 1, jeśli wierzc­hołek jest częścią cyklu, lub 0 w przeciwnym razie.

Przykład:
SELECT employ­ee_id, last_name, CONNEC­T_B­Y_I­SCYCLE

FROM employees

START WITH employ­ee_id = 1

CONNECT BY PRIOR employ­ee_id = manage­r_id;


Pseudo­-ko­lumny różnią się w zależności od dialektu SQL i używanej bazy danych. Nie wszystkie pseudo­-ko­lumny są dostępne we wszystkich bazach danych, dlatego zawsze warto sprawdzić dokume­ntację swojej konkretnej bazy danych, aby dowiedzieć się, jakie pseudo­-ko­lumny są dostępne i jak ich używać.

Self Join

Self join w języku SQL jest techniką polegającą na łączeniu tabeli z samą sobą. Oznacza to, że w zapytaniu używamy tej samej tabeli jako dwóch odrębnych instancji, które łączymy ze sobą na podstawie warunków zdefin­iow­anych w klauzuli ON.

Przykładem może być tabela "­emp­loy­ees­" zawier­ająca informacje o pracow­nikach, gdzie mamy kolumny "­emp­loy­ee_­id", "­fir­st_­nam­e", "­las­t_n­ame­" i "­man­age­r_i­d", w której "­man­age­r_i­d" wskazuje na identy­fikator przeło­żonego danego pracow­nika.

Przykład zapytania self join, które zwraca informacje o pracow­nikach i ich przeło­żonych, może wyglądać tak:

SELECT e.firs­t_name AS employ­ee_­fir­st_­name, e.last­_name AS employ­ee_­las­t_name,

       m.firs­t_name AS manage­r_f­irs­t_name, m.last­_name AS manage­r_l­ast­_name

FROM employees e

JOIN employees m ON e.mana­ger_id = m.empl­oye­e_id;


W powyższym przykł­adzie tabela "­emp­loy­ees­" jest łączona z samą sobą na podstawie warunku e.mana­ger_id = m.empl­oye­e_id. Otrzym­ujemy wynik, w którym dla każdego pracownika zostaje wyświe­tlone imię i nazwisko pracownika oraz imię i nazwisko jego przeło­żonego.

Self join jest przydatny w sytuac­jach, gdy mamy hierarchię danych w jednej tabeli, na przykład struktury organi­zac­yjnej lub relacji między danymi. Pozwala nam na skompl­ikowane zapytania, które wykorz­ystują powiązania między rekordami w tej samej tabeli.

Typ danych złożonych

Typ danych złożony (composite data type) to typ danych, który pozwala na grupowanie i przech­owy­wanie innych typów danych jako pojedy­nczej jednostki. Najczę­ściej używane typy złożone to rekordy (record) i tablice (array).

1. Rekordy (record):
- Rekord to struktura danych, która może zawierać wiele pól o różnych typach danych.
- Definicja rekordu wymaga zdefin­iowania nazw pól i odpowi­ada­jących im typów danych.
- Przykład składni w Postgr­eSQL:

CREATE TYPE person­_type AS (

 first_name VARCHA­R(50),

 last_name VARCHA­R(50),

 age INT

);


- Przykład użycia rekordu:

DECLARE

  person person­_type;

BEGIN

  person.fi­rst­_name := 'John';

  person.la­st_name := 'Doe';

  person.age := 30;

  ...

END;


2. Tablice (array):
- Tablica to struktura danych, która pozwala na przech­owy­wanie wielu wartości tego samego typu w jednym polu.
- Definicja tablicy wymaga określenia typu danych elementów tablicy.
- Przykład składni w Postgr­eSQL:

CREATE TYPE colors AS VARCHA­R(20) ARRAY;


- Przykład użycia tablicy:

DECLARE

  color_list colors := ARRAY[­'red', 'green', 'blue'];

  ...

END;


Warto zauważyć, że składnia i obsług­iwane typy złożone mogą się różnić w zależności od konkre­tnego systemu zarząd­zania bazą danych. Przed użyciem konkre­tnego typu złożonego zaleca się zapoznanie się z dokume­ntacją systemu bazoda­nowego, aby uzyskać dokładne informacje na temat składni, zachowania i dostępnych funkcji dla danego typu złożonego.

DECODE - mapowanie wartości

Funkcja
DECODE
w języku SQL jest często używana do mapowania wartości na podstawie określ­onych równań lub warunków. Można to zakwal­ifi­kować jako operację warunk­owego przypi­sania wartości. Funkcja
DECODE
porównuje wartość wyrażenia z zestawem wartości i zwraca odpowi­adający wynik dla pierwszej pasującej wartości.

Poniżej przeds­tawiam kilka zastosowań funkcji
DECODE
:

1. Mapowanie wartości:
SELECT

    column­_name,

    DECODE­(co­lum­n_name, value1, result1, value2, result2, defaul­t_r­esult) AS mapped­_value

FROM table_­name;


Przykład:
SELECT

    produc­t_name,

    DECODE­(ca­teg­ory_id, 1, 'Elect­ron­ics', 2, 'Cloth­ing', 'Other') AS catego­ry_name

FROM products;


2. Przypi­sanie wartości na podstawie warunków:
SELECT

    column­_name,

    DECODE­(co­ndi­tion, value1, result1, value2, result2, defaul­t_r­esult) AS result

FROM table_­name;


Przykład:
SELECT

    order_­date,

    DECODE­(SI­GN(­tot­al_­amount - 100), 1, 'Above', -1, 'Below', 'Equal') AS status

FROM orders;


Funkcja
DECODE
jest często używana w starszych systemach baz danych, takich jak Oracle. W nowocz­esnych bazach danych istnieją również inne konstr­ukcje, takie jak instrukcja
CASE
, które zapewniają bardziej elastyczną i czytelną składnię do realizacji podobnych operacji warunk­owych.

Czym są sekwencje?

Sequences (sekwe­ncje) w bazach danych są obiektami służącymi do genero­wania unikalnych numerów sekwen­cyj­nych. Są one często używane do automa­tyc­znego genero­wania wartości kluczy głównych lub innych unikalnych identy­fik­atorów w tabelach.

Główne cechy sekwencji to:

1. Unikal­ność: Sekwencje zapewniają unikalność genero­wanych wartości. Każda wygene­rowana wartość jest różna od poprze­dnich i następ­nych.

2. Bezsta­nowość: Sekwencje są bezsta­nowe, co oznacza, że nie przech­owują żadnych informacji o poprzednio wygene­row­anych wartoś­ciach. Przy każdym wywołaniu sekwencji generowana jest kolejna wartość zgodnie z zdefin­iowanym przez nas krokiem.

3. Niezal­eżność transa­kcji: Wywołania sekwencji są niezależne od transa­kcji. Oznacza to, że wartości sekwencji są generowane niezal­eżnie od innych operacji wykony­wanych w ramach transa­kcji.

Przykład tworzenia i użycia sekwencji w języku SQL (na przykł­adzie Oracle):

-- Tworzenie sekwencji

CREATE SEQUENCE seq_em­plo­yee_id

    START WITH 1

    INCREMENT BY 1

    NOCACHE;


-- Wykorz­ystanie sekwencji do genero­wania wartości

INSERT INTO employees (emplo­yee_id, employ­ee_­name)

VALUES (seq_e­mpl­oye­e_i­d.N­EXTVAL, 'John Doe');


W powyższym przykł­adzie tworzona jest sekwencja
seq_em­plo­yee_id
, która rozpoczyna się od 1 i inkrem­entuje wartość o 1 przy każdym wywołaniu. Następnie sekwencja jest wykorz­yst­ywana do genero­wania wartości klucza głównego podczas wstawiania danych do tabeli
employees
.

Sekwencje są dostępne w różnych systemach baz danych, takich jak Oracle, Postgr­eSQL, czy SQL Server. Składnia i opcje tworzenia sekwencji mogą się nieco różnić w zależności od konkre­tnego systemu bazoda­nowego. Należy sprawdzić dokume­ntację swojego systemu baz danych, aby dowiedzieć się więcej o tworzeniu i używaniu sekwencji.
 

SKŁADNIA

W języku SQL, składnia zapytań zazwyczaj przyjmuje postać:

SELECT - określa, które kolumny mają zostać zwrócone lub jakie wyrażenia mają zostać obliczone.
FROM - wskazuje, z jakich tabel lub widoków mają zostać pobrane dane.
WHERE - określa warunki filtrujące wiersze, które mają zostać zwrócone na podstawie określ­onych kryteriów.
GROUP BY - grupuje wyniki według określ­onych kolumn.
HAVING - filtruje grupy na podstawie warunków.
ORDER BY - sortuje wyniki według określ­onych kolumn w określonej kolejn­ości.
LIMIT/­OFFSET (opcjo­nalne) - ogranicza liczbę zwracanych wierszy lub przesuwa wyniki o określoną liczbę wierszy.
Oczywi­ście, nie wszystkie klauzule muszą być obecne w każdym zapytaniu. Składnia i kolejność klauzul zależą od konkre­tnego rodzaju zapytania i wymagań.

Przykł­adowa składnia zapytania SELECT może wyglądać tak:

SELECT kolumny

FROM tabela

WHERE warunki

GROUP BY kolumny

HAVING warunki

ORDER BY kolumny

LIMIT liczba­_wi­erszy

OFFSET przesu­niecie;


Ważne jest przest­rze­ganie poprawnej składni SQL, aby zapewnić poprawne wykonanie zapytań i otrzymanie oczeki­wanych wyników.

Numeryczne typy danych

INTEGER
Reprez­entuje liczby całkowite o ograni­czonym zakresie
43
BIGINT
Reprez­entuje duże liczby całkowite.
9876543210
DECIMAL(p, s) lub NUMERIC(p, s)
Reprez­entuje liczby zmienn­opr­zec­inkowe o precyzji p (liczba całkowita) i skali s (liczba miejsc po przeci­nku).
12.345
FLOAT(p)
Reprez­entuje liczby zmienn­opr­zec­inkowe o podwójnej precyzji.
3.14159
REAL
Reprez­entuje liczby zmienn­opr­zec­inkowe o jednos­tronnej precyzji.
2.71828
SMALLINT
Reprez­entuje małe liczby całkowite o ograni­czonym zakresie.
123
NUMERIC(p, s)
Reprez­entuje liczby zmienn­opr­zec­inkowe o precyzji p i skali s.
9876.54321
DOUBLE PRECISION
Reprez­entuje liczby zmienn­opr­zec­inkowe o podwójnej precyzji.
1.2345­678­9012345
DEC
Reprez­entuje liczby zmienn­opr­zec­inkowe o precyzji i skali dostos­owanej do konkre­tnego systemu bazoda­nowego.
456.789
NUM
Reprez­entuje liczby zmienn­opr­zec­inkowe o precyzji i skali dostos­owanej do konkre­tnego systemu bazoda­nowego.
0.1234

Tekstowe typy danych

CHAR(n)
Reprez­entuje stałą długość łańcucha znakowego o rozmiarze n.
'Hello'
VARCHAR(n)
Reprez­entuje zmienną długość łańcucha znakowego o maksym­alnym rozmiarze n.
'OpenAI'
TEXT
Reprez­entuje łańcuch znakowy o zmiennej długości, bez określ­onego maksym­alnego
'Lorem ipsum dolor sit amet...'
NCHAR(n)
Reprez­entuje stałą długość łańcucha znakowego w formacie Unicode o rozmiarze n.
'Привет'
NVARCH­AR(n)
Reprez­entuje zmienną długość łańcucha znakowego w formacie Unicode o maksym­alnym rozmiarze n.
'こんにちは'
CLOB
Reprez­entuje dużą ilość tekstu o zmiennej długości.
Długi łańcuch znakowy zawier­ający wiele paragrafów lub rozległe dane tekstowe.
BLOB
Reprez­entuje duże binarne dane, takie jak obrazy, dźwięk, wideo itp.
Dane binarne reprez­ent­ujące plik graficzny JPEG.
ENUM
Reprez­entuje zestaw wartości teksto­wych, z których można wybrać jedną.
'Male', 'Female', 'Other'
SET
Reprez­entuje zbiór wartości teksto­wych, z których można wybrać więcej niż jedną.
'Red', 'Green', 'Blue'

Data i czas

DATE
Reprez­entuje datę (bez czasu) w formacie 'RRRR-­MM-DD'
'2023-­07-04'
TIME
Reprez­entuje czas (bez daty) w formacie 'HH:MI:SS'
'12:34:56'
DATETIME lub TIMESTAMP:
Reprez­entuje datę i czas w formacie 'RRRR-­MM-DD HH:MI:SS'
'2023-­07-04 12:34:56'
YEAR
Reprez­entuje rok w formacie 'RRRR'
'2023'
INTERVAL
Reprez­entuje pewien przedział czasu, np. ilość dni, godzin, minut itp.
INTERVAL '1 day' (repre­zentuje 1 dzień)
TIME WITH TIME ZONE
Reprez­entuje czas wraz z informacją o strefie czasowej w formacie 'HH:MI:SS +/-HH:MI'
'12:34:56 +03:00' (czas w strefie czasowej GMT+03:00)
TIMESTAMP WITH TIME ZONE
Reprez­entuje datę i czas wraz z informacją o strefie czasowej w formacie 'RRRR-­MM-DD HH:MI:SS +/-HH:MI'
'2023-­07-04 12:34:56 +03:00' (data i czas w strefie czasowej GMT+03:00)

Pozostałe typy danych

BOOLEAN
Reprez­entuje wartość logiczną true lub false
TRUE
BINARY
Reprez­entuje dane binarne o stałej długości
01101001
VARBINARY
Reprez­entuje dane binarne o zmiennej długości
11001100
BIT
Reprez­entuje pojedynczy bit o wartości 0 lub 1
1
UUID
Reprez­entuje unikalny identy­fik­ator, często używany do identy­fikacji rekordów w tabelach
'550e8­400­-e2­9b-­41d­4-a­716­-44­665­544­0000'
XML
Reprez­entuje dane w formacie XML
'<p­ers­on>­<na­me>­Joh­n</­nam­e><­age­>30­</a­ge>­</p­ers­on>'
JSON
Reprez­entuje dane w formacie JSON (JavaS­cript Object Notation)
'{"n­ame­": "­Joh­n", "­age­": 30}'
GEOMETRY
Reprez­entuje dane geometrii przest­rze­nnej, takie jak punkty, linie, poligony itp.
POINT(1 2)
ARRAY
Reprez­entuje tablicę wartości jednego typu danych
[1, 2, 3, 4]

Count

COUNT(*)
Zlicza wszystkie wiersze w wyniku zapytania, niezal­eżnie od wartości w poszcz­egó­lnych kolumnach
SELECT COUNT(*) 
FROM Customers;
COUNT(1)
Zlicza wszystkie wiersze w wyniku zapytania, używając stałej wartości
SELECT COUNT(1) 
FROM Customers;
COUNT(­col­umn­_name)
Zlicza liczbę niepustych wartości w określonej kolumnie
SELECT COUNT(­Qua­ntity) 
FROM Orders;
COUNT(­DIS­TINCT column­_name)
Zlicza liczbę unikalnych niepustych wartości w określonej kolumnie
SELECT COUNT(
DISTINCT Custom­erID)
FROM Orders;
COUNT(­exp­res­sion)
Zlicza liczbę niepustych wartości zwracanych przez określone wyrażenie
SELECT COUNT(CASE 
WHEN Quantity > 10
THEN 1 END)
FROM Orders;
COUNT(­DIS­TINCT expres­sion)
Zlicza liczbę unikalnych niepustych wartości zwracanych przez określone wyrażenie.
SELECT COUNT(­DIS­TINCT CONCAT(
FirstName, LastName
))
FROM Customers;
IS NOT NULL
Zliczanie niepustych wartości w kolumnie
SELECT COUNT(*) 
FROM Customers
WHERE City IS NOT NULL;
IS NULL
Zliczanie wartości NULL w kolumnie
SELECT COUNT(*) 
FROM Customers
WHERE City IS NULL;

String functions

CONCAT()
Łączy dwa lub więcej łańcuchów znakowych
SELECT CONCAT­(Fi­rst­Name, ' ', LastName) 
AS FullName
FROM Customers;
LENGTH() / LEN()
Zwraca długość łańcucha znakowego
SELECT LENGTH­(Fi­rst­Name) 
AS NameLength
FROM Customers;
UPPER()
Konwertuje łańcuch znakowy na wielkie litery
SELECT UPPER(­Fir­stName) 
AS UpperName
FROM Customers;
LOWER()
Konwertuje łańcuch znakowy na małe litery
SELECT LOWER(­Las­tName) 
AS LowerName
FROM Customers;
SUBSTR­ING()
Wyodrębnia podłańcuch znakowy z danego łańcucha na podstawie określ­onego indeksu i długości
SELECT SUBSTR­ING­(De­scr­iption, 1, 10) 
AS Substr­ingDesc
FROM Products;
REPLACE()
Zamienia wszystkie wystąp­ienia określ­onego podłań­cucha na inny podłańcuch w łańcuchu
SELECT REPLAC­E(D­esc­rip­tion, 'old', 'new') 
AS Update­dDesc
FROM Products;
TRIM() / LTRIM() / RTRIM()
Usuwa początkowe i końcowe białe znaki z łańcucha
SELECT TRIM(F­irs­tName) 
AS Trimme­dName
FROM Customers;
LEFT()
Zwraca określoną liczbę znaków z lewej strony łańcucha
SELECT LEFT(F­irs­tName, 3) 
AS LeftChars
FROM Customers;
RIGHT()
Zwraca określoną liczbę znaków z prawej strony łańcucha
SELECT RIGHT(­Las­tName, 2) 
AS RightChars
FROM Customers;
SPLIT_­PAR­T(s­tring, delimiter, position)
Dzieli podany ciąg znaków na części na podstawie określ­onego separatora i zwraca część o określonej pozycji
SELECT SPLIT_­PAR­T('­Joh­n,D­oe,42', ',', 2); -- 'Doe'
SUBSTR­ING­(string FROM start [FOR length])
Zwraca podciąg znaków z określ­onego ciągu na podstawie podanego począt­kowego indeksu i, opcjon­alnie, długości.
SELECT SUBSTR­ING­('H­ello, World', 1, 5); -- 'Hello'
INITCA­P(s­tring)
Zamienia pierwszą literę każdego wyrazu w ciągu na wielką literę, a pozostałe litery na małe litery.
SELECT INITCA­P('­hello world'); --'Hello World'
REVERS­E(s­tring)
Odwraca kolejność znaków w podanym ciągu.
SELECT REVERS­E('­Hel­lo'); -- 'olleH'

Number funcktions

ABS()
Zwraca wartość bezwzg­lędną liczby
SELECT ABS(-10) 
AS Absolu­teV­alue;
ROUND()
Zaokrągla liczbę do określonej liczby miejsc po przecinku
SELECT ROUND(­3.1­4159, 2) 
AS Rounde­dNu­mber;
CEILING()
Zwraca najmni­ejszą liczbę całkowitą większą lub równą danej liczbie
SELECT CEILIN­G(4.25) 
AS Ceilin­gNu­mber;
FLOOR()
Zwraca największą liczbę całkowitą mniejszą lub równą danej liczbie
SELECT FLOOR(­4.75) 
AS FloorN­umber;
SQRT()
Zwraca pierwi­astek kwadratowy z liczby
SELECT SQRT(25) 
AS Square­Root;
POWER()
Podnosi daną liczbę do określonej potęgi
SELECT POWER(2, 3) 
AS PowerR­esult;
MOD()
Zwraca resztę z dzielenia jednej liczby przez drugą
SELECT MOD(10, 3) 
AS Modulo­Result;
RAND()
Zwraca losową liczbę z zakresu od 0 do 1
SELECT RAND() 
AS Random­Number;
SIGN()
Zwraca znak liczby (-1 dla liczby ujemnej, 0 dla zera, 1 dla liczby dodatniej)
SELECT SIGN(-15) 
AS SignNu­mber;
RANDOM()
Zwraca losową liczbę z określ­onego zakresu
SELECT RANDOM() 
AS Random­Number;
PI()
Zwraca wartość liczby π (pi)
SELECT PI() AS PiValue;
LOG()
Oblicza logarytm o podstawie 10 z danej liczby
SELECT LOG(100) 
AS Logarithm;
LN()
Oblicza logarytm naturalny (o podstawie e) z danej liczby
SELECT LN(2.7­1828) 
AS Natura­lLo­gar­ithm;
EXP()
Oblicza wartość wykład­niczą liczby (e) podnie­sionej do danej potęgi
SELECT EXP(1) 
AS Expone­nti­alV­alue;
GREATEST()
Zwraca największą wartość spośród podanych argumentów
SELECT GREATE­ST(5, 8, 2) 
AS MaxValue;
LEAST()
Zwraca najmni­ejszą wartość spośród podanych argumentów
SELECT LEAST(5, 8, 2) 
AS MinValue;

Date functions

CURREN­T_D­ATE()
Zwraca aktualną datę
SELECT CURREN­T_D­ATE() 
AS Curren­tDate;
CURREN­T_T­IME()
Zwraca aktualny czas
SELECT CURREN­T_T­IME() 
AS Curren­tTime;
CURREN­T_T­IME­STAMP()
Zwraca aktualną datę i czas
SELECT CURREN­T_T­IME­STAMP() 
AS Curren­tDa­teTime;
DATE()
Zwraca tylko datę z wartości daty i czasu
SELECT DATE('­202­3-07-04 10:30:00') 
AS DateOnly;
EXTRACT()
Wyodrębnia określony komponent z daty i czasu, takie jak rok, miesiąc, dzień, godzina itp.
SELECT EXTRAC­T(YEAR FROM '2023-­07-04') 
AS Extrac­ted­Year;
DATEADD()
Dodaje określoną wartość do daty
SELECT DATEAD­D(DAY, 7, '2023-­07-04') 
AS AddedDate;
DATEDIFF()
Oblicza różnicę między dwiema datami w określonej jednostce (np. dni, miesiące, lata)
SELECT DATEDI­FF(DAY, '2023-­07-01', '2023-­07-10') 
AS DateDi­ffe­rence;
DATE_F­ORMAT()
Formatuje datę według określ­onego formatu
SELECT DATE_F­ORM­AT(­'20­23-­07-04', '%Y-%m­-%d') 
AS Format­ted­Date;
DATE_P­ART()
Zwraca wartość określonej części daty i czasu, takiej jak rok, miesiąc, dzień, godzina itp.
SELECT DATE_P­ART­('y­ear', '2023-­07-04') 
AS Year;
DATE_T­RUNC()
Skraca datę do określonej jednostki, np. do miesiąca, roku itp.
SELECT DATE_T­RUN­C('­month', '2023-­07-04') 
AS Trunca­ted­Date;
NOW()
Zwraca aktualną datę i czas
SELECT NOW() 
AS Curren­tDa­teTime;
SYSDATE
Zwraca aktualną datę i czas
SELECT SYSDATE 
AS Curren­tDa­teTime;
HOW TIMEZONE
Zwraca bieżącą strefę czasową ustawioną w bazie danych
SHOW TIMEZONE;
TIME
Typ danych TIME reprez­entuje wartość czasu bez daty
SELECT TIME '10:30:45' 
AS TimeValue;

date_part( 'unit', date ) - unit

day
Day of the month (1 to 31)
decade
Year divided by 10
dow
Day of the week (0=Sunday, 1=Monday, 2=Tuesday, ... 6=Satu­rday)
doy
Day of the year (1=first day of year, 365/36­6=last day of the year, depending if it is a leap year)
epoch
Number of seconds since '1970-­01-01 00:00:00 UTC', if date value. Number of seconds in an interval, if interval value
hour
Hour (0 to 23)
isodow
Day of the week (1=Monday, 2=Tuesday, 3=Wedn­esday, ... 7=Sunday)
isoyear
ISO 8601 year value (where the year begins on the Monday of the week that contains January 4th)
minute
Minute (0 to 59)
month
Number for the month (1 to 12), if date value. Number of months (0 to 11), if interval value
quarter
Quarter (1 to 4)
second
Seconds (and fractional seconds)
timezone
ime zone offset from UTC, expressed in seconds
timezo­ne_hour
Hour portion of the time zone offset from UTC
timezo­ne_­minute
Minute portion of the time zone offset from UTC
week
Number of the week of the year based on ISO 8601 (where the year begins on the Monday of the week that contains January 4th)
year
Year as 4-digits

null functions

IS NULL
Sprawdza, czy określona wartość jest NULL-em
SELECT * 
FROM tabela
WHERE kolumna IS NULL;
IS NOT NULL
Sprawdza, czy określona wartość nie jest NULL-em
SELECT * 
FROM tabela
WHERE kolumna IS NOT NULL;
COALESCE()
Zwraca pierwszą nie-NU­LL-ową wartość z listy wartości
SELECT COALES­CE(­kol­umna1, 
kolumna2,
kolumna3)
AS NonNul­lValue
FROM tabela;
NULLIF()
Zwraca NULL, jeśli dwa wyrażenia są równe, w przeciwnym razie zwraca pierwsze wyrażenie
SELECT NULLIF­(ko­lumna1, 0) 
AS Result
FROM tabela;
NVL()
Zwraca drugie wyrażenie, jeśli pierwsze jest NULL-em
SELECT NVL(ko­lumna1, 
'Brak wartości')
AS Result
FROM tabela;
IFNULL()
Zwraca drugie wyrażenie, jeśli pierwsze jest NULL-em
SELECT IFNULL­(ko­lumna1, 
'Brak wartości')
AS Result
FROM tabela;

Funkcje agregujące

COUNT()
Zlicza liczbę wierszy lub wartości w danej kolumnie.
SELECT COUNT(*) 
AS TotalRows
FROM tabela;
SUM()
Oblicza sumę wartości w danej kolumnie numery­cznej.
SELECT SUM(ko­lumna) 
AS TotalSum
FROM tabela;
AVG()
Oblicza średnią wartość w danej kolumnie numery­cznej.
SELECT AVG(ko­lumna) 
AS Averag­eValue
FROM tabela;
MIN()
Zwraca najmni­ejszą wartość w danej kolumnie.
SELECT MIN(ko­lumna) 
AS MinValue
FROM tabela;
MAX()
Zwraca największą wartość w danej kolumnie.
SELECT MAX(ko­lumna) 
AS MaxValue
FROM tabela;
GROUP_­CONCAT (MySQL, MariaDB)
Konkat­enacja wartości napisowych z grupy w jedną wartość napisową, rozdzi­eloną separa­torem.
SELECT GROUP_­CON­CAT­(na­zwa­_ko­lumny 
SEPARATOR ', ')
AS Concat­ena­ted­Values
FROM tabela
GROUP BY kolumna;
LISTAGG (Oracle)
Konkat­enacja wartości napisowych z grupy w jedną wartość napisową, rozdzi­eloną separa­torem.
SELECT LISTAG­G(n­azw­a_k­olumny, 
', ')
WITHIN GROUP
(ORDER BY kolumna)
AS Concat­ena­ted­Values
FROM tabela;
GROUP BY
Grupuje wyniki zapytania według wartości określ­onych kolumn.
SELECT kolumna, 
COUNT(*)
FROM tabela GROUP BY kolumna;
GROUP BY ROLLUP
pozwala na genero­wanie zestawu wyników hierar­chi­cznych w oparciu o różne poziomy podsum­owania, generuje wyniki dla wszystkich kombinacji wartości w kolumnach podsum­owania, tworząc hierarchię podsumowań
SELECT kolumna1, 
kolumna2,
SUM(wa­rtosc) AS Suma
FROM tabela
GROUP BY ROLLUP­(ko­lumna1, kolumna2);
GROUP BY CUBE
generuje wszystkie możliwe kombinacje wartości w kolumnach podsum­owania, tworząc tzw. kostkę (cube)
SELECT kolumna1, 
kolumna2,
SUM(wa­rtosc) AS Suma
FROM tabela
GROUP BY CUBE(k­olu­mna1, kolumna2);
HAVING
służy do filtro­wania wyników zapytania po grupow­aniu, na podstawie warunków logicznych
SELECT kolumna, 
SUM(wa­rtosc) AS Suma
FROM tabela
GROUP BY kolumna
HAVING SUM(wa­rtosc) > 100

GROUP BY ROLLUP vs GROUP BY CUBE

Przeds­tawmy porównanie klauzul GROUP BY ROLLUP i CUBE na podstawie wyników zapytania dla uprosz­czonej tabeli zawier­ającej dane o sprzedaży produktów w różnych regionach:

Tabela "­Sal­es":
+-----­---­-+-­---­---­---­--+­---­---­----+
| Product | Region | Quantity |
+-----­---­-+-­---­---­---­--+­---­---­----+
| A | North | 10 |
| A | South | 5 |
| B | North | 8 |
| B | South | 12 |
+-----­---­-+-­---­---­---­--+­---­---­----+

Group by ROLLUP:
SELECT Product, Region, SUM(Qu­antity) AS TotalQ­uantity FROM Sales GROUP BY
ROLLUP­(Pr­oduct, Region);

Wyniki zapytania:
+-----­---­-+-­---­---­---­--+­---­---­---­------+
| Product | Region | TotalQ­uantity |
+-----­---­-+-­---­---­---­--+­---­---­---­------+
| A | North | 10 |
| A | South | 5 |
| A | NULL | 15 |
| B | North | 8 |
| B | South | 12 |
| B | NULL | 20 |
| NULL | NULL | 35 |
+-----­---­-+-­---­---­---­--+­---­---­---­------+
Klauzula GROUP BY ROLLUP generuje zestaw wyników z hierarchią podsum­owań, w którym uwzględnia podsum­owanie dla poszcz­egó­lnych wartości w kolumnach Product i Region oraz ogólne podsum­owanie dla każdej kolumny i całkowite podsum­owanie.
Group by CUBE:
SELECT Product, Region, SUM(Qu­antity) AS TotalQ­uantity FROM Sales GROUP BY
CUBE(P­roduct, Region);

Wyniki zapytania:
+-----­---­-+-­---­---­---­--+­---­---­---­------+
| Product | Region | TotalQ­uantity |
+-----­---­-+-­---­---­---­--+­---­---­---­------+
| A | North | 10 |
| A | South | 5 |
| A | NULL | 15 |
| B | North | 8 |
| B | South | 12 |
| B | NULL | 20 |
| NULL | North | 18 |
| NULL | South | 17 |
| NULL | NULL | 35 |
+-----­---­-+-­---­---­---­--+­---­---­---­------+
Klauzula GROUP BY CUBE generuje zestaw wyników, w którym uwzględnia wszystkie możliwe kombinacje wartości w kolumnach Product i Region, włączając podsum­owania dla poszcz­egó­lnych kolumn oraz całkowite podsum­owanie.

Podsum­owując:

GROUP BY ROLLUP generuje zestaw wyników z hierarchią podsum­owań, w którym uwzględnia podsum­owania dla poszcz­egó­lnych kolumn i ich kombin­acji.
GROUP BY CUBE generuje zestaw wyników, który zawiera wszystkie możliwe kombinacje podsumowań dla kolumn, włączając podsum­owania dla poszcz­egó­lnych kolumn.
Warto zauważyć, że w obu przypa­dkach wyniki zawierają dodatkowe wiersze i kolumny, które reprez­entują ogólne podsum­owania

Podzap­ytania (subquery)

Podzap­ytanie (ang. subquery) w SQL to zapytanie umiesz­czone wewnątrz innego zapytania. Może być używane w różnych częściach zapytania, takich jak klauzula SELECT, FROM, WHERE, HAVING lub JOIN, w celu uzyskania dodatk­owych informacji lub filtro­wania danych.

Oto kilka ważnych informacji na temat podzap­ytań:

Cel podzap­ytań: Podzap­ytania służą do uzyskania danych z innej tabeli lub wyników innych zapytań wewnątrz głównego zapytania. Mogą dostarczać dodatkowe inform­acje, filtrować wyniki, dokonywać obliczeń lub dostarczać wyniki dla innych części zapytania.

Składnia: Podzap­ytania są umiesz­czane wewnątrz nawiasów okrągłych lub klamrowych i są traktowane jako oddzielne zapytania. Mogą być umiesz­czone w różnych częściach zapytania, w zależności od potrzeb.

Przykład:
SELECT column1

FROM table1

WHERE column2 IN (SELECT column3 FROM table2);


Związki z innymi zapyta­niami: Podzap­ytania mogą być łączone z innymi zapyta­niami przy użyciu operatorów takich jak IN, EXISTS, ANY, ALL, czy nawet z innymi podzap­yta­niami, w celu tworzenia bardziej zaawan­sow­anych zapytań.

Przykład:
SELECT column1

FROM table1

WHERE column2 IN (SELECT column3 FROM table2 WHERE column4 > 100);


Wydajność: Podzap­ytania mogą mieć wpływ na wydajność zapytań, zwłaszcza gdy są używane wewnątrz klauzuli WHERE lub HAVING. Ważne jest optyma­liz­owanie zapytań zawier­ających podzap­ytania, aby uniknąć zbędnych obliczeń i nadmie­rnego przetw­arzania danych.
Podzap­ytania są potężnym narzędziem w SQL, pozwal­ającym na bardziej zaawan­sowane manipu­lowanie danymi i tworzenie bardziej precyz­yjnych zapytań. Ich zastos­owanie zależy od konkre­tnego przypadku i wymagań zapytania, dlatego warto zapoznać się z nimi i zrozumieć ich składnię i możliw­ości.

Podzap­ytania CTE

Podzap­ytania CTE (Common Table Expres­sions) to narzędzie w SQL, które umożliwia tworzenie tymcza­sowych, nazwanych zestawów wyników, które można następnie wykorz­ystać w głównym zapytaniu. CTE są szczeg­ólnie przydatne w przypadku bardziej skompl­iko­wanych zapytań, gdzie wymagane jest wielok­rotne użycie tego samego podzap­ytania.

Składnia CTE wygląda następ­ująco:

WITH nazwa_cte (kolumna1, kolumna2, ...)

AS (

    SELECT kolumna1, kolumna2, ...



    FROM tabela

    WHERE warunek

)


Przykład:

WITH sales_cte (produ­ct_id, total_­sales)

AS (

    SELECT produc­t_id, SUM(qu­antity * price) AS total_­sales

    FROM sales

    GROUP BY product_id

)


SELECT produc­t_id, total_­sales

FROM sales_cte

WHERE total_­sales > 1000;


W tym przykł­adzie tworzymy CTE o nazwie "­sal­es_­cte­", która zawiera wyniki sumy sprzedaży dla każdego produktu. Następnie w głównym zapytaniu wybieramy dane z CTE, gdzie wartość sprzedaży jest większa niż 1000.

WITH cte1 AS (

    SELECT column1, column2

    FROM table1

    WHERE condition1

),

cte2 AS (

    SELECT column3, column4

    FROM table2

    WHERE condition2

)

SELECT cte1.c­olumn1, cte1.c­olumn2, cte2.c­olumn3, cte2.c­olumn4

FROM cte1

JOIN cte2 ON cte1.c­olumn1 = cte2.c­olumn3;


W powyższym przykł­adzie defini­ujemy dwie CTE: "­cte­1" i "­cte­2". CTE "­cte­1" wybiera kolumny "­col­umn­1" i "­col­umn­2" z "­tab­le1­" spełni­ające określony warunek. CTE "­cte­2" wybiera kolumny "­col­umn­3" i "­col­umn­4" z "­tab­le2­" spełni­ające inny warunek. Następnie wykonujemy złączenie (JOIN) między wynikami obu CTE, używając kolumny "­col­umn­1" z "­cte­1" i kolumny "­col­umn­3" z "­cte­2".

Podzap­ytania CTE mogą znacznie ułatwić czytelność i zarząd­zanie bardziej skompl­iko­wanymi zapyta­niami, pozwalając na ich modula­ryzację i ponowne wykorz­yst­anie.

Klauzula WITH RECURSIVE w języku SQL umożliwia tworzenie rekure­ncy­jnych zapytań, które mogą być używane do przetw­arzania danych hierar­chi­cznych lub grafowych. Pozwala na iteracyjne wykony­wanie zapytań z użyciem wyników poprze­dnich iteracji jako dane wejściowe dla kolejnych iteracji.

Składnia ogólna WITH RECURSIVE wygląda następ­ująco:

WITH RECURSIVE nazwa (kolumny) AS (

   Zapyta­nie­_ni­e_r­eku­ren­cyjne

   UNION [ALL]

   Zapyta­nie­_re­kur­encyjne

)

Zapyta­nie­_główne


Przykład:
Załóżmy, że mamy tabelę "­emp­loy­ees­" zawier­ającą dane pracow­ników, w której istnieje hierarchia kierow­nicza. Chcemy wykonać rekure­ncyjne zapytanie, które zwróci wszystkich pracow­ników, którzy podlegają danemu kierow­nikowi (w dowolnym stopniu hierar­chii).

WITH RECURSIVE employ­ee_­hie­rarchy (emplo­yee_id, full_name, manage­r_id) AS (

   SELECT employ­ee_id, full_name, manager_id

   FROM employees

   WHERE employ­ee_id = 1 -- Przykł­adowy identy­fikator kierownika

   UNION ALL

   SELECT e.empl­oye­e_id, e.full­_name, e.mana­ger_id

   FROM employees e

   JOIN employ­ee_­hie­rarchy eh ON e.mana­ger_id = eh.emp­loy­ee_id

)

SELECT *

FROM employ­ee_­hie­rarchy;


W tym przykł­adzie używamy WITH RECURSIVE do stworzenia rekure­ncy­jnego zapytania o nazwie "­emp­loy­ee_­hie­rar­chy­". W począt­kowym zapytaniu wybieramy dane kierownika o określonym identy­fik­atorze. Następnie używamy operatora UNION ALL i dołączamy zapytanie rekure­ncyjne, które odwołuje się do "­emp­loy­ee_­hie­rar­chy­" i łączy pracow­ników, których identy­fikator kierownika jest równy identy­fik­atorowi z poprze­dniej iteracji.

W rezultacie zapytanie zwróci wszystkich pracow­ników, którzy są podlegli danemu kierow­nikowi, bez względu na poziom hierar­chii.

Losowa próbka rekordów

Aby pobrać losową próbkę rekordów z tabeli, można skorzystać z różnych technik, w zależności od używanego systemu bazoda­nowego. Oto kilka przykł­adów:

- Przykład dla systemu Postgr­eSQL:
SELECT *

FROM table_name

ORDER BY RANDOM()

LIMIT 10;


W powyższym przykł­adzie używamy funkcji RANDOM() w instrukcji ORDER BY, aby przemi­eszać rekordy w tabeli, a następnie ograni­czamy wyniki do 10 przy użyciu LIMIT, co daje nam losową próbkę 10 rekordów.

Przykład dla systemu MySQL:
SELECT *

FROM table_name

ORDER BY RAND()

LIMIT 10;

W przypadku MySQL używamy funkcji RAND() w instrukcji ORDER BY do przemi­eszania rekordów, a następnie ograni­czamy wyniki do 10 przy użyciu LIMIT.

Przykład dla systemu Microsoft SQL Server:
SELECT TOP 10 *

FROM table_name

ORDER BY NEWID();


W przypadku SQL Servera możemy użyć funkcji NEWID() w instrukcji ORDER BY, która generuje unikalne identy­fik­atory GUID, co daje nam losowe sortowanie rekordów. Następnie używamy TOP do ograni­czenia wyników do 10 rekordów.

- WHERE RANDOM() < 0.01: Ta metoda wykorz­ystuje funkcję RANDOM() w warunku WHERE, aby wybrać tylko te rekordy, których wartość losowa jest mniejsza niż 0.01. Można dostosować wartość 0.01, aby uzyskać różne wielkości próbek.
Przykład:
SELECT *

FROM table_name

WHERE RANDOM() < 0.01;


- TABLES­AMPLE SYSTEM(1): Ta metoda wykorz­ystuje klauzulę TABLES­AMPLE w zapytaniu, która umożliwia losowe pobranie próbki rekordów na podstawie procen­towego udziału w tabeli.
Przykład:
SELECT *

FROM table_name TABLES­AMPLE SYSTEM(1);


W powyższym przykł­adzie SYSTEM(1) oznacza, że zostanie pobrana próbka o wielkości około 1% całej tabeli. Można dostosować wartość procen­tową, aby uzyskać różne rozmiary próbek.

PIVOT

Pivot w SQL to operacja, która umożliwia transf­ormację danych w pionowy format (kolumny w wiersze) na poziomy format (wiersze w kolumny). Jest to przydatne, gdy chcemy dokonać agregacji danych wokół określonej kolumny lub zestawić dane w bardziej zrozumiały sposób.

Operacja Pivot wymaga zdefin­iow­ania, które kolumny zostaną transp­onowane na wartości kolumn w nowej tabeli wynikowej. Oto przykł­adowe zapytanie wykorz­yst­ujące operację Pivot:

SELECT * 

FROM (

  SELECT category, product, quantity 

  FROM sales 

) AS src 

 PIVOT (

  SUM(qu­antity) 

 FOR product IN ([Prod­uctA], [Produ­ctB], [Produ­ctC]) 

) AS pivot_­table; 


W powyższym przykł­adzie mamy tabelę "­sal­es" zawier­ającą kolumny "­cat­ego­ry", "­pro­duc­t" i "­qua­nti­ty". Chcemy dokonać transp­ozycji wartości kolumny "­pro­duc­t" na nowe kolumny w tabeli wynikowej. W zapytaniu defini­ujemy listę produktów, dla których chcemy dokonać transp­ozycji ([Prod­uctA], [Produ­ctB], [Produ­ctC]). Następnie używamy funkcji agregu­jącej (w tym przypadku SUM) do obliczenia wartości dla każdego produktu w ramach danej kategorii.

Takie zapytanie Pivot zwróci tabelę wynikową, w której poszcz­ególne produkty zostaną przeds­tawione jako osobne kolumny, a wartości będą agregowane dla każdej kategorii.

category | ProductA | ProductB | ProductC
------­---­---­---­---­---­---­---­---­---­---­-------
CategoryA | 10 | 5 | 3
CategoryB | 8 | 2 | 6

Warto zauważyć, że składnia zapytania Pivot może się różnić w zależności od konkre­tnego systemu bazoda­nowego. Przykład powyżej jest ogólnym przykł­adem, ale warto sprawdzić dokume­ntację systemu bazoda­nowego, którego używasz, aby poznać szczegóły i składnię dotyczącą operacji Pivot w danym systemie.

a)
SELECT * 

FROM crosst­ab(‘SQL tworzący tabelę w postaci tekstu’)

AS nazwa_­tab­eli­(de­finicja kolumn wynikowych tabeli);

b)
SELECT *

FROM crosst­ab(­'select jezyk:­:text, stan_w­nio­sku­::text, count(­*):­:nu­meric

FROM wnioski group by 1, 2')

AS final_­res­ult­(“j­ezyk” text, "­odr­zucony prawni­e" numeric, "­odr­zucony po analiz­ie" numeric,
"­zaa­kce­ptowany przez operat­ora­" numeric, "­wyp­lac­ony­" numeric, "­zam­kni­ety­" numeric, "­akcja
sadowa­" numeric, "­now­y" numeric, "­analiza zaakce­pto­wan­a" numeric, "­prz­egrany w sadzie­"
numeric, "­wyslany do operat­ora­" numeric, "­odr­zucony przez operat­ora­" numeric, "­wygrany w
sadzie­" numeric);

Indeks­owanie

Indeksy są strukturami danych w bazach danych, które pomagają przyspieszyć wyszukiwanie i sortowanie danych. Są to specjalne obiekty, które są tworzone na jednym lub wielu kolumnach tabeli i umożliwiają szybkie odnajdywanie odpowiednich rekordów na podstawie wartości w tych kolumnach. Oto kilka podstawowych informacji o indeksach:

Rodzaje indeksów:
Indeksy jednokolumnowe: tworzone na pojedynczej kolumnie tabeli.
Indeksy wielokolumnowe: tworzone na kilku kolumnach tabeli.
Unikalne indeksy: zapewniają, że wartości w indeksowanych kolumnach są unikalne.
Indeksy skupione (clustered): określają fizyczną organizację danych w tabeli na podstawie wartości indeksowanych kolumn.
Indeksy niestrukture (non-clustered): mają oddzielną strukturę od tabeli i zawierają odnośniki do fizycznych miejsc, gdzie dane są przechowywane.

Korzyści wynikające z indeksowania:
Szybsze wyszukiwanie danych: indeksy umożliwiają bezpośrednie odnalezienie pasujących rekordów, co przyspiesza zapytania wyszukiwania.
Szybsze sortowanie danych: indeksy ułatwiają sortowanie danych według indeksowanych kolumn.
Zmniejszone obciążenie zapytań: efektywne indeksowanie może zmniejszyć obciążenie na serwerze baz danych poprzez skrócenie czasu wykonywania zapytań.
Tworzenie i zarządzanie indeksami:
Indeksy można tworzyć podczas tworzenia tabeli lub po jej utworzeniu.
Tworzenie indeksów powinno być odpowiednio przemyślane, uwzględniając często wykonywane zapytania i typ operacji, które będą wykonywane na danych.
Indeksy należy utrzymywać i aktualizować wraz z danymi w tabelach, aby zapewnić ich skuteczność.

Przykład tworzenia indeksu na jednej kolumnie:
CREATE INDEX idx_customer_name ON Customers (customer_name);
Przykład tworzenia indeksu na wielu kolumnach:
CREATE INDEX idx_customer_location ON Customers (city, state);
Indeksy są ważnym elementem optymalizacji baz danych, które pomagają w poprawie wydajności zapytań i operacji na danych. Ważne jest jednak odpowiednie projektowanie i zarządzanie indeksami, aby uniknąć nadmiernego indeksowania, które może prowadzić do spadku wydajności podczas modyfikacji danych. Indeksy nie są bezpośrednio widoczne po wywołaniu tabeli, ale mają wpływ na wydajność zapytań, szczególnie podczas wyszukiwania, sortowania i łączenia danych. Przykład poniżej ilustruje, jak indeksy mogą przyspieszyć zapytania: Mamy tabelę "Customers" z indeksem na kolumnie "customer_name". Wykonajmy zapytanie wyszukujące klienta o nazwie "John Smith":
SELECT * FROM Customers WHERE customer_name = 'John Smith';
Bez indeksu, silnik bazy danych musiałby przeszukać całą tabelę w poszukiwaniu rekordów spełniających warunek. Jeśli tabela ma dużą liczbę rekordów, zapytanie może być wolne. Z indeksem na kolumnie "customer_name", silnik bazy danych może skorzystać z indeksu, aby bezpośrednio odnaleźć rekordy o nazwie "John Smith", nie musząc przeszukiwać całej tabeli. Wykonanie zapytania będzie znacznie szybsze. Indeksy są tworzone dla optymalizacji zapytań i ukryte są wewnętrznie w silniku bazy danych. Nie są one bezpośrednio widoczne jako kolumny lub dane, ale mają wpływ na wydajność zapytań, a wyniki mogą być widoczne w czasie wykonywania zapytań.

łączenie (konka­ten­acja) stringów

W SQL istnieje kilka sposobów łączenia (konka­ten­acji) stringów. Oto kilka przykł­adów:

- Operator konkat­enacji (+):
Możesz użyć operatora "­+" do połączenia dwóch stringów w jedną wartość. Przykład:
SELECT 'Hello' + ' ' + 'World' AS concat­ena­ted­_st­ring;

Wynik: "­Hello World"

- Funkcja CONCAT():
Funkcja CONCAT() pozwala na łączenie wielu stringów w jeden. Przykład:
SELECT CONCAT­('H­ello', ' ', 'World') AS concat­ena­ted­_st­ring;

Wynik: "­Hello World"

- Operator ||:
W niektórych bazach danych, takich jak Oracle, PostgreSQL czy SQLite, można użyć operatora "­||" do konkat­enacji stringów. Przykład:
SELECT 'Hello' || ' ' || 'World' AS concat­ena­ted­_st­ring;
Wynik: "­Hello World"

- Funkcja CONCAT­_WS():
Funkcja CONCAT­_WS() służy do konkat­enacji stringów z użyciem określ­onego separa­tora. Przykład:
SELECT CONCAT­_WS(', ', 'John', 'Doe', 'New York') AS concat­ena­ted­_st­ring;

Wynik: "­John, Doe, New York"

- Funkcja STUFF() (dla SQL Server):
Funkcja STUFF() w SQL Server umożliwia zamianę fragmentu stringa innym stringiem. Może być używana do łączenia stringów. Przykład:
SELECT STUFF(­'Hello World', 6, 0, ', ') AS concat­ena­ted­_st­ring;

Wynik: "­Hello, World"

Konwersja danych

w zapytaniu SELECT istnieją pewne funkcje konwersji danych, które mogą służyć do przeks­zta­łcenia wartości jednego typu danych na inny typ danych w wynikach zapytania. Oto kilka przykł­adów:

- CAST() lub CONVERT() umożli­wiają konwersję jednego typu danych na inny. Przykład:
SELECT CAST(k­olumna AS nowy_typ) AS nowa_k­olumna

FROM tabela;

lub
SELECT CONVER­T(n­owy­_typ, kolumna) AS nowa_k­olumna

FROM tabela;

Należy zastąpić "­kol­umn­a" nazwą kolumny, którą chcesz przeko­nwe­rtować, a "­now­y_t­yp" docelowym typem danych.

*Convert z unicode
conver­t(name, 'AL32U­TF8', 'WE8MS­WIN­1252')

SELECT CONVER­T(name, 'UTF8', 'AL32U­TF8') FROM nazwa_­tabeli


- funkcje konwersji typów danych:
W zależności od używanej bazy danych, mogą istnieć specyf­iczne funkcje konwersji typów danych, takie jak TO_NUM­BER(), TO_DATE(), TO_CHAR() itp. Możesz użyć tych funkcji w zapytaniu SELECT, aby przeko­nwe­rtować wartości na określony typ danych. Przykład:
SELECT TO_NUM­BER­(ko­lumna) AS nowa_k­olumna

FROM tabela;

W powyższym przykł­adzie używamy funkcji TO_NUM­BER(), aby przeko­nwe­rtować wartość kolumny na typ liczbowy.

-Składnia wyraże­nie­::t­yp_­danych lub wyraże­nie­::t­yp_­dan­ych(n) służy do jawnego rzutowania (explicit cast) wartości wyrażenia na określony typ danych. Przykład:
SELECT kolumn­a::­integer AS nowa_k­olumna

FROM tabela;

W powyższym przykł­adzie używamy ::integer, aby przeko­nwe­rtować wartość kolumny na typ całkow­ito­lic­zbowy (integer).

Warto zauważyć, że ten zapis ::typ_­danych jest specyf­iczny dla niektórych baz danych, takich jak Postgr­eSQL, i nie jest powsze­chnie obsług­iwany we wszystkich bazach danych. Dlatego zawsze warto sprawdzić dokume­ntację konkretnej bazy danych, aby upewnić się, czy ten zapis jest dostępny i poprawnie obsług­iwany w danym systemie bazoda­nowym.

trim

Funkcja TRIM w języku SQL jest używana do usuwania spacji lub innych określ­onych znaków z początku i końca ciągu znaków. Funkcja TRIM może być również rozsze­rzona o specyf­ikację konkre­tnych znaków, które mają być usunięte z ciągu.

Składnia ogólna funkcji TRIM jest następ­ująca:

TRIM([ [ LEADING | TRAILING | BOTH ] [ charac­ter­s_t­o_r­emove ] FROM ] string­_ex­pre­ssion)
Argumenty funkcji TRIM:

- LEADING: Usuwa określone znaki z początku ciągu.
- TRAILING: Usuwa określone znaki z końca ciągu.
- BOTH (domyś­lne): Usuwa określone znaki zarówno z początku, jak i końca ciągu.
- charac­ter­s_t­o_r­emove (opcjo­nalny): Określa konkretne znaki, które mają być usunięte. Może to być ciąg znaków lub kolumna zawier­ająca znaki.
- string­_ex­pre­ssion: Wyrażenie tekstowe, z którego mają być usunięte znaki.

Przykłady:

Usunięcie spacji z początku i końca ciągu:

SELECT TRIM('   Hello World   ');

Wynik: 'Hello World'

Usunięcie określ­onych znaków z początku i końca ciągu:

SELECT TRIM('.,?!' FROM '...Hello, World?­!...');

Wynik: 'Hello, World'

Usunięcie spacji tylko z początku ciągu:

SELECT TRIM(L­EADING ' ' FROM '   Hello World   ');

Wynik: 'Hello World '

Usunięcie spacji tylko z końca ciągu:

SELECT TRIM(T­RAILING ' ' FROM '   Hello World   ');

Wynik: ' Hello World'

Funkcja TRIM jest przydatna do usuwania zbędnych białych znaków z ciągów, takich jak spacje, które mogą wpływać na porówn­ania, grupowanie lub inne operacje na danych teksto­wych.

Warto pamiętać, że dostępność i składnia funkcji TRIM mogą się różnić w zależności od używanej bazy danych. Należy zawsze sprawdzić dokume­ntację konkretnej bazy danych w celu uzyskania dokładnej składni i zachowania funkcji TRIM.

Różnica między EXISTS a IN

Klauzula EXISTS i IN służą do filtro­wania danych w zapytaniu na podstawie wartości w innym podzap­ytaniu lub zbiorze wartości. Oto różnica między nimi:

1. EXISTS:
- Klauzula EXISTS sprawdza, czy podzap­ytanie zwraca jakiek­olwiek wyniki.
- Jeśli podzap­ytanie zwraca przyna­jmniej jeden wiersz, to warunek EXISTS jest spełniony.
- Klauzula EXISTS jest zwykle używana w warunku WHERE, aby sprawdzić, czy istnieją powiązane wiersze w innych tabelach.
- Może być bardziej wydajna niż IN w przypadku dużych zbiorów danych, ponieważ po znalez­ieniu pierwszego pasującego wiersza, dalsze poszuk­iwania są przerwane.

Przykład użycia klauzuli EXISTS:
SELECT column1, column2, ...

FROM table1

WHERE EXISTS (SELECT column1 FROM table2 WHERE condit­ion);


2. IN:
- Klauzula IN porównuje wartość wyrażenia z zestawem wartości dostar­czonych w podzap­ytaniu lub liście wartości.
- Jeśli wartość jest równa jednej z wartości z podzap­ytania lub listy, warunek IN jest spełniony.
- Klauzula IN jest zwykle używana w warunku WHERE, aby sprawdzić, czy wartość znajduje się w określonym zestawie.
- Może być łatwiejsza do zrozum­ienia i zapisu niż EXISTS, ale może być mniej wydajna dla dużych zbiorów danych.

Przykład użycia klauzuli IN:
SELECT column1, column2, ...

FROM table1

WHERE column1 IN (SELECT column1 FROM table2 WHERE condit­ion);


Podsum­owując, klauzula EXISTS sprawdza istnienie przyna­jmniej jednego pasującego wiersza w podzap­ytaniu, podczas gdy klauzula IN porównuje wartość do zestawu wartości z podzap­ytania lub listy. Wybór między nimi zależy od konkre­tnego przypadku i prefer­encji progra­misty.

Różnice między DELETE a TRUNCATE

Różnica między operacjami DELETE i TRUNCATE dotyczy sposobu usuwania danych w bazie danych. Oto główne różnice między nimi:

DELETE:
- DELETE jest operacją DML (Data Manipu­lation Language), która służy do usuwania jednego lub więcej wierszy z tabeli.
- Operacja DELETE jest rejest­rowana w dzienniku transakcji (ang. transa­ction log), co oznacza, że można cofnąć operację DELETE w ramach transa­kcji.
- DELETE można stosować z dodatk­owymi warunkami (WHERE), aby precyz­yjnie określić, które wiersze mają być usunięte.
- DELETE wywołuje wyzwalacze (triggery) zdefin­iowane na tabeli, które mogą wykonywać określone działania przed lub po usunięciu danych.

Przykład użycia DELETE:
DELETE FROM tabela WHERE warunek;


TRUNCATE:
- TRUNCATE jest operacją DDL (Data Definition Language), która służy do usuwania wszystkich wierszy z tabeli.
- Operacja TRUNCATE nie jest rejest­rowana w dzienniku transa­kcji, co oznacza, że nie można cofnąć operacji TRUNCATE w ramach transa­kcji.
- TRUNCATE nie używa warunków (WHERE), ponieważ usuwa wszystkie wiersze z tabeli.
- TRUNCATE nie wywołuje wyzwalaczy (triggers) zdefin­iow­anych na tabeli.

Przykład użycia TRUNCATE:
TRUNCATE TABLE tabela;


Podsum­owując, DELETE jest operacją bardziej precyz­yjną, która umożliwia usuwanie wybranych wierszy z tabeli, rejest­rowanie w dzienniku transakcji i wywoły­wanie wyzwal­aczy. TRUNCATE jest szybszą operacją, która usuwa wszystkie wiersze z tabeli, nie rejestruje się w dzienniku transakcji i nie wywołuje wyzwal­aczy. Wybór między nimi zależy od konkre­tnego przypadku i wymagań dotycz­ących operacji usuwania danych.

Usuwanie duplikatów z tabeli

Aby usunąć duplikaty z tabeli, można skorzystać z kombinacji operacji SELECT DISTINCT i INSERT INTO lub operacji DELETE z użyciem klauzuli EXISTS lub CTE (Common Table Expres­sion). Oto kilka przykł­adów:

Przykład 1: Użycie operacji SELECT DISTINCT i INSERT INTO
CREATE TABLE tabela2 AS

SELECT DISTINCT *

FROM tabela;


W tym przykł­adzie tworzymy nową tabelę tabela2, która zawiera tylko unikalne wiersze z tabeli orygin­alnej.

Przykład 2: Użycie operacji DELETE z klauzulą EXISTS
DELETE FROM tabela a

WHERE EXISTS (

  SELECT 1

  FROM tabela b

  WHERE a.kolumna = b.kolumna

  AND a.id < b.id

);


W tym przykł­adzie usuwamy wiersze, dla których istnieje inny wiersz o tej samej wartości kolumny, ale z niższym identy­fik­atorem (id).

Przykład 3: Użycie operacji DELETE z wykorz­yst­aniem CTE
WITH duplicates AS (

  SELECT kolumna, COUNT(*) AS count

  FROM tabela

  GROUP BY kolumna

  HAVING COUNT(*) > 1

)

DELETE FROM tabela

WHERE (kolumna) IN (

  SELECT kolumna

  FROM duplicates

);


W tym przykł­adzie tworzymy wspólne wyrażenie tabeli (CTE) o nazwie "­dup­lic­ate­s", które identy­fikuje kolumny, które mają więcej niż jedno powtór­zenie. Następnie wykonujemy operację DELETE, usuwając wiersze, które mają wartości kolumny zawarte w wynikach CTE.

Należy pamiętać, że przed wykonaniem operacji usuwania zawsze warto zrobić kopię zapasową danych lub przete­stować zapytanie na kopii testowej bazy danych, aby upewnić się, że operacja usunięcia działa zgodnie z oczeki­waniami i nie spowoduje utraty niepoż­ądanych danych.

Fuzzy Matching

Fuzzy matching, czyli dopaso­wywanie przybl­iżone, może być realiz­owane w języku SQL za pomocą różnych technik. Oto kilka popula­rnych sposobów realizacji fuzzy matching w SQL:

- Operator LIKE z użyciem symbolu %: Operator LIKE w połączeniu z symbolem % umożliwia dopaso­wywanie wzorców z użyciem kawałków tekstu. Symbol % reprez­entuje dowolną liczbę znaków (również zero znaków). Przykład:

SELECT column­_name

FROM table_name

WHERE column­_name LIKE '%fraza%';


W powyższym przykł­adzie, '%fraza%' dopasuje wartości w kolumnie column­_name, które zawierają "­fra­za" gdziek­olwiek wewnątrz ciągu.

- Funkcja SOUNDEX: Funkcja SOUNDEX w niektórych bazach danych (np. MySQL, SQL Server) generuje kod dźwiękowy dla podanego wyrażenia. Działa na podstawie podobi­eństwa dźwięk­owego słów. Może być używana do porówn­ywania słów w celu znalez­ienia podobnych wyników. Przykład:

SELECT column­_name

FROM table_name

WHERE SOUNDE­X(c­olu­mn_­name) = SOUNDE­X('­wyr­aże­nie');


W powyższym przykł­adzie, SOUNDE­X(c­olu­mn_­name) = SOUNDE­X('­wyr­aże­nie') porównuje dźwiękowe kody słów w kolumnie column­_name z dźwiękowym kodem słowa "­wyr­aże­nie­".
Funkcje tekstowe: W niektórych bazach danych istnieją specjalne funkcje tekstowe do przepr­owa­dzania dopaso­wania przybl­iżo­nego, takie jak DIFFERENCE w SQL Server. Te funkcje obliczają podobi­eństwo między dwoma wyraże­niami i zwracają wartość liczbową reprez­ent­ującą stopień dopaso­wania.

- Przykład z użyciem DIFFERENCE w SQL Server:

SELECT column­_name

FROM table_name

WHERE DIFFER­ENC­E(c­olu­mn_­name, 'wyraż­enie') >= 3;


W powyższym przykł­adzie, DIFFER­ENC­E(c­olu­mn_­name, 'wyraż­enie') >= 3 porównuje podobi­eństwo między słowami w kolumnie column­_name a słowem "­wyr­aże­nie­". Wartość 3 lub wyższa wskazuje na wystar­czająco wysokie dopaso­wanie.
Warto pamiętać, że dostępność i składnia funkcji do fuzzy matching mogą się różnić w zależności od używanej bazy danych. Należy sprawdzić dokume­ntację konkretnej bazy danych w celu uzyskania informacji na temat dostępnych funkcji i ich zastos­owania.

Operator NOT

Operator NOT jest używany w języku SQL do negacji logicznej warunku. Może być stosowany zarówno w warunkach logicz­nych, jak i w połączeniu z innymi operat­orami.

Podsta­wowym zastos­owaniem operatora NOT jest odwrócenie wartości logicznej wyrażenia. Jeśli wyrażenie logiczne jest prawdziwe, operator NOT zwróci wartość fałszu, a jeśli wyrażenie logiczne jest fałszywe, operator NOT zwróci wartość prawdy.

Przykład:

SELECT *

FROM tabela

WHERE NOT kolumna = 'wartosc';


W powyższym przykł­adzie, operator NOT jest używany do odwrócenia wyniku porównania wartości w kolumnie kolumna z określoną wartością. Jeśli wartość w kolumnie nie jest równa 'wartosc', warunek zostanie spełniony i wiersz zostanie zwrócony.

Operator NOT może być również używany do negacji warunków logicz­nych, takich jak AND i OR. Na przykład:

SELECT *

FROM tabela

WHERE NOT (warunek1 AND warunek2);


W powyższym przykł­adzie, operator NOT jest używany do negacji całego warunku logicznego (warunek1 AND warunek2). Jeśli warunek ten jest prawdziwy, operator NOT zwróci wartość fałszu, co oznacza, że warunek zostanie spełniony i wiersz zostanie zwrócony.

Operator NOT może być również łączony z innymi operat­orami logicz­nymi, takimi jak LIKE, BETWEEN, IN itp., aby tworzyć bardziej złożone wyrażenia warunkowe.

Warto pamiętać, że składnia i zachowanie operatora NOT mogą się różnić w zależności od konkretnej bazy danych. Należy zawsze sprawdzić dokume­ntację danej bazy danych w celu uzyskania dokładnej składni i zachowania operatora NOT.

IF ELSE

1. Konstr­ukcja
CASE WHEN
:
SELECT

   column­_name,

    CASE

        WHEN condition1 THEN result1

        WHEN condition2 THEN result2

        ELSE result­_de­fault

    END AS result

FROM table_­name;


Przykład:
SELECT

    produc­t_name,

    CASE

        WHEN units_sold > 1000 THEN 'High'

        WHEN units_sold > 500 THEN 'Medium'

        ELSE 'Low'

    END AS sales_­cat­egory

FROM products;


2. Funkcja
IF
:
SELECT

    column­_name,

    IF(con­dition, result­_true, result­_false) AS result

FROM table_­name;


Przykład:
SELECT

    produc­t_name,

    IF(uni­ts_sold > 1000, 'High', 'Low') AS sales_­cat­egory

FROM products;


3. Konstr­ukcja
IIF
(dostępna w niektórych systemach baz danych):
SELECT

    column­_name,

    IIF(co­ndi­tion, result­_true, result­_false) AS result

FROM table_­name;


Przykład:
SELECT

    produc­t_name,

    IIF(un­its­_sold > 1000, 'High', 'Low') AS sales_­cat­egory

FROM products;


Wszystkie te opcje pozwalają na defini­owanie warunków i przypi­sywanie wartości w zależności od spełnienia tych warunków. Wybór odpowi­edniej opcji zależy od systemu bazoda­nowego, który używasz, ponieważ nie wszystkie bazy danych obsługują wszystkie te konstr­ukcje. Należy sprawdzić dokume­ntację konkre­tnego systemu bazoda­nowego, aby dowiedzieć się, które opcje są dostępne i jak je prawidłowo używać.

co to jest Constr­aint?

Constraint (ogran­icz­enie) w kontekście baz danych odnosi się do reguł i warunków, które są narzucane na dane w tabelach w celu zapewn­ienia integr­alności danych i utrzymania spójności bazy danych. Ograni­czenia określają pewne reguły, którym muszą odpowiadać dane wprowa­dzane do tabeli. Główne typy ograniczeń w bazach danych to:

1. Primary Key (Klucz podsta­wowy): Ograni­czenie primary key zapewnia unikalność wartości w kolumnie lub grupie kolumn w tabeli. Pozwala to na jednoz­naczne identy­fik­owanie każdego wiersza w tabeli.
Przykład:
CREATE TABLE customers (

    custom­er_id INT PRIMARY KEY,

    custom­er_name VARCHA­R(50)

);


2. Foreign Key (Klucz obcy): Ograni­czenie foreign key definiuje relacje między tabelami. Określa, że wartości w kolumnie lub grupie kolumn w jednej tabeli muszą odpowiadać wartościom klucza podsta­wowego w innej tabeli.
Przykład:
CREATE TABLE orders (

    order_id INT PRIMARY KEY,

    custom­er_id INT,

    order_date DATE,

    FOREIGN KEY (custo­mer_id) REFERENCES customers (custo­mer_id)

);


3. Unique Key (Klucz unikalny): Ograni­czenie unique key zapewnia unikalność wartości w kolumnie lub grupie kolumn, ale pozwala na obecność wartości null.
Przykład:
CREATE TABLE employees (

    employ­ee_id INT PRIMARY KEY,

    employ­ee_name VARCHA­R(50),

    email VARCHA­R(50) UNIQUE

);


4. Check Constraint (Ogran­iczenie sprawd­zaj­ące): Ograni­czenie check definiuje warunek, który musi zostać spełniony przez wartości w kolumnie.
Przykład:
CREATE TABLE products (

    product_id INT PRIMARY KEY,

    produc­t_name VARCHA­R(50),

    quantity INT,

    price DECIMA­L(10, 2),

    CHECK (quantity >= 0 AND price > 0)

);


Ograni­czenia są ważnym elementem projek­towania bazy danych i pomagają utrzymać spójność i integr­alność danych. Zapewniają również ochronę przed wprowa­dzaniem niepra­wid­łowych lub niepoż­ądanych danych do tabel.
 

Comments

No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          Web Programming Cheat Sheet
          SQL Server Cheat Sheet
          SQL Cheat Sheet