Иллюстрированный самоучитель по PostgreSQL

Группировка записей

Секция GROUP BY в листинге 4.40 указывает PostgreSQL на то, что записи объединенного набора данных должны группироваться по имени р .name, которое в данном запросе является ссылкой на имя name таблицы publishers. Все записи с одинаковым названием издательства группируются, после чего функция count() подсчитывает в каждой группе количество значений isbn из таблицы editions и возвращает результат – количество записей, объединенных в каждую группу для одного издательства.

Учтите, что в листинге 4.40 аргумент (поле isbn таблицы editions) функции count () был выбран только для того, чтобы дать наглядное представление о смысле команды (подсчет количества книг для одного издателя). Его можно было заменить любым другим полем, поскольку функция count() всегда возвращает количество записей в текущей агрегатной группе.

При проектировании агрегатных запросов следует помнить, что секция WHERE не может содержать агрегатных функций, поэтому вместо нее следует использовать секцию HAVING. Секция HAVING работает аналогично секции WHERE, но ее условия должны быть основаны на агрегатных функциях, а не на условиях для отдельных записей. С точки зрения синтаксиса секция HAVING должна следовать за секцией GROUP BY (листинг 4.41).

Листинг 4.41. Использование секции HAVING.

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 publisher
booktown-# HAVING count(e.isbn) > 1;
number of books | publisher
2 | Ace Books
2 | Doubleday
3 | Random House
2 | Roc
(4 rows)

В листингах 4.40 и 4.41 набор данных создается внутренним объединением таблиц editions и publishers, однако листинг 4.41 ограничивает результат теми издательствами, которые представлены в базе данных booktown двумя и более книгами. Задача решается при помощи секции HAVING.

Примечание
Если поле итогового набора связывается ключевым словом AS с синонимом, совпадающим с именем существующего поля в одном из исходных наборов данных, то при использовании этого имени в секции GROUP BY PostgreSQL предполагает, что имя относится к исходному полю, а не к синониму
.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.