|
Программирование >> Преобразование значений null
Указывая еще один столбец таблицы EMP, JOB, мы меняем группу и результирующее множество. Таким образом, теперь JOB необходимо включить в оператор GROUP BY вместе с DEPTNO, в противном случае запрос даст сбой. Включение JOB в операторы SELECT/GROUP BY меняет запрос и превращает его из Сколько служащих в каждом отделе? в Сколько разных типов служащих в каждом отделе? . Еще раз обратите внимание на то, что группы уникальны. Значения DEPTNO и JOB по отдельности не уникальны, а вот их сочетания (которые мы видим в списке GROUP BY и SELECT и, таким образом, которые являются группами) уникальны (например, пара 10 и CLERK появляется только один раз). Если в списке оператора SELECT присутствуют только агрегатные функции, в операторе GROUP BY могут быть перечислены любые действительные столбцы. Рассмотрим следующие два запроса, подтверждающие этот факт: Не дайте этому запросу сбить вас с толку. Элементы списка SELECT, не перечисленные в операторе GROUP BY, не оказывают влияния ни на значения CNT для каждого DEPTNO, ни на значения DEPTNO. На основании результатов предыдущего запроса можно более точно сформулировать правило о соответствии элементов списка SELECT и оператора GROUP BY при использовании агрегатов: Элементы списка оператора SELECT, которые потенциально могут изменить группу или значение, возвращаемое агрегатной функцией, должны быть включены в оператор GROUP BY. В предыдущем запросе дополнительные элементы списка оператора SELECT не меняют ни значения CNT любой из групп (для каждого DEPTNO), ни сами группы. Теперь пришло время задать вопрос: а какие именно элементы списка SELECT могут менять группировку или значение, возвращаемое агрегатной функцией? Ответ прост: другие столбцы запрашиваемых(ой) таблиц(ы). Добавим в рассматриваемый запрос столбец JOB: select count(*) from emp group by deptno COUNT(*) select count(*) from emp group by deptno,job COUNT(*) 1 1 1 1 1 1 4 Кроме агрегатных функций в списке оператора SELECT могут быть и другие элементы. Включать их в список не обязательно, но часто это делает результаты запроса более понятными и удобными для использования. Как правило, при использовании GROUP BY и агрегатных функций любые элементы списка оператора SELECT (из таб-лиц(ы), указанных(ой) в операторе FROM), не используемые как аргумент агрегатной функции, должны быть включены в оператор GROUP BY. Однако в MySQL есть возможность отойти от этого правила и размещать в списке SELECT элементы (т. е. столбцы таблиц(ы), из которых(ой) осуществляется выборка), не используемые как аргументы агрегатной функции и не представленные в операторе GROUP BY. Я очень неточно употребляю здесь термин возможность , поскольку это бомба замедленного действия , ошибка, ждущая своего часа, и я советую избегать ее применения. Собственно говоря, если вы работаете с MySQL и крайне беспокоитесь о правильности своих запросов, не используйте эту, гм, возможность . Сегментирование Если ясна концепция группировки и использования агрегатов в SQL, разобраться с оконными функциями просто. Оконные функции, как и агрегатные функции, выполняют агрегацию заданного набора (группы) строк, но вместо того чтобы возвращать по одному значению на Это довольно просто, но часто возникает необходимость получить такие агрегатные данные из строк, которые не входят в данную группировку. Оконные функции упрощают решение подобных задач. Например, следующий запрос показывает, как с помощью оконной функции можно получить агрегатные данные (общее число служащих) из заданных строк (по одной на каждого служащего): select ename, deptno, count(*) over() as cnt from emp
группу, оконные функции могут возвращать несколько значений для каждой группы. Группа строк, подвергающаяся агрегации, - это окно (отсюда название оконные функции ). В DB2 такие функции называют функциями оперативного анализа данных (online analytic processing, OLAP), а в Oracle - аналитическими функциями, но стандарт ISO SQL называет их оконными функциями, поэтому в книге я использую именно этот термин. Простой пример Скажем, требуется подсчитать общее число служащих во всех отделах. Традиционно для этого используется запрос с функцией COUNT(*) ко всей таблице EMP: select count(*) as cnt from emp
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |