ОГРАНИЧЕНИЯ НА ЗАПРОСЫ С ГРУППИРОВКОЙ

НЕСКОЛЬКО СТОЛБЦОВ ГРУППИРОВКИ

SQL позволяет группировать результаты запроса на основании двух или более столбцов. Например, предположим, что вам требуется сгруппировать заказы по служащим и клиентам. Эту задачу выполняет запрос, приведенный ниже:

Можно отсортировать данные таким образом, чтобы строки в таблице результатов запроса шли в нужном порядке. Во многих реализациях SQL при использовании предложения group by сортировка выполняется автоматически, однако автоматический порядок сортировки можно изменить с помощью предложения order by, как показано ниже:

С помощью одного запроса невозможно получить как детальные, так и промежуточные итоговые результаты. Чтобы получить детальные результаты с итогами по группам, необходимо с помощью программного SQL написать прикладную программу и вычислить промежуточные итоговые результаты в программе. В SQL Server это ограничение стандартного SQL устраняется с помощью дополнительного предложения compute, которое добавляется в конец оператора select. Предложение compute обеспечивает получение промежуточных и общих итогов, как показано в следующем примере:

Приведенный выше запрос генерирует обычные результаты, содержащие одну строку для каждой строки таблицы orders и отсортированные по столбцам rep и cust. Кроме того, он вычисляет сумму заказов для каждой пары клиент/служащий (промежуточный итог нижнего уровня) и вычисляет сумму заказов и среднюю стоимость заказа для каждого служащего (промежуточный итог верхнего уровня). Таким образом, результаты запроса содержат смесь нормальных строк и итоговых строк двух уровней.

Предложение compute не вписывается ни в какие стандарты. Более того, оно нарушает основные правила построения реляционных запросов, поскольку результаты оператора select, в котором используется это предложение, являются не таблицей, а странной комбинацией строк различного типа. Но тем не менее, как показывает пример, оно может быть весьма полезным.

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

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

константа,

• агрегатная функция, возвращающая одно значение для всех строк, входящих в группу;

столбец группировки, который, по определению, имеет одно и то же значение во всех строках группы;

выражение, включающее в себя перечисленные выше элементы.

На практике в список возвращаемых столбцов запроса с группировкой всегда входят столбец группировки и агрегатная функция. Если последняя не указана, значит, запрос можно более просто выразить с помощью ключевого слова distinct без использования предложения group by. И наоборот, если не включить в результаты запроса столбец группировки, вы не сможете определить, к какой группе относится каждая строка результатов!

Еще одно ограничение запросов с группировкой обусловлено тем, что в SQL игнорируется информация о первичных и внешних ключах при анализе правильности запроса с группировкой. Рассмотрим следующий запрос:

Зная природу данных, можно сказать, что запрос правильный, поскольку группировка по идентификатору служащего — фактически то же самое, что и группировка по имени служащего. Говоря более точно, столбец группировки empl_num является первичным ключом таблицы salesreps, поэтому столбец name должен иметь одно значение для каждой группы. Тем не менее выдается сообщение об ошибке, поскольку столбец name не указан в качестве столбца группировки. Чтобы решить эту проблему, необходимо просто включить этот столбец в предложение group by:

Конечно, если идентификатор служащего в результатах запроса не требуется, можно вообще исключить его из списка возвращаемых столбцов: