Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Konspekt_lektsiy_BD_amp_amp_SD

.pdf
Скачиваний:
28
Добавлен:
10.02.2016
Размер:
1.41 Mб
Скачать

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

71

 

 

 

 

 

 

 

WHERE умова. Наприклад:

 

 

 

 

 

SELECT * FROM Rating WHERE DKod = 2 AND Mark >= 60;

 

 

з наступним результатом:

 

 

 

 

 

KOD

DKOD

MARK

MDATE

 

Причому, в умові команд SELECT, UPDATE і

 

 

 

 

 

2

2

76

12.10.2011

 

DELETE можуть використовуватися як оператори

 

3

2

85

12.10.2011

 

порівняння, так і булеві оператори, що видно з

 

останнього прикладу. Крім того, в умові цих команд,

4

2

85

12.10.2011

 

так само, як в обмеженнях таблиць і доменів, мо-

жуть використовуватися спеціальні оператори LIKE, BETWEEN, IN і плюс ще оператор IS NULL, що згадувався раніше. Наведемо кілька прикладів:

SELECT *

FROM

Student

WHERE

Spec

IN(‘ОІ’, ‘OC’);

Запит виведе всі дані, які є в таблиці Student, про студентів спеціальностей ОІ („Економічна кібернетика“) та ОС („Прикладна математика“).

SELECT Kod, DKod, Mark, MDate

FROM Rating

WHERE DKod = 2 AND Mark

BETWEEN 30 AND 60;

Запит відобразить коди та рейтинг з певної (тут — другої) дисципліни студентів, які мають допуск до підсумкового контролю з цієї дисципліни, тобто мають рейтинг у межах 30 та 60 балів,

SELECT *

FROM Student

WHERE

SecondName LIKE ‘%M%B’;

Запит вибере студентів, прізвища яких закінчуються літерою В, а в середині чи на початку мають літеру М, та виведе всі дані про них.

SELECT * FROM Student WHERE Patronymic IS NULL;

Запит вибере та виведе всі дані про студентів, які не мають по-батькові.

Крім умовних операторів, у командах ММД, конкретно у SELECT, використовуються так звані агрегатні функції, що повертають деяке єдине значення поля для підмножини кортежів таблиці.

Агрегатні функції

У стандарті SQL визначено 5 таких функцій, хоча будь-яка реалізація мови містить у 4 - 6 разів більше функцій. Особливістю агрегатних функцій є те, що, використовуючи імена полів як аргументи, самі вони вказуються в команді SELECT замість або разом з полями. Це функції AVG (average) і SUM (summa), які використовуються тільки для числових полів, і функції MAX, MIN і COUNT, що можуть застосовуватися і для числових, і для символьних атрибутів. Так функції AVG і SUM дозволяють обчислити відповідно середнє значення і суму значень певного атрибуту у всіх кортежах таблиці. Наприклад:

SELECT AVG(Mark)

FROM Rating [WHERE DKod = 8];

Цей запит повертає середній рейтинг, підрахований, якщо умова відсутня, по всіх кортежах таблиці або, при наявності умови, тільки по кортежах, що відповідають восьмій дисципліні.

Назви функцій MAX і MIN говорять самі за себе. Функція ж COUNT підраховує кіль-

кість значень у стовпці чи кількість рядків у таблиці.

Наприклад:

SELECT COUNT(*)

FROM Student;

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

72

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

Використання * як атрибута забезпечить підрахунок кількості всіх рядків у таблиці,

включаючи повторювані і NULL-еві (яких, за ідеєю, не має бути).

Для підрахунку кількості не-NULL-евих значень якого-небудь атрибута використовується формат:

SELECT COUNT([ALL] поле) FROM таблиця;

Ключове слово ALL використовується за замовчуванням. Наприклад: SELECT COUNT(Patronymic) FROM Student;

До речі, всі інші агрегатні функції в будь-якому випадку ігнорують NULL-значення. Якщо ж необхідно підрахувати число різних значень якогось поля і виключити при

цьому NULL-значення, то в аргументах функції необхідно використовувати оператор

DISTINCT. Наприклад:

SELECT COUNT(DISTINCT Patronymic) FROM Student;

До речі, оператор DISTINCT може бути вказаний у будь-якій агрегатній функції, але в MAX і MIN він марний, а в SUM і AVG — не має сенсу, тому що вплине на результат.

Ще одна особливість агрегатних функцій — можливість використання скалярних виразів у якості їхніх аргументів, у яких, щоправда, не має бути самих агрегатних функцій. Наприклад:

SELECT AVG(LongevityInc + DegreeInc + TitleInc + SpecialInc) FROM SalaryIncrements;

У деяких розширеннях SQL, зокрема PostgreSQL останнє обмеження зняте.

Скалярні вирази можуть бути аргументами і самої команди SELECT, також як і команди UPDATE. У цьому випадку в них можуть входити і поля, і числові константи, і агрегатні функції.

Наприклад:

SELECT (MAX(LongevityInc)+MAX(DegreeInc)+MAX(TitleInc)+MAX(SpecialInc))/4 FROM SalaryIncrements;

Символьні константи у виразах використовуватися не можуть. Але зате їх можна просто включити у вихідну таблицю результату вибірки в інтерактивному режимі.

Наприклад:

SELECT

Kod, DKod, Mark, ‘на 14.10.11’

FROM

Rating;

Результат — всі рядки таблиці з додатковим полем:

 

 

 

 

 

 

 

 

 

 

Kod

DKod

 

Mark

 

 

 

1

1

 

82

на 14.10.11

 

 

1

2

 

10

на 14.10.11

 

 

 

 

 

 

 

 

 

8

1

 

0

на 14.10.11

Чи наприклад:

 

 

 

 

SELECT

AVG(Mark), ‘до 10-го тижня’

FROM

Rating;

З визначення агрегатних функцій видно, що вони не можуть використовуватися в одному SELECT-запиті разом з полями, тому що повертають одне єдине значення. Наприклад

(неправильно):

SELECT Kod, MAX(Mark) FROM Rating;

Однак на практиці може виникнути така задача: необхідно отримати середнє значення

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

73

 

 

Mark у межах певної дисципліни.

Розв’язати цю задачу допоможе оператор GROUP BY, що забезпечує виділення під-

групи з конкретним значенням атрибута чи підмножини атрибутів і застосування агре-

гатних функцій до кожної підгрупи. Наприклад:

SELECT DKod, AVG (Mark) FROM

Rating

 

 

GROUP BY DKod;

 

 

 

Результат може бути такий:

 

 

 

 

DKod

 

Тепер розширимо цей приклад. Припустимо, що не-

 

 

1

60

обхідно з відношення (таблиці), отриманої в попередньому

2

64

прикладі, виконати вибірку кортежів, для яких середнє

3

30

значення більше ніж, наприклад, 75. Ми вже знаємо, що

операція вибірки реалізується за допомогою оператора

4

97

WHERE. Однак результуюча таблиця цього прикладу бу-

5

65

дується на основі груп з використанням агрегатної функції,

 

 

 

 

тому тут існує низка обмежень.

 

 

 

Для розв’язання подібних задач, де в умові запиту використовується агрегатна функція чи поле, на яке виконується проекція, у SQL був уведений ще один оператор, що реалізує операцію вибірки — HAVING.

Відтак запит, що відповідає поставленій задачі буде виглядати таким чином:

 

 

SELECT

DKod, AVG(Mark)

FROM

Rating

 

 

 

 

 

GROUP BY

DKod

 

 

 

 

 

 

 

 

 

HAVING

AVG(Mark) > 75;

 

 

 

 

 

 

 

 

з таким результатом:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DKod

 

 

 

 

У вислові HAVING можна використовувати і просто

 

 

 

 

 

 

 

 

 

4

 

 

