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

Вы можете авторизоваться на сайте всего одним кликом:

2016-07-08
SQL → Группирование результатов
Как получить количество уникальных записей в таблице

Предположим, что Вы захотели вывести список авторов и количество принадлежа­ щих им материалов...

Группирование результатов

В предыдущих уроках, чтобы узнать, сколько материалов хранится в таблице material, вы использовали следующий запрос:

SELECT COUNT(*) FROM material

Функция COUNT принадлежит к особому виду функций, которые называются агрегирующими, или функциями группирования. Их полный список приведен в руководстве по MySQL (http://dev.mysql.com/doc/mysql/en/group-by-functions.html). В отличие от других функций, которые работают с отдельными записями, полученными при выполнении команды SELECT, они груп­ пируют все результаты и возвращают единый ответ. В вышеприведенном примере функция COUNT возвращает общее количество полученных строк.

Группирование результатов

Предположим, вы захотели вывести список авторов и количество принадлежа­щих им материалов. Скорее всего, первое, что придет вам в голову, — это извлечь имена и идентификаторы всех авторов, получить списки всех материалов для каждого авто­ра, используя соответствующие id, а затем применить к полученным результатам функцию COUNT. Вот как примерно выглядел бы ваш PHP -код (для упрощения записи обработка ошибок не использовалась):

// Получаем список всех авторов.
$result = $pdo->query('SELECT id, name FROM author1);

// Считываем всех авторов,
foreach ($result as $row)
   {
      $authors[] = array(
      'id' => $row['id'],
      'name' => $row['name']
   ) ;
}

// Получаем количество материалов, принадлежащих автору.
$sql = 'SELECT COUNT(*) AS nummaterial FROM material WHERE authorid = :id';
$s = $pdo->prepare($sql);

// Перебираем список авторов,
foreach ($authors as $author)
{
   $s->bindValue(':id 1, $author['id']);
   $s->execute();
   $row = $s->fetch();
   $nummaterial = $row['nummaterial'];

   // Выводим имя автора и количество материалов.
   $output .= htmlspecialchars($author['name'], ENT_QUOTES, 'UTF-8'). " ($nummaterial material)<br>";
}

Обратите внимание, что во втором запросе использовалось ключевое слово AS, которое позволило дать понятное имя результатам вычисления COUNT ( * ) .

Код сработает, но повлечет выполнение п + 1 дополнительных запросов, где п — количество авторов в базе данных. Зависимости между количеством запро­сов и записей в базе данных всегда лучше избегать, поскольку, если авторов будет огромное множество, ваш скрипт станет медленно работать и окажется требователен к ресурсам. Здесь пригодится еще одна особенность оператора SELECT.

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

SELECT author.name, COUNT(*) AS nummaterial
FROM material INNER JOIN author
   ON authorid = author.id
GROUP BY authorid

Тот же результат можно получить, если использовать в запросе выражение GROUP BY author.id (при условии, что столбцы, указанные в операторе FROM совпадают). Выражение GROUP BY author.name в большинстве случаев тоже сработает. Однако существует вероятность (хоть и небольшая), что у двух разных авторов имена одинаковы, и их значения сольются в один результат. Учитывая эту особенность, лучше привязываться к столбцам с идентификаторами, уникальность которых для каждого автора гарантирована.

447
0
Пожалуйста, авторизируйтесь, чтобы скачать архив с файлами урока