Группировка записей
Секция GROUP BY представляет чрезвычайно мощную концепцию SQL – агрегирование. На практике агрегирование запросов SQL приводит к тому, что все записи с одинаковыми значениями выражения, заданного в секции GROUP BY, группируются в одну агрегатную запись. Выражение GROUP BY может быть простым полем таблицы, но оно также может представлять собой произвольную операцию с полем. При перечислении нескольких полей или выражений, разделенных запятыми, группировка записей осуществляется лишь при совпадении записей по всем критериям.
Чтобы эффективно пользоваться агрегированием, необходимо понимать, что все целевые поля, участвующие в агрегирующем запросе, но не указанные в секции GROUP BY, доступны лишь при выборке через агрегатную функцию. Агрегатная функция получает имя поля (или выражение, в котором участвует хотя бы одно имя поля), представляющее несколько значений (например, в нескольких сгруппированных записях), выполняет с ними некоторую операцию и возвращает одно значение.
Самые распространенные агрегатные функции:
- count () – возвращает количество записей в наборе;
- mах () – возвращает максимальное значение в наборе;
- min () – возвращает минимальное значение в наборе.
Агрегатные функции работают только с записями итогового набора, поэтому они выполняются после обработки всех условных объединений и секций WHERE.
Предположим, вы хотите вывести количество книг, хранящихся в базе данных booktown для каждого издательства. Название издательства связывается с названиями опубликованных книг простым объединением таблиц editions и publishers, однако подсчитывать записи вручную весьма утомительно, а при очень больших объемах итоговых наборов – вообще неприемлемо.
В листинге 4.40 выполняется стандартное объединение двух таблиц базы данных booktown, но в нем присутствуют два новых элемента: вызов функции count () и секция GROUP BY.
Листинг 4.40. Группировка записей.
booktown=# SELECT count(e.isbn) AS "number of books", booktown-# p.name AS publisher booktown-# FROM editions AS e INNER JOIN publishers AS p booktown-# ON (e.publisher_id = p.id) booktown-# GROUP BY p.name; number of books | publisher 2 | Ace Books 1 | Books of Wonder 2 | Doubleday 1 | HarperCollins 1 | Henry Holt & Company. Inc. 1 | Kids Can Press 1 | Mojo Press 1 | O'Reilly & Associates 1 | Penguin 3 | Random House 2 | Roc 1 | Watson-Guptill Publications (12 rows)