97

 

імена полів. Єдина умова при цьому — таке поле чи під-

 

 

 

 

 

 

 

 

 

 

 

 

множина полів повинна мати одне і теж значення в межах групи.

 

 

 

 

 

Наприклад:

 

 

 

 

 

 

 

 

 

 

SELECT

DKod, AVG(Mark)

FROM

Rating

 

 

 

 

 

GROUP BY

DKod

 

 

 

 

 

 

 

 

 

HAVING

DKod <> 4;

 

 

 

 

 

 

 

 

для виключення з результату дисципліни з кодом 4.

 

 

 

 

 

Чи, наприклад:

 

 

 

 

 

 

 

 

 

 

… HAVING

NOT DKod IN(3, 4);

 

 

 

 

 

для виключення з результату дисциплін з кодом 3 та 4:

 

 

 

 

 

 

DKod

 

 

 

Таким

чином,

оператор

HAVING

аналогічний

 

1

 

 

60

 

WHERE за винятком того, що рядки відбираються не за

 

2

 

 

64

 

значеннями стовпців, а будуються зі значень стовпців за-

 

 

 

 

 

 

 

5

 

 

65

 

значених в GROUP BY і значень агрегатних функцій, обчи-

 

 

 

 

 

 

 

 

 

 

 

 

слених для кожної групи, утвореної GROUP BY.

Якщо ж необхідно додати в запит з GROUP BY умову, що містить поле, яке не використовується для групування, то така умова, як і раніше, задається за допомогою WHERE і навіть одночасно з HAVING. Наприклад:

SELECT Kod, AVG(Mark)

FROM Rating

WHERE

DKod = 5

 

GROUP BY

Kod

 

HAVING

NOT

Kod

IN(3, 4);

Цей запит виключить з підрахунку середнього рейтингу кортежі, що стосуються студе-

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

74

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

нтів, що мають код 3 або 4, і підрахує його для п’ятої дисципліни.

Наступний момент, який ми розглянемо, зв’язаний із сортуванням значень, отриманих у результаті запиту SELECT. Справа в тому, що кортежі в таблиці зберігаються в порядку їхнього надходження (введення). Відповідно при введенні (за замовчуванням) цей порядок буде збережений. Виняток становлять проіндексовані поля. Очевидно, більш зручним для використання є введення множини кортежів таблиці, відсортованих відповідно до значень множини символьних та/або числових полів у прямому чи зворотному порядку. Для забезпечення такої можливості в SQL введений оператор ORDER BY. Наприклад:

SELECT * FROM Student ORDER BY SecondName;

Однак у цьому прикладі кортежі, що мають однакове значення прізвища, можуть виявитися невпорядкованими за ім’ям, по-батькові тощо, що також незручно. Поправимо цей приклад:

SELECT * FROM Student ORDER BY SecondName, FirstName, Patronymic;

Для сортування кортежів у зворотному алфавітному порядку значень чи атрибута за убуванням використовується ключове слово DESC. Наприклад:

SELECT DKod, Mark FROM Rating ORDER BY DKod, Mark DESC;

(за DKod прямий, за Mark зворотний порядок).

Причому поле, за яким виконується сортування, не обов’язково має бути присутнім у підмножині, на яку виконується проекція.

Це особливо актуально у вбудованому режимі, коли результати різних операцій проекції того ж самого відношення виводяться в різні вікна. Наприклад:

1) SELECT

DKod FROM

Rating ORDER BY DKod;

2) SELECT

Kod, Mark

FROM Rating ORDER BY DKod, Mark DESC;

Аналогічні підходи можуть використовуватися і для таблиць, отриманих у результаті угруповання. Наприклад:

SELECT DKod, AVG(Mark) FROM Rating GROUP BY DKod ORDER BY DKod;

Однак відсортувати подібну таблицю за результатом агрегатної операції не є можливим, тому що таке поле не пойменоване і не існує ні в базовій таблиці, ані в представленні. На допомогу тут приходить внутрішня (автоматична) нумерація вихідних стовпців відповідно до порядку перерахування в команді SELECT. Наприклад:

