- •Мова sql(Structured Query Language) – як універсальний засіб створення баз даних, маніпулювання данними та отримамання потрібної інформації.
- •Умова відбору (ключове слово where)
- •Зрівняння.
- •Ліве з’єднання (left join)
- •Сортування результату (фраза order by)
- •Групування результатів (фраза group by). Агрегатні функціії.
- •Використання фрази group by
- •Використання фрази having
- •Підзапити
- •Ключові слова exists I not exists
- •Модифікація даних (оператор update)
- •Видалення даних з бази(оператор delete).
- •Створенння таблиць (оператор create table).
- •Check (Naukov_stupin in(‘не має’, ‘кадидат’, ‘доктор’))
- •Використання транзакцій.
- •Управління доступом даних
- •Insert – право втавляти в таблицю нові рядки;
- •Надання привілеїв іншим користувачам (оператор grant)
- •Insert - користувач з цим привілеєм може виконувати оператор insert для цієї таблиці;
- •Відміна наданих привілеїв (оператор revoke)
Підзапити
Звернімося до таблиць Vidomist(kod,year,month,D), tpp(d_l,d_r, p,c) i Osoba(kod, priz). Нагадаємо, що в таблиці Vidomist (kod,year,month,D – її поля) зберігається інформація про нараховану зарплату співробітників за певний рік і місяць. Таблиця tpp містить дані для обрахування податку на прибуток, а таблиця Osoba інформацію про персональний склад. Нехай нам потрібно сформувати список осіб з такими колонками: “ Прізвище ”,” Нараховано ”, які одержують нараховану зарплату вищу за середню середню нараховану зарплату за 2-й місяць 2002 року. Середню нараховану зарплату за 2-й місяць 2002 року визначить такий запит:
SELECT AVG(D)
FROM Vidomist
WHERE year=2002 AND mounth=2
Середня нарахована зарплата становить 500 грн.
Для вирішення цієї задачі потрібно а) знайти чому дорівнює середня зарплата а потім б) ті рядки, в яких нарахована сума перевищує середню зарплату, включити до результуючої таблиці. Запит, який вирішує поставлену задачу, наведено нижче:
SELECT a.priz AS Прізвище, b.D AS Нараховано
FROM (Osoba AS a INNER JOIN Vidomist AS b ON a.kod=b.kod)
WHERE b.year=2002 AND b.mounth=2 AND b.D> (SELECT AVG(D) FROM Vidomist WHERE year=2002 AND mounth=2)
Результуюча таблиця матиме вид:
-
Прізвище
Нараховано
Сидоров
600
Пояснимо цей SELECT-оператор. Запит
SELECT AVG(D)
FROM Vidomist
WHERE year=2002 AND mounth=2
який розташований у фразі WHERE першого SELECT’у (він взятий у дужки) називають підзапитом. На відміну від основного запиту, якого ще називають зовнішнім запитом, підзапит ще називають внутрішнім запитом. Цей підзапит знаходить середню нараховану зарплату. Потім запит відбирає ті рядки, в яких нарахована зарплата перевищує число (в цьому конкретному випадку воно дорівнює 500), знайдене підзапитом.
Якщо ж потрібно скласти список співробітників, які мають нараховану зарплату вище середньої, вказавши при цьому на скільки вона перевищує середню, то запит матиме вид:
SELECT a.priz AS Прізвище, b.D AS Нараховано, b.D-(SELECT AVG(D) FROM Vidomist WHERE year=2002 AND mounth=2) AS Перевищення
FROM (Osoba AS a INNER JOIN Vidomist AS b ON a.kod=b.kod)
WHERE b.year=2002 AND b.mounth=2 AND b.D> (SELECT AVG(D) FROM Vidomist WHERE year=2002 AND mounth=2)
Результуюча таблиця матиме вид:
-
Прізвище
Нараховано
Перевищення
Сидоров
600
100
Якщо ж середню величину зарплати обраховувати виходячи з суми, яку повинні видавати на руки (нарахована мінус податок на прибуток) і запит має повертати такі колонки: “ Прізвище ”,” Нараховано ”,” Сума податку ” і “ До виплати ”, то запит матиме вид:
SELECT a.priz AS Прізвище, b.D AS Нараховано, (b.D-c.d_l)*c.p+c.c AS [Сума податку], b.D-((b.D-c.d_l)*c.p+c.c) AS [До виплати]
FROM (Osoba AS a INNER JOIN Vidomist AS b ON a.kod=b.kod) INNER JOIN tpp AS c ON (b.D>c.d_l) AND (b.D<=c.d_r)
WHERE b.year=2002 AND b.mounth=2 AND (b.D-((b.D-c.d_l)*c.p+c.c))> (SELECT AVG(b.D-((b.D-c.d_l)*c.p+c.c)) FROM Osoba a, Vidomist b, tpp c WHERE a.kod=b.kod AND (b.D>c.d_l) AND (b.D<=c.d_r) AND b.year=2002 AND b.mounth=2)
Результуюча таблиця матиме вид:
-
Прізвище
Нараховано
Сума податку
До виплати
Сидоров
600
105,55
494,45
Підзапит цього запиту має вид:
SELECT AVG(b.D-((b.D-c.d_l)*c.p+c.c))
FROM Osoba a, Vidomist b, tpp c
WHERE a.kod=b.kod AND (b.D>c.d_l) AND (b.D<=c.d_r) AND b.year=2002 AND b.mounth=2
Підзапит може вказуватись безпосередньо після операторів зрівнювання (=, <, >, <=, >=, <>) у фразах WHERE i HAVING. Текст підзапиту потрібно брати в дужки. До підзапитів застосовують такі правила і обмеження.
-
В підзапитах не повинна використовуватись фраза ORDER BY, хоч вона може використовуватись у зовнішньому запиті.
-
За змовчуванням імена стовпчиків в підзапиті відносяться до таблиць, які вказані у фразі FROM підзапиту. Разом з тим допускається посилатись і на стовпчики таблиць, які вказані у фразі FROM зовнішнього запиту, для чого використовуються аліаси.
-
Якщо підзапит є одним з двох операндів оператора зрівнювання, то підзапит повинен вказуватись в правій частині оператора зрівнювання.
-
Якщо підзапит є одним з двох операндів оператора зрівнювання, то підзапит має повертати єдине значення.
Існує три типи підзапитів.
-
Скалярний підзапит – це підзапит, який повертає єдине значення. У вищенаведених прикладах використовувався скалярний підзапит.
-
Строковий підзапит – це підзапит, який повертає значення декількох стовпчиків у вигляді одного рядка.
-
Табличний підзапит - це підзапит, який повертає значення одного або більше стовпчиків таблиці, які розташовані в більш ніж одному рядку. Табличний підзапит може використовуватись кругом де допускається вказувати таблицю – наприклад, як операнд предикату IN.
Ключові слова ANY i ALL
Ключові слова ANY i ALL використовуються лише з підзапитами, які повертають один стовпчик чисел. Якщо перед підзапитом стоятиме ключове слово ALL, умова зрівняння вважається істинною, якщо вона виконується для всіх значень в результуючому стовпчику підзапиту. Наприклад, запит
SELECT *
FROM Vidomist
WHERE D> ALL (SELECT D FROM Vidomist WHERE kod IN (1,2))
Результат наведено нижче
|
kod |
Year |
mounth |
D |
|
3 |
2002 |
1 |
2709.98 |
В данному конкретному випадку внутрішній запит
SELECT D FROM Vidomist WHERE kod IN (1,2)
відбере такі значення: {367.78,1309.55,400,500}.
Очевидно, умова D> ALL (SELECT D FROM Vidomist WHERE kod IN (1,2))
еквівалентна умові D> (SELECT MAX(D) FROM Vidomist WHERE kod IN (1,2)).
Власне кажучи, цей запит еквівалентний запиту (дасть той же результат)
SELECT *
FROM Vidomist
WHERE D> (SELECT MAX(D) FROM Vidomist WHERE kod IN (1,2))
Якщо перед підзапитом стоятиме ключове слово ANY, умова зрівняння вважається істинною, якщо вона виконується хоча б для одного значення в результуючому стовпчику підзапиту. Наприклад, умова
D> ANY(SELECT D FROM Vidomist WHERE kod IN (1,2))
істинна тоді і тільки тоді коли вона істинна хоча б для одного значення, яке відбере внутрішній запит. Отже, любе D, яке більше 400, задовольнить нашій умові.
Результатом запиту
SELECT *
FROM Vidomist
WHERE D> ANY (SELECT D FROM Vidomist WHERE kod IN (1,2))
буде таблиця:
|
kod |
Year |
mounth |
D |
|
1 |
2002 |
1 |
367.78 |
|
2 |
2002 |
1 |
1309.55 |
|
3 |
2002 |
1 |
2709.98 |
|
2 |
2002 |
2 |
500 |
|
3 |
2002 |
2 |
600 |
Очевидно, цей запит буде еквівалентний запиту
SELECT *
FROM Vidomist
WHERE D> (SELECT MIN(D) FROM Vidomist WHERE kod IN (1,2))
