Группировка строк (предложение GROUP BY)

В SQL есть возможность разбивать любую таблицу на логические группы и вычислять агрегатные функции не для всей таблицы, а для каждой из этих групп. Для этого и служит предложение GROUP BY.

Синтаксис:

GROUP BY <столбец группировки1>[<, столбец группировки2>][,…]

Пример 35а. Посчитать общую длительность всех вызовов.

SELECT SUM(DLIT)

FROM VYZOVY

Пример 35б. Посчитать общую длительность всех исходящих вызовов (TIP_ID=2).

SELECT SUM(DLIT)

FROM VYZOVY

WHERE TIP_ID=2

Пример 35в. Посчитать общую длительность вызовов каждого типа.

вариант 1 (известны коды)

SELECT TIP_ID, SUM(DLIT)

FROM VYZOVY

GROUP BY TIP_ID

вариант 2 (известны названия)

SELECT T.NAZV, SUM(DLIT)

FROM VYZOVY V, TIPY_VYZ T

WHERE V.TIP_ID=T.ID

GROUP BY T.ID, T.NAZV

Предложение GROUP BY реализуется следующим образом:

- строки исходной таблицы, содержащие одинаковые значения столбца (столбцов) группировки, выделяются в отдельные группы (также создается отдельная группа для строк, в которых в столбце группировки присутствует NULL);

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

Ограничения на запросы с группировкой:

- в качестве столбцов группировки можно использовать только имена столбцов таблиц;

- возвращаемые столбцы в предложении SELECT должны иметь одно значение для каждой группы (это значит, что в качестве возвращаемых столбцов можно использовать агрегатные функции, столбцы группировки, константы, а также выражения, состоящие из перечисленных элементов).

На практике в предложении SELECT запроса с группировкой всегда входят столбец группировки и агрегатная функция. Если агрегатная функция не указана, значит, запрос можно написать без использования предложения GROUP BY (используя ключевое слово DISTINCT). И наоборот, если не включить в результаты запросов столбец группировки, невозможно будет определить, к какой группе относится каждая строка результатов.

Примечание 1. Все столбцы из предложения SELECT, в которых не используются агрегатные функции, должны быть обязательно указаны в предложении GROUP BY!!!

Примечание 2. Группировку лучше осуществлять по первичному ключу.

Пример 36. Вывести количество номеров определенного контакта.

SELECT COUNT(*)

FROM KONTAKTY K, NOMERA N

WHERE (K.ID=N.KONT_ID) AND (K.NAME1='Иванов Александр Сергеевич')

Пример 37. Вывести количество номеров для каждого контакта.

SELECT K.NAME1, COUNT(*)

FROM KONTAKTY K, NOMERA N

WHERE (K.ID=N.KONT_ID)

GROUP BY K.ID, K.NAME1

Пример 38. Вывести количество контактов в каждой группе.

SELECT G.NAZV, COUNT(*)

FROM GRUPPY G, KONT_GR KG

WHERE (G.ID=KG.GR_ID)

GROUP BY G.ID, G.NAZV

Пример 39. Вычислить, со сколькими контактами был зафиксирован каждый тип вызова.

Неправильно (вычисляется количество вызовов, а не количество контактов):

SELECT T.NAZV, COUNT(N.KONT_ID)

FROM TIPY_VYZ T, VYZOVY V, NOMERA N

WHERE (T.ID=V.TIP_ID) AND (V.NOMER_ID=N.ID)

GROUP BY T.ID, T.NAZV

Не работает в Microsoft Access:

SELECT T.NAZV, COUNT(DISTINCT N.KONT_ID)

FROM TIPY_VYZ T, VYZOVY V, NOMERA N

WHERE (T.ID=V.TIP_ID) AND (V.NOMER_ID=N.ID)

GROUP BY T.ID, T.NAZV

Работает в Microsoft Access:

SELECT T1.NAZV, COUNT(T1.KONT_ID)

FROM (SELECT DISTINCT T.NAZV, N.KONT_ID

FROM TIPY_VYZ T, VYZOVY V, NOMERA N

WHERE (T.ID=V.TIP_ID) AND (V.NOMER_ID=N.ID)) AS T1

GROUP BY T1.NAZV

Пример 40. Для каждого контакта вывести дату и время самого первого вызова каждого типа.

SELECT K.NAME1, T.NAZV, MIN(VREMYA) AS FIRST

FROM KONTAKTY K, NOMERA N, VYZOVY V, TIPY_VYZ T

WHERE (T.ID=V.TIP_ID) AND (V.NOMER_ID=N.ID) AND (N.KONT_ID=K.ID)

GROUP BY K.ID, K.NAME1, T.NAZV


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: