Итак, наконец, одно из направлений, а именно однотабличные запросы, мы, наконец, закончили! Теперь давайте подведем маленький итог и сформулируем правила выполнения однотабличных запросов. В принципе такой тип запросов легко читаем, достаточно внимательно посмотреть на оператор SELECT и, как правило, становиться все ясно, тем не менее, давайте опишем все сухими постулатами! Иногда это полезно! Итак:
Вот в принципе такие правила, может быть витиевато, но на то они и правила. Если вы будете их придерживаться, то все будет замечательно и проблем не возникнет!!! :) Прежде чем начинать новую тему, давайте рассмотрим, оператор UNION, он позволяет объеденить результаты двух запросов. Тем более что, как раз он и предварит тему многотабличных запросов. Сказать честно, я за всю свою практику такую систему объеденения двух SELECT'ов не применял, хотя может кому-то это и нужно! :)))
Давайте рассмотрим для начала два простых запроса, первый: Вывести список всех товаров, цены которых превышают $500.
SQL> SELECT MFR_ID, PRODUCT_ID 2 FROM PRODUCTS 3 WHERE PRICE > 500.00 4 / MFR PRODU --- ----- IMM 779C BIC 41003 REI 2A44L IMM 775C ACI 4100Z REI 2A44R IMM 773C 7 строк выбрано.
Получаем следующее. 7 строк и два столбца.
А теперь второй запрос: Вывести список всех товаров, которых было заказано более чем $4.0 за один раз.
SQL> SELECT DISTINCT MFR, PRODUCT 2 FROM ORDERS 3 WHERE AMOUNT > 4.00 4 / MFR PRODU --- ----- ACI 41002 ACI 41004 ACI 4100X ACI 4100Y ACI 4100Z BIC 41003 IMM 775C IMM 779C QSA XK47 REI 2A44L REI 2A44R REI 2A45C 12 строк выбрано.
Получаем 12 строк и два столбца.
А вот теперь применим UNION! Вывести список всех товаров, цены которых превышают $500 или которых было заказано более чем $4.0 за один раз.
SQL> SELECT MFR_ID, PRODUCT_ID 2 FROM PRODUCTS 3 WHERE PRICE > 500.00 4 UNION 5 SELECT DISTINCT MFR, PRODUCT 6 FROM ORDERS 7 WHERE AMOUNT > 4.00 8 / MFR PRODU --- ----- ACI 41002 ACI 41004 ACI 4100X ACI 4100Y ACI 4100Z BIC 41003 IMM 773C IMM 775C IMM 779C QSA XK47 REI 2A44L REI 2A44R REI 2A45C 13 строк выбрано.
Интересно, правда, 13 строк и два столбца, а почему их не 19ть? Ведь один из запросов вернул, 7мь, а второй 12ть! Вот в этом и есть объединение, посмотрите внимательнее на значения в первом и втором запросе:
MFR PRODU --- ----- IMM 779C BIC 41003 REI 2A44L IMM 775C ACI 4100Z REI 2A44R IMM 773C MFR PRODU --- ----- ACI 41002 ACI 41004 ACI 4100X ACI 4100Y ACI 4100Z BIC 41003 IMM 775C IMM 779C QSA XK47 REI 2A44L REI 2A44R REI 2A45C
Правда, много похожего, а объедененый не стал повторяться, а просто показал 13ть строк, вот и все! При таком запросе возвращаемые столбцы, если они повторяются, то повторяющиеся столбцы просто отбрасываются. Так как при действии предложения DISTINCT хотя в одном из запросов он присутствует явно! Главное, чтобы запросы содержали одинаковое количество столбцов и тип столбцов в обоих запросах был одинаковый! И еще ORDER BY в таких запросах не применяется! А вот если, все таки нужно вернуть все строки объедененного запроса, то просто укажите ALL после оператора UNION:
SQL> SELECT MFR_ID, PRODUCT_ID 2 FROM PRODUCTS 3 WHERE PRICE > 500.00 4 UNION ALL 5 SELECT DISTINCT MFR, PRODUCT 6 FROM ORDERS 7 WHERE AMOUNT > 4.00 8 / MFR PRODU --- ----- IMM 779C BIC 41003 REI 2A44L IMM 775C ACI 4100Z REI 2A44R IMM 773C ACI 41002 ACI 41004 ACI 4100X ACI 4100Y ACI 4100Z BIC 41003 IMM 775C IMM 779C QSA XK47 REI 2A44L REI 2A44R REI 2A45C 19 строк выбрано.
Оп! Вот и все 19ть строк! Что и требовалось! Теперь надеюсь стало понятно. Единственное скажу, что удаление повторяющихся строк, в таких запросах, занимает много времени, так как эти типы запросов ресурсоемки! :) Хоть я и говорил, что ORDER BY не используют, можно в принципе, попробовать следующее:
SQL> SELECT MFR_ID, PRODUCT_ID 2 FROM PRODUCTS 3 WHERE PRICE > 500.00 4 UNION ALL 5 SELECT DISTINCT MFR, PRODUCT 6 FROM ORDERS 7 WHERE AMOUNT > 4.00 8 ORDER BY 1,2 9 / MFR PRODU --- ----- ACI 4100X ACI 4100Y ACI 4100Z ACI 4100Z ACI 41002 ACI 41004 BIC 41003 BIC 41003 IMM 773C IMM 775C IMM 775C IMM 779C IMM 779C QSA XK47 REI 2A44L REI 2A44L REI 2A44R REI 2A44R REI 2A45C 19 строк выбрано.
Ух, ты! Сработало! Только имена столбцов не используйте, так как может возникнуть путаница! Лучше их порядковые номера! Вот такие примеры! :) Так же можно писать многократные запросы на обьеденение:
Например:
SELECT * FROM A UNION (SELECT * FROM B UNION SELECT * FROM C) ------- Вася Петя Коля Маша 4 строки выбрано.
Скобки показывают какой оператор UNION должен выполниться первым. Так же независимо от того исключаются повторяющиеся строки или нет, выражения например такого типа полностью эквивалентны:
A UNION (B UNION C) (A UNION B) UNION C (A UNION C) UNION B
Если применять предложение ALL, то следующий тип обьеденения, так же одно и то же!
A UNION ALL (B UNION ALL C) (A UNION ALL B) UNION ALL C (A UNION ALL C) UNION ALL B
Если вы применяете и UNION и UNION ALL, то выражение типа:
A UNION ALL B UNION C
Переписать как:
A UNION ALL (B UNION C) или (A UNION ALL B) UNION C
То результаты таких запросов будут РАЗЛИЧНЫ!!!
Не путайтесь, в таких случаях и, применяя такие выражения, четко представляйте себе, чего вы хотите получить! Собственно вот такие дела, пробуйте еще раз все самостоятельно и усваивайте материал! :)))