Вывести имена и фамилии менеджер(ов), продавшего товаров в январе 2016 года на наибольшую сумму Построение 1.Построим таблицу из id - менеджеров и их суммарных продаж за указанный в условии период select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id 2.Обернем эту таблицу именем tmp (select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id) tmp 3.Построим запрос следующего уровня с использованием "обертки" select manager.manager_first_name, manager.manager_last_name, tmp.itogo from manager, (select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id) tmp where tmp.mid = manager.manager_id and tmp.itogo = ...... 4.Разберемся с max: -- Написать max(tmp.itogo) в заголовке и применить group by - нельзя, так как группировка по таблице tmp дает ошибку из-за ее фактического отсутствия -- Дописать ... and tmp.itogo = (select max(itogo) from tmp) в предложение where -тоже нельзя, так как это уже новый запрос с неизвестной таблицей tmp -- Остается вариант скопировать весь запрос (см. п.1) в предложение from, получается select manager.manager_first_name, manager.manager_last_name, tmp.itogo from manager, (select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id) tmp where tmp.mid = manager.manager_id and tmp.itogo = (select max(itogo) from (select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id) tmp ); .. и, несмотря на громозскость конструкции, это работает и выдает верный результат >> Rachel Wallace 176198,95 <<< 5.Теперь о возможных ошибках: -- Показать ошибочный результат группировки по атрибуту manager_first_name -- Показать правильный результат с группировкой по двум атрибутам (manger_first_name,manager_last_name) и подчеркнуть, что правильный результат получился только из-за того, что в базе данных нет полных тезок 6.Более красивый вариант запроса может быть реализован с помощью так называемых временных представлений Синтаксис конструкции WITH в Oracle WITH имя_представления (параметры) AS ( запрос(ы) именование) SELECT ..... from представление WHERE предикат Особенности использования: 1) Используется только с инструкциями SELECT. 2) Именование запроса - глобальное включая блоки его подзапросов). 3) Если именование запроса совпадает с именем существующей таблицы, синтаксический анализатор производит поиск изнутри наружу, а имя блока запроса имеет приоритет над именем таблицы. 4) Предложение WITH может содержать более одного запроса. В этом случае каждый запрос отделяется запятой В нашем примере исходный запрос оборачивается не локальным именованием, а временным представлением with tmp as (select m.manager_id mid, sum(l.product_qty*l.product_price) itogo from sales_order_line l, sales_order o, manager m where m.manager_id = o.manager_id and o.sales_order_id = l.sales_order_id and o.order_date between '01.01.2016' and '31.01.2016' group by m.manager_id) select m.manager_first_name MFN, m.manager_last_name MLN, tmp.itogo from manager m join tmp on m.manager_id = tmp.mid where tmp.itogo = (select max(tmp.itogo) from tmp); >> Rachel Wallace 176198,95 <<<