Шаг 37 - Вопрос ответ и идем дальше !

Вот тут мне пришло письмо, по прошлому шагу. Очень радует, что уже есть обратная связь с теми для кого мы собственно все это делаем! Во-первых, я допустил ошибку в прошлом шаге, не написав полностью условие в рассматриваемом запросе. Так что давайте разберемся со всем этим! :) Вопрос был такой:

>Домашнее задание от 05.10.03. 
>Разобрать запрос:
> 
>SELECT DESCRIPTION, PRICE, QTY_ON_HAND, SUM(QTY)
>FROM PRODUCTS, ORDERS
>WHERE MFR = MFR_ID       
>GROUP BY MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND
>HAVING SUM(QTY) > (0.75 * QTY_ON_HAND)
>ORDER BY QTY_ON_HAND DESC
>/
>
> 1. Сначала в одну собираются две таблицы PRODUCTS и 
>    ORDERS на основе равенства полей MFR = MFR_ID
> 2. Потом формируются группы по полям MFR_ID, PRODUCT_ID, 
>    DESCRIPTION, PRICE, QTY_ON_HAND и считается сумма поля 
>    QTY для каждой группы.
> 3. После этого исключаются из списка выводимых группы, 
>    в которых SUM(QTY) > (0.75 * QTY_ON_HAND)
> 4. И в конце получившаяся последовательность строк сортируется 
>    по убыванию значения поля QTY_ON_HAND
> 
>Вот вроде всё.. Но есть вопрос... Зачем в ORDER BY стоит PRODUCT_ID? 
>По логике поле DESCRIPTION должно быть уникальным (ведь пользователю 
>не удобно оперировать с кодами). Нельзя ли ORDER BY сократить до 
>DESCRIPTION, PRICE, QTY_ON_HAND?
>Заранее благодарен.

Отвечаю! В принципе концептуально Вы совершенно правы! Правда Вы наверное имели в виду GROUP BY, в своем вопросе. И так же я приведу текст правильной формулировки этого запроса:

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

SELECT DESCRIPTION, PRICE, QTY_ON_HAND, SUM(QTY)
FROM PRODUCTS, ORDERS
WHERE MFR = MFR_ID
	AND PRODUCT = PRODUCT_ID
GROUP BY MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND
HAVING SUM(QTY) > (0.75 * QTY_ON_HAND)
ORDER BY QTY_ON_HAND DESC
/

Я забыл вписать эту строку "AND PRODUCT = PRODUCT_ID"! Вот по этим двум полям дополнительно и указано GROUP BY! Так как по правилам ANSI/ISO необходимо указывать все поля фигурирующие в запросе.

Получаем:

SQL> SELECT DESCRIPTION, PRICE, QTY_ON_HAND, SUM(QTY)
  2  FROM PRODUCTS, ORDERS
  3  WHERE MFR = MFR_ID
  4  	AND PRODUCT = PRODUCT_ID
  5  GROUP BY MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND
  6  HAVING SUM(QTY) > (0.75 * QTY_ON_HAND)
  7  ORDER BY QTY_ON_HAND DESC
  8  /

DESCRIPTION            PRICE   QTY_ON_HAND   SUM(QTY)
-------------------- ------- ------------- ----------
Труба алюминиевая        355            38         32
Карандаш простой          25            37         30
Электродвигатель         243            15         16
Телевизор SAMSUNG       4500            12         15
Осветитель ртутный      1425             5         22

А вообще этот запрос можно записать и так, собственно ничего не изменится:

SELECT DESCRIPTION, PRICE, QTY_ON_HAND, SUM(QTY)
FROM PRODUCTS, ORDERS
WHERE MFR = MFR_ID
	AND PRODUCT = PRODUCT_ID
GROUP BY DESCRIPTION, PRICE, QTY_ON_HAND
HAVING SUM(QTY) > (0.75 * QTY_ON_HAND)
ORDER BY QTY_ON_HAND DESC
/

Получаем:

SQL> SELECT DESCRIPTION, PRICE, QTY_ON_HAND, SUM(QTY)
  2  FROM PRODUCTS, ORDERS
  3  WHERE MFR = MFR_ID
  4  	AND PRODUCT = PRODUCT_ID
  5  GROUP BY DESCRIPTION, PRICE, QTY_ON_HAND
  6  HAVING SUM(QTY) > (0.75 * QTY_ON_HAND)
  7  ORDER BY QTY_ON_HAND DESC
  8  /

DESCRIPTION           PRICE   QTY_ON_HAND   SUM(QTY)
------------------- ------- ------------- ----------
Труба алюминиевая       355            38         32
Карандаш простой         25            37         30
Электродвигатель        243            15         16
Телевизор SAMSUNG      4500            12         15
Осветитель ртутный     1425             5         22

Но в целом для полноты картины не плохо записать GROUP BY, как GROUP BY MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND.

Так вернее синтаксически! Хотя не принципиально! Так что, особой ошибки здесь нет! Но некоторые правила все же стоит соблюдать! Вот собственно, если говорить по большому счету, с SELECT мы более менее разобрались! В следующий раз я думаю, начнем очень серьезную тему а именно PL/SQL! Что является основной тематикой моего раздела. Осталось еще кое-что по вложенным запросам и объединениям таблиц, но я подумал и решил, что оставлю это на рассмотрение в совокупи с PL/SQL! Так будет интереснее и нагляднее! А, так же не будем забывать и о сервере Oracle, в частности администрирование и т.д. И думаю постепенно мы это все одолеем, а путь у нас не близкий!!! :)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Летучий Сергей - 13.10.2003