SELECT

DKod, AVG(Mark) FROM Rating GROUP BY DKod ORDER BY 2 DESC;

Запит дасть один з отриманих вище результатів, але в

 

 

DKod

 

іншому порядку:

 

 

4

97

На жаль, це єдиний спосіб звернутися до таких стов-

 

 

5

65

пців, незважаючи на те, що їх можна пойменувати, задавши

 

 

2

64

їм псевдоніми чи, використовуючи вже прийнятий термін,

 

 

1

60

аліаси. Наприклад:

 

 

 

 

 

 

3

30

 

 

 

 

SELECT

DKod Discipline,

 

 

AVG(Mark) Averrage_Rating

 

 

FROM

Rating

GROUP BY DKod;

 

 

Раніше ми відмітили, що будь-який діалект SQL містить набагато більше агрегатних функцій чи подібних агрегатним. Так в PostgreSQL були введені аналітичні чи віконні функції, які окрім задач агрегування, виконують ще й частку операцій над багатовимірними структурами.

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

75

 

 

Аналітичні функції

За допомогою аналітичних функцій SQL-запити оформляються простіше та виконуються швидше у порівнянні з використанням чистої мови SQL у наступних випадках:

при підрахунку проміжної суми, коли необхідно показати сумарну зарплату співробітників відділу порядково, щоб у кожному рядку видавалася сума зарплат всіх співробітників аж до зазначеного;

при підрахунку відсотків у групі, коли необхідно показати, який відсоток від загальної зарплати по відділу становить зарплата кожного співробітника;

при запиті перших N, коли необхідно знайти N співробітників з найбільшими зарплатами або N товарів, які користуються найбільшим попитом по регіонах;

при підрахунку ковзного середнього, коли необхідно отримати середнє значення по поточним і попереднім N рядкам.

при виконанні ранжуючих запитів, коли необхідно показати відносний ранг зарплати співробітника серед інших співробітників того ж відділу.

Аналітичні функції мають наступний синтаксис:

ім’я_функції (аргумент, аргумент, …) OVER (опис_зрізу_даних)

Значення ім’я_функції визначається стандартними функціями агрегації (SUM, COUNT, MIN, MAX, AVG) та спеціальними функціями.

Опис_зрізу_даних визначається конструкціями: конструкція фрагментації, конструкція

впорядкування, конструкція вікна.

Конструкція фрагментації визначається ключовим словом PARTITION BY і логічно розбиває результуючу множину на групи за критеріями, що задаються виразами секціонування. Аналітичні функції застосовуються до кожної групи незалежно та для кожної нової групи вони скидаються. Якщо не вказати конструкцію фрагментації, вся результуюча множина вважається однією групою. Кожна аналітична функція в запиті може мати унікальну конструкцію фрагментації. Синтаксис конструкції фрагментації аналогічний синтаксису конструкції GROUP BY у звичайних SQL-запитах:

PARTITION BY вираз [, вираз [, вираз]]

Розглянемо два запити:

SELECT DeptKod, Job, SUM(Salary) sum_sal FROM Lecturer GROUP BY DeptKod, Job;

SELECT SecondName, DeptKod, Job,

SUM(Salary) OVER (PARTITION BY DeptKod, Job) sum_sal FROM Lecturer;

Перший запит отримає суму зарплати викладачів, які згруповані за кафедрами та посадами. Другий запит отримає список викладачів, для кожного з яких визначається сума зарплати викладачів, які мають ту ж саму кафедру та посаду.

Конструкція впорядкування визначається ключовим словом ORDER BY і задає критерій сортування даних у кожному фрагменті, як і у кожній групі. Конструкція ORDER BY в аналітичних функціях має наступний синтаксис:

ORDER BY вираз [ASC | DESC] [NULLS FIRST | NULLS LAST]

Необхідно враховувати, що рядки будуть упорядковані тільки в межах фрагментів (груп). Конструкції NULLS FIRST і NULLS LAST указують, де при впорядкуванні повинні бути значення NULL — на початку або наприкінці.

Розглянемо два запити:

SELECT SecondName, DeptKod, Job, HireDate,

SUM(Salary) OVER (PARTITION BY DeptKod, Job) sum_sal FROM Lecturer;

SELECT SecondName, DeptKod, Job, HireDate, SUM(Salary)

OVER (PARTITION BY DeptKod, Job ORDER BY HireDate) sum_sal FROM Lecturer;

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

76М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

Взапиті без конструкції впорядкування для кожного рядка (тобто по викладачу) виводиться загальна сума зарплат по всій групі викладачів, згрупованих по кафедрі та посаді, тобто визначаються витрати університу на зарплату викладачів по вказаній групі на поточний момент.

Взапиті з конструкцією впорядкування викладачі впорядковані за датою зарахування на роботу, і для кожного рядка виводиться сума зарплат викладача, описаного цим (поточним) рядком, та працюючих в тому ж підрозділі та на тій же посаді викладачів, описаних попередніми рядками, тобто визначаються витрати університету на зарплату викладачів по вказаній групі не на поточний момент, як в попередньому запиті, а з урахуванням дат їх прийняття на роботу:

SECONDNAME

DEPTKOD

JOB

HIREDATE

SUM_SAL

Погорецька

2

Доц.

1980-09-01

1000

Чугунов

2

Доц.

1985-09-01

2250

Малахов

2

Зав. каф.

1990-09-01

1500

Юхименко

3

Проф.

1982-09-01

1300

Востров

4

Доц.

1982-09-01

1100

Щоб отримати список викладачів з їх іменами, датою зарахування, зарплатою, де в кожному рядку буде визначено поточні витрати університету на зарплату викладачів, можна виконати запит:

SELECT SecondName, DeptKod, Job, HireDate,

SUM(Salary) OVER (ORDER BY HireDate) sum_sal FROM Lecturer;

Проаналізувавши результат запиту, можна визначити, що без конструкції фрагментації групою вважаються всі рядки, в кожному рядку по викладачу виводиться сума його зарплати та зарплат викладачів, які зараховані раніше, а для викладачів з однаковими значеннями дати зарахування зарплати підсумовуються в цій умовній групі.

Конструкція вікна використовується для віконних функцій, тобто коли в секції впорядкування зазначене ORDER BY, і може мати один із синтаксисів:

[RANGE | ROWS] початок_вікна

[RANGE | ROWS] BETWEEN початок_вікнаAND кінець_вікна

Опис початку та кінця вікна може визначатися як:

UNBOUNDED PRECEDING | значення PRECEDING CURRENT ROW

UNBOUNDED FOLLOWING | значення FOLLOWING

Вікно може бути створене по діапазону значень даних з використанням ключового слова RANGE або по зсуву відносно поточного рядка з використанням ключового слова ROWS.

Конструкція вікна дозволяє задати вікно даних у межах групи, яке переміщається або жорстко прив’язане (набір, інтервал), з яким буде працювати аналітична функція. Наприклад, конструкція діапазону RANGE UNBOUNDED PRECEDING визначає застосування аналітичної функції до кожного рядка даної групи з першого до поточного. Стандартним є жорстко прив’язане вікно, яке починається з першого рядка групи та триває до поточного.

Ключове слово UNBOUNDED знімає фіксовану границю вікна.

Ключові слова PRECEDING та FOLLOWING задають верхню і нижню границі агрегування, тобто інтервал рядків, „вікно“ для агрегування.

Можливі такі варіанти вікон:

якщо нижня границя вікна фіксована, тобто збігається з першим рядком упорядкованої деяким чином групи рядків, а верхня границя повзе, тобто збігається з поточним ряд-

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

77

 

 

ком у цій групі, то отримуємо наростаючий підсумок (кумулятивний агрегат), коли розмір вікна змінюється, розширюючись в один бік, і саме вікно рухається за рахунок розширення;

якщо нижня та верхня границі фіксовані, тобто фіксовані щодо поточного рядка в цій групі, наприклад, перший рядок до поточного і другий рядок після поточного, то одержуємо ковзний агрегат, коли розміри вікна фіксовані або нікуди не розширюються, а саме вікно рухається або ковзає.

Розглянемо наступний приклад запиту:

SELECT SecondName, DeptKod, Job, SUM(Salary)

OVER (PARTITION BY DeptKod, Job ORDER BY HireDate ROWS BETWEEN UNBOUNDED PRECEDING

AND CURRENT ROW) sum_sal

FROM Lecturer;

Цей запит має декілька особливостей:

в межах кожної групи за кафедрою та посадою (PARTITION BY) викладачі упорядковуються за часом початку роботи (ORDER BY);

для кожного співробітника в групі (кожного запису в групі) підраховується сума зарплати, його та його попередників в групі (ROWS BETWEEN).

Наступний запит визначає для кожного співробітника накопичувальні витрати

університету після його зарахування на роботу:

SELECT SecondName, HireDate, Salary, SUM(Salary) OVER(ORDER BY HireDate

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) rows_sal, SUM(Salary) OVER(ORDER BY HireDate

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) range_sal FROM Lecturer;

Особливістю цього запиту є різний результат, який повертають функції RANGE та ROWS. Якщо декілька викладачів зараховані на роботу одночасно, сума „по діапазону“ (RANGE) буде відрізнятися від суми „по рядках“ (ROWS), бо RANGE не відрізняє рядки цих викладачів та підсумовує їх зарплати (тобто дає загальну суму по підгрупі), в той час, як ROWS підсумовує витрати для кожного рядка окремо.

SECONDNAME HIREDATE SALARY ROWS_SAL RANGE_SAL

Погорецька

1980-09-01

1000

1000

1000

Востров

1982-09-01

1100

2100

3400

Юхименко

1982-09-01

1300

3400

3400

Чугунов

1985-09-01

1250

4650

4650

Малахов

1990-09-01

1500

6150

6150

У наступному запиті викладачів згруповано по кафедрах, а всередині кожної групи упорядковано за зростанням зарплати. Для кожного рядка отриманої таблиці підраховується середня зарплата трьох викладачів: поточного (тобто самого рядка) та двох попередніх у межах однієї групи (кафедри):

SELECT DeptKod,SecondName, Job, Salary,

ROUND(AVG(Salary) OVER(PARTITION BY DeptKod ORDER BY Salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW )) AS Avg_3

FROM Lecturer;

Результат цього запиту виглядає наступним чином:

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

78

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

DEPTKOD

SECONDNAME

JOB

SALARY

AVG_3

2

Малахов

Зав.каф

1500

1500

2

Чугунов

Доц.

1250

1375

2

Погорецька

Доц.

1000

1250

3

Юхименко

Проф.

1300

1300

4

Востров

Доц.

1100

1100

Тут можна побачити, що у першого і двох останніх рядків таблиці немає ніяких попередніх рядків у межах їхніх груп, тому їхня зарплата — це єдиний елемент, що приймає участь у підрахунку середньої зарплати. Для другого рядка вже є один попередник, і функція AVG підраховується для двох значень. І тільки для третього рядка першої групи (кафедра 2) вікно приймає максимальний розмір, і середня зарплата вираховується для поточного (третього) та двох попередніх викладачів цієї кафедри.

Нижче представлені декілька функцій, призначених для роботи безпосередньо з вікна-

ми.

Функція ROW_NUMBER() повертає номер рядка у вікні для:

створення нумерації, яка відрізняється від порядку сортування рядків результуючого набору;

створення „ненаскрізної“ нумерації, тобто виділення групи із загальної множини рядків та нумерування їх окремо для кожної групи;

використання одночасно кілька способів нумерації, оскільки, фактично, нумерація не залежить від сортування рядків.

Щоб отримати викладачів з порядковим номером слідування зарплати за зростанням та убуванням, можна виконати запит:

SELECT SecondName, Salary,

ROW_NUMBER() OVER ( ORDER BY Salary DESC) AS SalBackNumber, ROW_NUMBER () OVER (ORDER BY Salary) AS SalNumber

FROM Lecturer;

з таким результатом:

SECONDNAME

SALARY

SALBACKNUMBER

SALNUMBER

Погорецька

1000

5

1

Востров

1100

4

2

Чугунов

1250

3

3

Юхименко

1300

2

4

Малахов

1500

1

5

Щоб отримати п’ять викладачів з найбільшою зарплатою, можна виконати запит:

SELECT SecondName, Salary FROM (SELECT SecondName, Salary,

ROW_NUMBER() OVER( ORDER BY Salary DESC) AS R FROM Lecturer) AS T WHERE R <= 5;

Щоб отримати викладачів з порядковим номером рядка за зростанням їх зарплати, який визначається окремо в кожній групі по кафедрі та посаді можна виконати запит:

SELECT ROW_NUMBER()

OVER ( PARTITION BY DeptKod, Job ORDER BY Salary) AS Num, DeptKod, Job, SecondName, Salary

FROM Lecturer;

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

79

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

NUM

DEPTKOD

JOB

SECONDNAME

SALARY

 

 

 

1

2

Доц.

Погорецька

1000

 

 

 

2

2

Доц.

Чугунов

1250

 

 

 

1

2

Зав. каф.

Малахов

1500

 

 

 

1

3

Проф.

Юхименко

1300

 

 

 

1

4

Доц.

Востров

1100

 

 

Отримати по кожній кафедрі двох викладачів з найбільшою зарплатою дозволить наступний запит:

SELECT DeptKod, Job, SecondName, Salary FROM

(SELECT DeptKod, Job, SecondName, Salary, ROW_NUMBER() OVER(PARTITION BY DeptKod ORDER BY Salary DESC) AS R

FROM Lecturer) AS T WHERE R <= 2;

Функція RANK() повертає позицію кожного рядка в секції результуючого набору, яка обчислюється як одиниця плюс кількість рангів, що знаходяться до цього рядка.

Функція DENSE_RANK() повертає позицію кожного рядка в секції результуючого набору без проміжків у ранжируванні, яка обчислюється як кількість різних значень рангів, що передують рядку, збільшена на одиницю, при цьому ранг збільшується при кожній зміні значень виразів, які входять у конструкцію ORDER BY, а рядки з однаковими значеннями одержують той самий ранг.

В наступному запиті наведено приклади використання функцій:

SELECT ROW_NUMBER () OVER (ORDER BY Salary) AS SalNumber,

RANK() OVER (ORDER BY Salary) AS SalRank, DENSE_RANK() OVER (ORDER BY Salary) AS SalDenseRank, DeptKod, Job, SecondName, Salary

FROM Lecturer;

Щоб обрати викладачів з низькою зарплатою, рівень якої знаходиться на четвертому місці, можна виконати запит:

SELECT SecondName, Salary FROM

(SELECT SecondName, Salary, DENSE_RANK() OVER(ORDER BY Salary) AS R FROM Lecturer) T

WHERE R = 4;

Функція PERCENT_RANK() повертає відносну позицію рядка, яка обчислюється по формулі (rank 1)(total _ rows 1), де total_rows — загальна кількість рядків у таб-

лиці.

Функція CUME_DIST() повертає відносну позицію рядка в групі, яка обчислюється по

формулі

(row _ num) (total _ rows), де row_num — кількість рядків, що передують

поточному рядку. Наприклад, у групі із трьох рядків повертаються значення 1/3, 2/3 і 3/3. Функція NTILE(кількість_груп) повертає номер групи, якій належить рядок. При цьому

