Программирование >>  Руководство по sql 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 105


никакой потребности формировать группы. GROUP BY - в первом запросе - просто ошибка.

Как вы, наверное, помните из предьщуших глав, GROUP BY имеет смысл пользоваться в основном с агрегирующими функциями (в этом случае вы можете находить итоговое значение для каждой группы). Вот как, например, можно было бы найти среднюю цену книг, стоимость которых не превышает $10.00, по типам этих книг:

SQL:

select avg{price), type from titles where price < $10.00 group by type

Результат:

price type

2.99 business

2.99 mod cook

7.50 psychology

Возможно, tot пользователь, который отправил данный вопрос в Internet, представлял себе что-то вроде этого. GROUP BY в данном случае имеет смысл, поскольку в предложении SELECT есть афегирующая функция.

Однако вернемся к первому вопросу: почему все-таки в результатах присутствуют сфоки для книг, цены на которые выше $10.00, в то время как, судя по всему, предложение WHERE должно было бы убрать их?

Если проанализировать результаты первого и второго запросов, а также результаты запроса без предложений GROUP BY и HAVING, то можно, наверное, понять, в чем тут дело. Предложение WHERE нашло сфоки со значениями ниже $10.00. Они включают фи типа книг: business, modcook и psychology. Предложение GROUP BY затем отобразило все книги в каждой из указанных фупп. Если в этот запрос добавить ORDER BY, ситуация прояснится:

SQL:

select price,

type

from titles

where price <

$10.00

group by type

order by type

Результат:

price

type

279 9

business

11.95

business

19.99

business

19.99

business

2.99

mod cook

19.99

mod cook

7.00

psychology

7.99

psychology

10.95

psychology

19.99

psychology

21.59

psychology



Запрос с предложением GROUP BY можно перефразировать как отобрази для меня цены и типы всех книг в группах, содержащих одну или несколько книг с ценами ниже $10.00 . Обратите внимание, что в результатах отсутствуют строки popular comp или trad cook. Нет здесь книг любой из этих групп, которые стоили бы ниже $10.00.

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

Теперь перейдем ко второму вопросу: почему повторение условия WHERE в предложении HAVING исправляет результаты? Во-первых, WHERE находит дешевые книги, а затем GROUP BY вставляет все книги в фуппы, которые содержат одну или несколько дешевых книг. Наконец, HAVING выбирает в этом списке значения ниже $10.00. Поскольку условия WHERE и HAVING идентичны, вы получаете в конце концов те же четыре строки в результате выполнения запроса, содержащего только WHERE, и запроса, содержащего предложения WHERE, GROUP BY и HAVING. Можно было бы сказать, что HAVING в этом конкретном запросе отменяет действие GROUP BY.

Изменение условия в предложении HAVING делает данный процесс более понятным:

SQL:

select price, type

from titles

where price < $10.00

group by type

having price > $20.00

Результат:

price type

21.59 psychology

После того как WHERE классифицирует сфоки, и GROUP BY сформирует Фуппы, HAVING делает завершающий аккорд . Как вы уже видели, WHERE и GROUP BY вместе отображают одиннадцать сфок. HAVING убирает все эти сфо-ки, кроме одной, цена в которой превышает $20.00. Поскольку условия WHERE и HAVING различны, запрос с HAVING находит не те сфоки, которые находит запрос, содержащий только WHERE.

В сущности, если рассмафивать этот конкретный запрос с его необычным использованием GROUP BY, то запрос, содержащий только HAVING, позволяет получить те же результаты, что и запрос, содержащий только WHERE, и даже запрос, содержащий и WHERE, и HAVING.

SQL:

select price, type from titles group by type having price < $10.00

Результат:

price type

2.99 business

2.99 mod cook

7.00 psychology

7.99 psychology



На самом деле ваша реализация может не допускать использования предложения HAVING без GROUP BY. Подробнее об использовании GROUP BY и HAVING вы можете узнать из справочного руководства по вашей системе.

Наилучший способ избежать загадочных результатов, подобных указанным выше, - это тщательно проанализировать, чего именно вы хотите добиться с помощью того или иного запроса. Может оказаться (как в нашем случае), что в использовании GROUP BY нет никакой необходимости.

Сочетание значений строк и агрегирующих функций

Вот еще одна ситуация, связанная с использованием предложений GROUP BY и HAVING. Как вы, наверное, помните, есть ряд строгих ограничений на то, что разрешено помещать в списке выбора в случае использования предложения GROUP BY. Вообще говоря, вы ограничены столбцами, которые вы используете для фуппирования, и столбцами, для которых вы вычисляете групповые итоговые (агрегирующие) значения. В выходных результатах отображается фуппа и итоговое значение для фуппы.

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

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

В качестве отправной точки рассмофим ЬоокЫ1-версию такого запроса в его сокращенном варианте - для нахождения только минимальной цены (итогового значения) по каждому типу книг (фуппе):

SQL:

select type, min(price) as minprice from titles

where type is not null group by type order by type

Результат:

type minprice

popular comp 20.00

trad cook 11.95

business 2.99

psychology 7.00

mod cook 2.99

Распространенным подходом для получения итоговых и сфочных значений является добавление в список выбора неафегируемого столбца, такого как titlejd (уникального для каждой сфоки):

SQL:

select type, min(price) as minprice, title id from titles

where type is not null group by type order by type



1 ... 80 81 82 [ 83 ] 84 85 86 ... 105

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика