Группировка записей
Листинг 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)
Секция 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).