рядки розподіляються в упорядковані групи заданої потужності.

Щоб обрати викладачів з їх розподілом на п`ять груп, можна виконати запит:

SELECT RANK() OVER (ORDER BY Salary) AS SalRank,

NTILE(5) OVER (ORDER BY Salary) AS SalNTile, SecondName, Salary FROM Lecturer;

Функція LAG(атрибут, [зсув], [значення_за_замовчуванням]) повертає значення атри-

бута рядка, який передує поточному рядку в групі зі зсувом у зворотній бік (за замовчуван-

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

80

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

ням зсув = 1 – посилання на попередній рядок). При цьому повертається значен-

ня_за_замовчуванням, якщо індекс виходить за межі вікна, а також для першого рядка групи.

Функція LEAD(атрибут, [зсув], [значення_за_замовчуванням]) повертає значення ат-

рибута рядка, наступного за поточним рядком у групі зі зсувом у прямий бік (за замовчуван-

ням зсув = 1 – посилання на наступний рядок). При цьому повертається значен-

ня_за_замовчуванням, якщо індекс виходить за межі вікна, а також для останнього рядка групи.

Наприклад, наступний запит для кожного співробітника повертає його зарплату, попередню за розміром зарплату та різницю між ними.

SELECT SecondName, Job, Salary, LAG(CAST(Salary AS INTEGER), 1, 0)

OVER (ORDER BY DeptKod, Salary) AS sal_prev, Salary - LAG(CAST(Salary AS INTEGER), 1, 0)

OVER (ORDER BY DeptKod, Salary) AS sal_diff FROM Lecturer;

Та як в реалізації PostgeSQL функції LAG, LEAD працюють з типом даних INTEGER, в запиті використано оператор перетворення типу CAST.

Якщо необхідно для кожного співробітника порівняти його поточну зарплату, попередню за розміром зарплату та визначити різницю між ними, можна виконати наступний запит:

SELECT SecondName, Job, Salary,

LEAD(CAST(Salary AS INTEGER), 1, 0) OVER (ORDER BY DeptKod, Salary) AS sal_next,

LEAD(CAST(Salary AS INTEGER), 1, 0)

OVER (ORDER BY DeptKod, Salary) - Salary AS sal_diff FROM Lecturer;

Функція FIRST_VALUE(атрибут) повертає перше значення атрибута рядка в групі. Функція LAST_VALUE(атрибут) повертає останнє значення атрибута рядка в групі. Функція NTH_VALUE(атрибут, зсув) повертає перше значення атрибута рядка в групі

із зазначеним зсувом.

В наступному запиті в кожному рядку до інформації про співробітника додається прізвище співробітника з максимальною та мінімальною зарплатою в групі співробітників однієї кафедри.

SELECT SecondName, DeptKod, Job, Salary, FIRST_VALUE(SecondName)

OVER (PARTITION BY DeptKod ORDER BY Salary) AS sal_min, LAST_VALUE(SecondName)

OVER (PARTITION BY DeptKod ORDER BY Salary) AS sal_max FROM Lecturer;

Надалі (див. розділи „Підзапити“, стор. 98, та „Ієрархічні (рекурсивні) запити PostgreSQL“, стор. 100) будуть розглянуті більш складні запити, що використовують аналітичні функції.

Реалізація операцій з’єднання

На відміну від імен полів у представленні, звернутися до вихідних стовпців за їх аліасом неможливо. Цим, до речі, аліаси стовпців відрізняються від аліасів таблиць. Аліас таблиці зручно використовувати, наприклад у тому випадку, коли ім’я таблиці досить довге, але воно необхідно для уточнення імені поля. З усіх попередніх прикладів це неочевидно, тому що в них ми використовували єдину таблицю в кожнім запиті. Для ілюстрації звертання до множини таблиць розглянемо реалізацію ще однієї реляційної операції — з’єднання.

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]