
- •1. Введение
- •2 Создание базы данных
- •2.1 Реляционные базы данных
- •2.2 Определение таблиц, домены.
- •3 Извлечение данных
- •3.1 Извлечение информации из одной таблицы.
- •3.2 Группировка данных и агрегатные функции.
- •3.3 Соединение таблиц
- •3.6 Представления
- •4.1 Изменение данных основных таблиц.
- •4.2 Изменение данных представлений.
3.2 Группировка данных и агрегатные функции.
Теперь рассмотрим возможности SQL по обработке табличных данных. Один из основных способов анализа данных связан с использованием инструкции group by в операторе select:
select ...
from . . .
[where . . . ]
group by <список группировке>
[order by . . .]
Список группировки является списком полей, разделенных запятыми. Семантика оператора group by такая: все строки объединяются в несколько групп таким образом, что каждую группу образуют строки, у которых значения всех столбцов их списка группировки совпадают. Затем из каждой группы формируется одна строка.
Например, если в операторе select присутствует инструкция вида
select l_name ...
group by l_name ...
то в результате выполнения этого оператора мы получим множество строк, в котором разные строки будут иметь различные значения поля l_name.
Из описанной семантики group by следует, в списке выбираемых полей после select нельзя использовать поля, не входящие в список группировки. В самом деле, если написать
select l_name, f_name
from student
group by l_name
то непонятно, чему должно быть равно значение второго столбца. В таблице есть два Ивановых, и значение f _name может быть равно и 'Иван', и 'Александр'.
Для того, чтобы из каждой группы выбрать одно значение для какого либо поля или сгенерировать новое значение, используются агрегатные функции: max — для выбора максимального значения, min — минимального, avg — среднего арифметического в группе, sum - для нахождения суммы в группе. Последние две функции могут использоваться только для столбцов числового типа. Еще одна агрегатная функция - count (*) - предназначена для подсчета количества строк в группе.
Рассмотрим несколько примеров.
Пример 20
select gr_nomer, count(*) as gr_count
from student
group by gr_nomer
gr nomer |
fr count |
11 |
2 |
12 |
3 |
13 |
1 |
В результате выполнения данного оператора будет, получен набор строк, каждая из которых будет содержать два поля: первое — номер группы, второе — количество студентов в этой группе.
Пример 21
select gr_nomer, min(nomer) as min_nomer,
max(nomer) as max_nomer
from student
group by gr_nomer
gr nomer |
min nomer |
max nomer |
11 |
010001 |
010002 |
12 |
011003 |
011005 |
13 |
011101 |
011101 |
Этот оператор для каждой группы вычисляет минимальный и максимальный номера студенческих билетов студентов из этой группы.
Заметим, что столбцы, формируемые с помощью агрегатных функций, не имеют имени, поэтому обычно им требуется явно присваивать имя при помощи as.
Пример 22
select dis, avg(res) as res
from ball
group by dis
Будем считать, что таблица ball заполнена следующим образом:
stud nomer |
dis |
dat |
form |
res |
010001 |
Алгебра |
04.01.2004 |
Зачет |
100 |
010001 |
Анализ |
08.01.2004 |
Экзамен |
80 |
010001 |
Информатика |
Ц.01.2004 |
Экзамен |
75 |
010002 |
Алгебра |
04-01.2004 |
Зачет |
50 |
010002 |
Анализ |
08.01.20 04 |
Экзамен |
10 |
010002 |
Инфюрматика |
Ц.01.2004 |
Экзамен |
80 |
011003 |
Алгебра |
09.01.2004 |
Экзамен |
30 |
011003 |
Анализ |
04.01.2004 |
Экзамен |
10 |
011003 |
Инфюрматика |
i4.Ol.2OO4 |
Зачет |
90 |
01Ю04 |
Алгебра |
09.01.2004 |
Экзамен |
60 |
01Ю04 |
Анализ |
04-01.2004 |
Экзамен |
60 |
01Ю04 |
Информатика |
Ц.01.2004 |
Зачет. |
10 |
011005 |
Алгебра |
09.01.2004 |
Экзамен |
80 |
011005 |
Анализ |
04.01.2004 |
Экзамен |
10 |
011005 |
Информатика |
14-01.2004 |
Зачет |
80 |
Тогда приведенный оператор выдаст
dis |
res |
Алгебра |
64 |
Анализ |
10 |
Информатика |
19 |
Этот, оператор для каждой дисциплины вычисляет средний балл, полученный при ее сдаче. Того же можно добиться, записав:
select dis, sum(res) / count(*) as res
from ball
group by dis
Результат будет, тем, же самым, здесь только явно записан способ вычисления среднего арифметического: вычислить сумму и разделить на количество слагаемых.
Задача 29 (Супермаркет) Найти какое количество различных товаров каждого производителя имеется в продаже.
Задача 30 (Супермаркет) Найти, сколько различных товаров каждого вида имеется в продаже.
Задача 31 (Супермаркет) Найти среднюю цену для каждого вида товаров.
Задача 32 (Супермаркет) Найти общее количество единиц товара каждого вида из имеющихся в магазине.
Задача 33 (Супермаркет) Найти наименьшую и наибольшую цены для каждого вида товара.
Инструкции group by и where можно использовать вместе. В этом случае сначала осуществляется отбор строк при помощи where, а затем - группировка.
Пример 23 Например, если мы хотим получить средний балл по каждой дисциплине, полученный при сдаче экзаменов, то следует, написать:
select dis, avg(res) as res
from ball
where form='Экзамен’
group by dis
При выполнении этого оператора сначала будут отобраны строки, в которых значение поля form равняется ‘Экзамен’, а потом среднее арифметическое будет вычисляться только среди значений поля res в этих строках.
dis |
res |
Алгебра |
56,6666 |
Анализ |
70 |
Информатика |
77,5 |
Если бы по каким-то дисциплинам экзамены вообще не проводились, то они вообще не попали бы в результирующий набор. На этом примере видно, что в инструкции where можно использовать имена тех столбцов, по которым группировка не проводиться (в нашем случае — form). Это как раз и связано с тем, что фильтрация строк в where осуществляется до группировки.
Задача 34 (Супермаркет) Найти среднюю цепу товаров фирмы «Рога и копыта» из имеющихся в продаже.
Задача 35 (Супермаркет) Найти количество каждого товара, имеющего цену от 1000 до 10000.
Агрегатные функции можно использовать, даже если инструкции group by в операторе select нет. В этом случае считается, что все строки образуют одну группу.
Пример 24 Например, оператор
select max(nomer) as max_nomer
from student
вернет таблицу
-
тах_ потеr
011101
выбрав максимальный номер студенческого билета из всех, содержащихся в таблице student.
Пример 25 Точно так же оператор
select avg(res) as res
from ball where form = 'Экзамен'
подсчитает среднее количество баллов набираемых студентами в ходе сдачи экзаменов:
-
res
67
Результатом в обоих примерах является одна строка.
Задача 36 (Супермаркет) Найти среднюю цену товара в магазине.
Задача 37 (Библиотека) Найти общее количество книг в библиотеке.
Задача 38 (Супермаркет) Найти наименьшую и наибольшую цены товара в магазине.
Как мы уже сказали, отбор строк с помощью инструкции where осуществляется до формирования групп. Для того, чтобы отбросить ненужные строки после группировки, используется инструкция having:
select ...
from ...
[where ...]
group by . . .
having <условие>
[order by ... ]
Поскольку having выполняется после формирования групп, то в условии после having можно использовать агрегатные функции, но нельзя использовать столбцы, не вошедшие в список группировки.
Пример 26 Например, чтобы вывести средний балл по дисциплинам,, для которых максимальный балл, полученный когда-либо, равен 100, следует выполнить
select dis, avg(res)
from ball
group by dis
having max(res) = 100
Результат:
dis |
|
Алгебра |
64 |
Сортировка результата выполняется тоже после группировки, поэтому в списке сортировки можно использовать агрегатные функции, но нельзя столбцы, не участвующие в группировке.
Пример 27 Например, можно вывести номера групп в порядке убывания их численности:
select gr_nomer, count(*) as cnt
from student
group by gr_nomer
order by count(*) DESC
gr nomer |
cnt |
12 |
3 |
11 |
2 |
13 |
1 |
Задача 39 (Супермаркет) Найти среднюю цену каждого из видов товаров, общее количество единиц которого в магазине превосходит 1000. Результат отсортировать по количеству единиц, т,овара по убыванию.
Задача 40 (Супермаркет) Найти максимальную и минимальную
цену каждого из видов товаров, средняя цена которых лежит в диапазоне от 100 до 200. Результат отсортировать по количеству единиц товара по возрастанию.
Задача 41 (Супермаркет) Найти общее количество различных товаров фирм, в названии которых есть слово «молоко», и средняя цена продукции которых не превосходит 10. Результат отсортировать по названию фирмы.
Задача 42 (Супермаркет) Найтм максимальную и минимальную цену товаров каждой фирмы, общее количество единиц товаров которых не, меньше 10000. результат отсортировать по средней цене товаров фирмы.