Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Авт_ПМП / Metod_BD.doc
Скачиваний:
31
Добавлен:
05.02.2016
Размер:
574.98 Кб
Скачать

Використання фрази having

Фраза HAVING призначена для сумісного використання з фразою GROUP BY для обмеження відбору груп, які відбираються для результуючої таблиці запиту. Хоч фрази HAVING і WHERE мають схожий синтаксис, їх призначення різне. WHERE призначене для фільтрації рядків, які використовуються в тому числі для групування, фраза HAVING призначена для фільтрації груп, які заносяться в результуючу таблицю. На практиці предикат фрази HAVING повинен містить одну з агрегатних функцій. Наприклад, якщо потрібно дізнатись на яку суму закуплено кожного товару, причому сумарна вартість товару не перевищувала б 200 грн., необхідно сформувати такий запит:

SELECT kod,SUM(suma) AS suma_tov

FROM table_a

GROUP BY kod

HAVING SUM(suma)<=200

Результуюча таблиця цього запиту матиме вид:

Kod

Suma_tov

1

195

3

28

Якщо потрібно сформувати список товарів (з включенням в результуючу таблицю коду товару, сумарну вартість цього товару і кількість покупок цього товару), середня вартість покупки товару перевищувала б 50, запит мав би вид:

SELECT kod,SUM(suma) AS suma_tov, COUNT(kod) AS kilkist_pokupok

FROM table_a

GROUP BY kod

HAVING AVG(suma)>50

Результуюча таблиця цього запиту матиме вид:

Kod

Suma_tov

kilkist_pokupok

1

195

3

2

239

2

Якщо ж до попереднього запиту додати умову: покупки здійснювались до 20.01.2002 року, запит матиме вид:

SELECT kod,SUM(suma) AS suma_tov, COUNT(kod) AS kilkist_pokupok

FROM table_a

WHERE data<{d'2002-01-20'}

GROUP BY kod

HAVING AVG(suma)>50

Результуюча таблиця цього запиту матиме вид:

Kod

Suma_tov

kilkist_pokupok

1

195

3

2

150

1

Підзапити

Звернімося до таблиць 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. Текст під запиту потрібно брати в дужки. До підзапитів застосовують такі правила і обмеження.

  1. В підзапитах не повинна використовуватись фраза ORDER BY, хоч вона може використовуватись у зовнішньому запиті.

  2. За змовчуванням імена стовпчиків в підзапиті відносяться до таблиць, які вказані у фразі FROM підзапиту. Разом з тим допускається посилатись і на стовпчики таблиць, які вказані у фразі FROM зовнішнього запиту, для чого використовуються аліаси.

  3. Якщо підзапит є одним з двох операндів оператора зрівнювання, то підзапит повинен вказуватись в правій частині оператора зрівнювання.

  4. Якщо підзапит є одним з двох операндів оператора зрівнювання, то під запит має повертати єдине значення.

Існує три типи підзапитів.

  • Скалярний підзапит – це підзапит, який повертає єдине значення. У вищенаведених прикладах використовувався скалярний підзапит.

  • Строковий підзапит– це підзапит, який повертає значення декількох стовпчиків у вигляді одного рядка.

  • Табличний підзапит - це підзапит, який повертає значення одного або більше стовпчиків таблиці, які розташовані в більш ніж одному рядку. Табличний під запит може використовуватись кругом де допускається вказувати таблицю – наприклад, як операнд предикату IN.

Соседние файлы в папке Авт_ПМП