Język
SQL stanowi najbardziej popularny mechanizm definiowania poleceń i zapytań
i modyfikacji w relacyjnych systemach baz danych.
Słowo SQL jest skrótem angielskim od Structure Query Language, tj. języka
zapytań strukturalnych.
Podstawowy rdzeń języka SQL jest implementacją algebry relacji, ale zawarte są
w nim również elementy daleko odbiegające od tego,
co można odnaleźć w algebrze relacji, np. możliwości agregowania
danych (np. sumy i podliczanie), a także możliwość modyfikowania
bazy danych.
Istnieje
wiele różnych dialektów języka SQL.
Najważniejsze z nich są dwa standardy: ANSI (American National Standard
Institute) SQL oraz zmodyfikowany w 1992 roku standard SQL-92, czyli SQL2.
W trakcie ustaleń znajduje się kolejna rozszerzona wersja tych standardów
o nazwie SQL3, która poza elementami SQL2 zawiera wiele nowości, takich
jak
rekurencja, wyzwalacze i obiekty. A poza tym istnieją wersje języka
SQL implementowane przez producentów oprogramowania systemowego baz danych.
Są one zgodne ze standardem ANSI, a w wielu miejscach również ze
standardem SQL2, ale każde z nich zawiera wiele własnych koncepcji
modyfikujących
ten drugi standard, a czasami te koncepcje są zgodne z bieżącym
stanem znajdującego się na etapie inkubacji standardu SQL3.
Język SQL
jest niezależnym językiem zapytań, który dostarcza możliwości interaktywnego
zadawania zapytań do bazy danych
oraz określania żądań modyfikowania danych. SQL jest językiem wysokiego poziomu
do manipulowania danymi
o niewielkiej liczbie instrukcji a o dużych możliwościach. Dzięki
temu można w bardzo zwarty sposób programować systemy użytkowe,
bazy danych lub wykorzystywać język SQL w trybie interakcyjnym.
Najprostsza
postać zapytania w języku SQL służy do wybierania krotek pewnej relacji,
które spełniają określone w zapytaniu warunek.
Taki typ zapytania stanowi odpowiednik operatora selekcji w algebrze
relacji.
Takie najprostsze zapytanie jak zresztą prawie wszystkie zapytania w tym
języku, konstruuje się za pomocą trzech charakterystycznych
dla SQL słów kluczowych: SELECT, FROM i WHERE.
Instrukcją wykorzystywaną do wyprowadzania informacji umieszczonych w tablicach języka SQL jest instrukcja SELECT o składni:
[INTO <klauzula>]
FROM <klauzula>
[WHERE <klauzula>]
[GROUP BY <klauzula>]
[HAVING <klauzula>]
[UNION <instrukcja SELECT>...]
[ORDER BY <klauzula>/FOR UPDATE OF <klauzula>]
[SAVE TO TEMP <klauzula>];
Najprostszym wyprowadzeniem wyspecyfikowanych kolumn pojedynczej tablicy jest postać:
SELECT materiał, ilość
FROM Ilość;
Z tablicy Ilość zostaną wyprowadzone zawartości kolumn: materiał i ilość.
Jeżeli mają być
wyprowadzane wszystkie kolumny tablicy, wówczas w instrukcji SELECT należy podać znać gwiazdki
(podawane w kolejności występowania w tablicy). Dla wyprowadzania
tylko różnych wierszy z tablicy
po instrukcji SELECT (lecz przed kolumnami) należy
zastosować opcję DISTINCT.
SELECT DISTINCT *
FROM Numer;
Zostaną wyprowadzone wszystkie różne wiersze tablicy Numer
Podstawowa postać instrukcji SELECT
SELECT <kolumny>
FROM <tablice>
WHERE <warunek>;
SELECT materiał, ilość
FROM Ilość
WHERE materiał = „szyby”;
Po wykonaniu takiego
rozkazu z tablicy Ilość zostaną wyselekcjonowane tylko te wiersze,
które w kolumnie materiał posiadają opis szyby oraz wyświetlone zostają
tylko 2 kolumny: materiał i ilość.
Operatory, które mogą być wykorzystywane w opcji WHERE zawiera poniższa tabela:
Operator |
Opis |
= |
Równość |
< |
Mniejsze niż |
> |
Większe niż |
<= |
Mniejsze niż lub równe |
>= |
Większe niż lub równe |
<> lub # |
Różne |
! |
Negacja operatorów <,> i = |
Porównywane wartości muszą być zgodnych typów (typy SMALLINT, INTEGER, DECIMAL, NUMERIC i FLOAT są wszystkie ze sobą zgodne).
W warunku umieszczonym
w opcji WHERE mogą występować następujące
operatory logiczne: NOT, AND
oraz OR
(z priorytetem takim jak kolejność występowania).
SELECT *
FROM Numer
WHERE nr > 100 AND mistrz = „Wiśniewski”;
Pod uwagę są brane
wszystkie kolumny z tablicy Numer. Zastaną wyprowadzone zawartości tych
wierszy,
dla których nr jest większe od 100 i nazwisko mistrza jest
Wiśniewski.
Wyrażenia są zapisami
operacji, które mogą być wykonane na obiektach języka.
Wyrażenia mogą zawierać kombinację kolumn, operatorów arytmetycznych
(+,-,/,*,**,^),
stałych (numerycznych, logicznych i tekstowych) oraz zmiennych.
W wyrażeniach mogą występować również operatory „+” oraz „-”
do wykonywania operacji na łańcuchach tekstowych.
Kolejność obliczania
wyrażenia wynika z priorytetów poszczególnych operatorów lub może być
sterowana przez nawiasy.
Wyrażenia podają wartość logiczną (prawdy lub fałszu), wartość numeryczną lub
łańcuch tekstowy.
Wyrażenia mogą być stosowane w następujących sytuacjach:
§ Do wprowadzenia opisu kolumny informacyjnej w tablicy wynikowej instrukcji SELECT;
§ Do definicji nowej kolumny obliczeniowej w klauzuli instrukcji SELECT;
§ Do definicji warunku w klauzuli WHERE;
§ Do definicji wyrażenia w klauzuli HAVING.
SELECT materiał, cena, cena*10,”(cena dziesięciokrotna)”
FROM Cena;
Zostaną wyprowadzone
zawartości kolumn: materiał oraz cena, a obok nich wartości dwóch wyrażeń:
wyrażenia pierwszego zawierającego cenę pomnożoną przez 10 oraz wyrażenia
drugiego zawierającego tekst: (cena dziesięciokrotna).
COUNT() zlicza liczbę wybranych wierszy;
SUM() sumuje wartości w kolumnach numerycznych;
MIN() znajduje minimalną wartość tekstową, typu daty lub numeryczną;
MAX() znajduje maksymalną wartość;
AVG() oblicza średnią wartość w kolumnach numerycznych.
Funkcje agregujące
wykonują obliczenia na wszystkich wartościach danej kolumny (lub
wszystkich kolumn) w tablicy,
perspektywie, tablicy wynikowej lub też grupie wierszy zdefiniowanych przez
klauzulę GROUP BY lub HAVING.
Wynikiem wykonywanej funkcji jest pojedyncza wartość.
SELECT COUNT(*)
FROM Ilość;
Zostanie podana liczba wszystkich materiałów wydanych z magazynu.
SELECT COUNT(*)
FROM Numer
WHERE mistrz = „Kowalski”;
Zostanie podana liczba kwitów magazynowych wydanych dla mistrza Kowalskiego.
SELECT SUM(ilość)
FROM Ilość;
Zostanie wyprowadzona liczba wszystkich wydanych materiałów z magazynu.
SELECT MAX(ilość), MIN(ilość)
FROM Ilość;
Zostanie wyprowadzona maksymalna i minimalna ilość wydanego materiału z magazynu.
SELECT COUNT(DISTINCT mistrz)
FROM Numer;
Zostanie wyprowadzona liczba wszystkich mistrzów.
Umożliwiają one odpowiednie wysterowanie opcji WHERE instrukcji SELECT. Działanie tych predykatów jest następujące:
BETWEEN testuje wartość z pewnego zakresu;
IN sprawdza, czy dana wartość znajduje się na liście wartości;
LIKE porównuje tekstową
kolumnę z podanym łańcuchem tekstowym.
Przy pomocy specjalnych znaków można wysterować, i
le znaków może być nieokreślonych w porównywanym łańcuchu: „?” (tylko
jeden znak), „*” (kilka znaków).
WHERE nr BETWEEN 100 AND 900;
WHERE mistrz IN(„Kowalski”, „Wiśniewski”);
WHERE mistrz LIKE „Wiśniews*”;
Wiersze tablicy
wyprowadzane są przez instrukcję SELECT, w takiej
kolejności, w jakiej są ułożone w tablicy.
Do zmiany tej kolejności służy klauzula ORDER BY
postaci:
ORDER BY <kolumna/nr> [ASC/DESC]
[,<kolumna/nr> [ASC/DESC] ...];
Kolumny wyszczególnione
w klauzuli ORDER BY muszą być również
wyszczególnione w klauzuli SELECT.
Zamiast nazwy kolumny można podać jej numer kolejny w klauzuli SELECT.
Opcja ASC powoduje wyprowadzenie w kolejności
niemalejącej, a DESC w kolejności
nierosnącej.
SELECT DISTINCT mistrz
FROM Numer
ORDER BY mistrz ASC;
Wybiera z tablicy Numer różne nazwiska mistrzów i układa je w kolejności alfabetycznej.
SELECT *
FROM Numer
ORDER BY mistrz ASC, nr DESC;
Z tablicy numer zostają
wyprowadzone wszystkie kolumny.
Wiersze zostaną ustawione w kolejności alfabetycznej wg nazwiska mistrza
a wartości kolumny nr w kolejności malejącej.
SELECT *
FROM Numer
WHERE nr > 3
ORDER BY mistrz DESC;
Dwie klauzule instrukcji SELECT, GROUP BY i HAVING pozwalają ustawiać wiersze w grupy,
co umożliwia zmianę zakresu funkcji agregujących ze wszystkich wierszy
z tablicy do wszystkich wierszy w grupie.
Klauzula GROUP BY układa wiersze w grupy, w których
określona kolumna ma tą samą wartość,
a następnie redukuje tą grupę do pojedynczego wiersza w tablicy
wynikowej. Kolumna wyszczególniona w klauzuli SELECT
musi być zawarta w klauzuli GROUP BY
i odwrotnie.
Klauzula HAVING podaje warunek, który musi spełniać każda grupa wyszczególniona w klauzuli GROUP BY, aby mogła znaleźć się w tablicy wynikowej.
SELECT COUNT(nr), mistrz
FROM Numer
GROUP BY mistrz
HAVING COUNT(nr) > 1
ORDER BY mistrz;
Zostaną wyprowadzone te nazwiska mistrzów, dla których liczba wydanych kwitów jest większa niż 1.
W języku SQL istnieje
możliwość połączenia tablic wynikowych dwóch lub więcej instrukcji SELECT.
Powtarzające się wiersze są usuwane. Łączone tablice wynikowe powinny być
zgodne,
to znaczy powinny mieć taką samą liczbę kolumn o zgodnych typach.
Nazwy kolumn w różnych tablicach mogą być różne.
W ostatniej łączonej instrukcji można zamieścić klauzulę ORDER BY, w której muszą występować numery kolumn
a nie ich nazwy.
SELECT DISTINCT mistrz
FROM Numer
UNION
SELECT DISTINCT kierownik
FROM Kierownicy
UNION
SELECT DISTINCT robotnik
FROM Robotnicy
ORDER BY 1;
Wyprowadza nazwiska wszystkich pracowników w kolejności alfabetycznej.
Klauzulę INTO wykorzystuje się do zapamiętania wyników zapytania w zmiennych (wyniki te muszą być pojedynczymi wartościami).
SELECT SUM(ilość)
INTO x
FROM Ilość;
W zmiennej x zostanie zapamiętana suma ilości wydanych materiałów.
Operacja połączenia jest
jedną z podstawowych operacji wykorzystywanych w językach
manipulowania danymi.
W języku SQL operację tę realizuje się przy pomocy instrukcji SELECT.
SELECT Numer.nr, mistrz, wydział
FROM Numer, Wydział
WHERE Numer.nr = Wydział.nr;
Powyższa instrukcja
dokonuje połączenia dwóch tablic Numer i Wydział.
Najpierw wyszczególnione są kolumny z dwóch łączonych tablic, które
powinny się znaleźć w tablicy wynikowej.
Przy kolumnie nr należy podać jeszcze nazwę tablicy, ponieważ kolumna ta
występuje w dwóch łączonych tablicach.
W opcji FROM podaje się nazwy łączonych tablic, a
w opcji WHERE warunek, który muszą spełniać
wiersze obu tablic,
aby się znaleźć w tablicy wynikowej. Wiersze, które nie spełniają tego
warunku, nie znajdą się w tablicy wynikowej.
SELECT Numer.nr, mistrz, wydział
FROM Numer, Wydział;
Powyższa instrukcja
realizuje operację tzw. naturalnego połączenia, w której nie jest
sprawdzany żaden warunek. T
ablice łączone są w ten sposób, że każdy wiersz pierwszej tablicy łączony
jest z wierszem drugiej tablicy. Warto zwrócić uwagę, że taka operacja
połączenia nie jest celowa.
W opcji WHERE, w której podaje się warunek wykorzystywany w operacji połączenia można również podać warunek, który ogranicza wiersze tablicy wynikowej.
SELECT Numer.nr, mistrz, wydział
FROM Numer, Wydział
WHERE Numer.nr = Wydział.nr AND Numer.nr > 3;
W języku SQL można łączyć
więcej niż dwie tablice. Dokonuje się tego tak jak poprzednio przy pomocy
instrukcji SELECT,
z tym, że dla każdej tablicy należy podać warunek, według którego będą
łączone wiersze.
SELECT Numer.nr, mistrz, wydział, Ilość.materiał, cena, ilość
FROM Numer, Wydział, Ilość, Cena
WHERE Numer.nr = Wydział.nr AND Wydział.nr = Ilość.nr
Ilość.materiał = Cena.materiał;
Powyższa instrukcja powoduje połączenie w tablicy wynikowej wszystkich tablic rozważanej bazy danych: Numer, Wydział, Ilość, Cena.
Zapytania zagnieżdżone można podzielić na dwie grupy:
§ Zapytania zagnieżdżone podające pojedynczą wartość;
§ Zapytania zagnieżdżone podające kilka wartości z jednej kolumny.
SELECT cena
FROM Cena
WHERE materiał =
(SELECT materiał
FROM Ilość
WHERE nr = k);
Zostanie wyprowadzona cena materiału, którego kwit magazynowy ma numer równy wartości zmiennej k.
W instrukcji SELECT można wykorzystywać również funkcje agregujące do podania pojedynczej wartości.
SELECT materiał
FROM Cena
WHERE cena >
(SELECT AVG(cena)
FROM Cena);
Zostaną określone materiały, których cena jest większa od przeciętnej ceny materiałów.
W języku SQL można
wykorzystać zapytania zagnieżdżone, które podają kilka wartości z jednej
kolumny.
Do interpretacji tych wartości wykorzystuje się słowa kluczowe IN, ANY, lub ALL.
Słowo kluczowe IN służy do sprawdzenia, czy wartość wyrażenia
umieszczonego w klauzuli WHERE
zawiera się w zbiorze wartości podawanych przez wewnętrzną instrukcję SELECT.
SELECT *
FROM Numer
WHERE nr IN
(SELECT nr
FROM Wydział
WHERE wydział = k);
Zostaną wyprowadzone nazwiska mistrzów pracujących na k-tym wydziale i numery ich kwitów magazynowych.
Słowo kluczowe ANY służy do sprawdzania, czy warunek umieszczony
w klauzuli WHERE jest prawdziwy
dla dowolnej wartości podawanej przez wewnętrzną instrukcję SELECT.
SELECT mistrz
FROM Numer
WHERE nr = ANY
(SELECT nr
FROM Ilość
WHERE materiał = nazwa);
Wewnętrzna instrukcja SELECT podaje wszystkie numery kwitów magazynowych wydanych
przy pobraniu materiału,
którego nazwa jest umieszczona w zmiennej nazwa. Słowo kluczowe ANY powoduje wyprowadzanie nazwisk mistrzów,
dla których numer kwitu jest jednym z numerów zdefiniowanych przez
wewnętrzną instrukcję SELECT.
Słowo kluczowe ALL służy do sprawdzania, czy warunek umieszczony
w klauzuli WHERE jest prawdziwy
dla wszystkich wartości podawanych przez wewnętrzną instrukcję SELECT.
SELECT DISTINCT materiał
FROM Ilość
WHERE ilość > ALL
(SELECT ilość
FROM Ilość
WHERE nr <k);
Zostaną podane nazwy
materiałów, których wydane ilości są większe od wszystkich wydanych il
ości materiałów o numerach mniejszych od k.
SELECT mistrz
FROM Numer
WHERE nr IN
(SELECT nr
FROM Wydział
WHERE wydział = 1 AND nr > 2);
Zostaną wyprowadzone
nazwiska mistrzów, którzy pracują na pierwszym wydziale i numery kwitów
magazynowych
wydanych dla nich materiałów są większe od 2.
W języku SQL zapytania mogą być zagnieżdżone jedno w drugim. Zapytania takie nazywamy zapytaniami wielokrotnymi.
SELECT mistrz
FROM Numer
WHERE nr IN
(SELECT nr
FROM Ilość
WHERE materiał =
(SELECT materiał
FROM Cena
WHERE cena >
(SELECT AVG(cena)
FROM Cena)));
Zostaną wyprowadzone nazwiska mistrzów, którzy pobrali materiały o cenie większej od przeciętnej ceny materiałów.
Predykat IS NULL umieszczony w klauzuli WHERE
podaje wartość prawdy lub fałszu w zależności od tego,
czy zapytanie wewnętrzne wyprowadza jakąś wartość. Jeżeli zapytanie wewnętrzne
wyprowadza wartość,
to predykat IS NULL podaje wartość prawdy,
w przeciwnym przypadku wartość fałszu.
W języku SQL można
zadawać również tzw. zapytania skorelowane.
Polegają one na tym, że z zapytania zewnętrznego jest przekazywana
do zapytania wewnętrznego pewna wartość,
dla której jest wykonywane zapytanie wewnętrzne.
W przypadku wykorzystywania w obu zapytaniach tej samej tablicy
należy podać obok nazwy tablicy jej nazwę dodatkową.
SELECT *
FROM Zarobki Z1
WHERE zarobek =
(SELECT MAX(zarobek)
FROM Zarobki Z2
WHERE Z1.wydział = Z2.wydział);
Powyższa instrukcja
spowoduje wyprowadzenie nazwisk mistrzów o maksymalnych zarobkach na danym
wydziale.
Zapytanie zewnętrzne przekazuje do zapytania wewnętrznego numer wydziału.
Na tej podstawie zapytanie wewnętrzne oblicza maksymalny zarobek oddzielnie dla
każdego wydziału.
Oprócz wyszukiwania
informacji w już istniejących tablicach język SQL daje nam możliwość
zmiany ich zawartości.
I tak, aby dodać nowy wiersz do naszej tablicy musimy posłużyć się
następującą klauzulą:
INSERT INTO <nazwa tablicy>
[(lista kolumn)]
VALUES (<lista wartości>);
Lista kolumn nie musi występować, podane wartości są wtedy wprowadzane do wszystkich kolumn w kolejności ich występowania w tablicy.
INSERT INTO Ilość
VALUES (1, „deski”, 20);
Przy odpowiednim wykorzystaniu klauzuli SELECT możliwe jest przekopiowanie wybranych przez nas wierszy z jednej tablicy do drugiej.
INSERT INTO <nazwa tablicy>
[(lista kolumn)]
<instrukcja SELECT>;
INSERT INTO Ilość
SELECT *
FROM Ilosc_1
WHERE materiał= „deski”;
W tym przykładzie zostaną przekopiowane wszystkie wiersze z tablicy Ilosc_1 odpowiadające selekcji do tablicy Ilość.
Oprócz możliwości wstawiania wierszy język SQL udostępnia także możliwość usuwania wierszy, które spełniają zadany warunek.
DELETE
FROM <nazwa tablicy>
[<alias>] WHERE <warunek>;
DELETE
FROM Ilość
WHERE materiał = „okna”;
Aby zmienić opis już
istniejącego wiersza nie musimy się uciekać do usuwania i dodawania,
ponieważ SQL daje nam możliwość edytowania istniejących wierszy.
UPDATE <nazwa tablicy> / <nazwa perspektywy>
SET <nazwa kolumny> = <wyrażenie>
[,<nazwa kolumny> = <wyrażenie> ...]
[WHERE <warunek>];
UPDATE Ilość
SET ilość = 100
WHERE nr = 23;
Podana instrukcja zmieni zawartość kolumny ilość na 100 w wierszach, które w kolumnie nr posiadają wartość 23.
To kolejna z możliwości języka SQL – udostępnia narzędzie, które pozwoli nam dodać kolumnę do już istniejącej tablicy.
ALTER TABLE <nazwa tablicy>
ADD (<nazwa kolumny> <typ danych>
[,<nazwa kolumny> <typ danych> ...]);
ALTER TABLE Ilość
ADD (mistrz CHAR(15));
Po wykonaniu tej instrukcji zostanie dodana kolumna typu znakowego o maksymalnej długości 15 znaków o nazwie mistrz.