
Групові функції і функція group by
Групові функції обробляються множиною рядків і повертають, як правило, один результат на групу. По замовчування всі рядки таблиці розглядаються як одна група. Для більш детального групування рядків використовується вираз GROUP BY, який ділить рядки на групи. У раз застосування функції GROUP BY функція SELECT містить стовпці, що ідентифікують групи. Інші стовпці можуть бути використані у функції Select тільки як аргументи агрегатних функцій.
Приклад 23
Задача.
Вести найбільшу, найменшу і середню оцінку для кожного студента.
Рішення.
SELECT P.NRecordBook [№ заліковки],
STname [ім’я студента],
MAX(Mark) [Максимальна оцінка],
MIN(Mark) [Мінимальна оцінка],
AVG(Mark)[Середня оцінка]
FROM Progress P INNER JOIN Student S
ON P.NRecordBook=S.NRecordBook
GROUP BY P.NRecordBook, StName
Для кожної групи буде виведений тільки один рядок.
З функцією GROUP BY можуть бути використані всі інші команди SELECT, наприклад, за допомогою функції WHERE можна виключити рядки, які не повинні приймати участь у запиті, припустимо рядки з ознакою NULL. Розглянемо це на прикладі використання агрегованої функції COUNT(). Функція COUNT() з аргументом відмінним від *, ігнорує рядки з ознакою NULL, в той час як функція виду COUNT(*) порахує всі рядки, в тому числі й ті рядки, в яких є атрибут з ознакою NULL.
SELECT COUNT(*), SUM(Mark), AVG(Mark)
FROM Progress
В наступному випадку COUNT() порахує рядки, в яких оцінка NOT NULL, і функції SUM() та AVG() будуть враховувати тільки ті рядки, в яких оцінка NOT NULL.
SELECT COUNT(Mark), SUM(Mark), AVG(Mark)
FROM Progress
Тут функція COUNT() буде працювати з тими ж рядками, що і функції SUM() та AVG(). Виключити можливі неоднозначності можна, включивши в запит умову відбору рядків: функція WHERE mark IS Not NULL.
SELECT COUNT(*), SUM(Mark), AVG(Mark)
FROM Progress
WHERE Mark IS NOT NULL
Однак використання у функції WHERE агрегованої функції приводить до помилки.
Приклад 24
Задача.
Вивести середню оцінку по кожній студентській групі, якщо середня оцінка вище 3.
Рішення.
SELECT NameGroup, AVG(Mark)[Средняя оценка]
FROM Progress P INNER JOIN Student S
ON P.NRecordBook=S.NRecordBook
INNER JOIN SGroup SG ON S.IDGroup=SG.IDGroup
WHERE AVG(Mark)>3
GROUP BY NameGroup
Результат реалізації запита:
Server: Msg 147
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
Приклад 25
Задача.
Вивести середню оцінку по кожній студентській групі, якщо середня оцінка вище 3. Значення оцінки округляти до однієї десятої.
Решение.
SELECT NameGroup, Round(AVG(Mark),1)[Средняя оценка]
FROM Progress P INNER JOIN Student S
ON P.NRecordBook=S.NRecordBook
INNER JOIN SGroup SG ON S.IDGroup=SG.IDGroup
GROUP BY NameGroup
HAVING AVG(Mark)>3