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