logo search
Книга по БД(Вальке А

5.5.1. Поиск по нескольким таблицам

Оператор SELECT может осуществлять поиск сразу по нескольким таблицам. В этом случае после слова FROM в операторе SELECT надо указать таблицы,по которым производится поиск. Если в нескольких полях имеются одноименные поля (например, поле name присутсвует и в таблице companies, и в таблице items), то для устранения неясностей надо перед именем поля указать имя таблицы и символ точка.

Например, если мы хотим получить список всех людей, информация о которых есть в базе, вместе с названием фирмы, в которой они работают, то надо выполнить запрос

SELECT name, address, lname, fname FROM companies, persons WHERE company_id = company

В данном примере не возникает коллизий и запрос будет правильно отработан. Но если мы захотим выдать список товаров и названий фирм, их производящих, то, так как поле name присутствует и в таблице items, и в таблице companies, нам потребуется для поля name указывать таблицу:

SELECT items.name, companies.name FROM persons, companies WHERE company = company_id

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

Стоит обратить внимание, что при выборке из двух таблиц мы получаем все возможные комбинации значений, при этом из всех таблиц выбираются только те записи, которые удовлетворяют заданному условию. Например, в приведенном выше примере на получение информации о фирмах и людях, в них работающих, мы получим список только тех компаний, для которых в таблице persons есть хотя бы один человек. А если мы хотим в этом запросе получить информацию и о фирмах, для которых мы не знаем ни одного сотрудника? Для этого в разделе FROM оператора SELECT перед таблицей persons надо поставить слово OUTER:

SELECT name, address, lname, fname FROM companies, OUTER persons WHERE company_id = company

Тогда такой оператор будет работать следующим образом. Он последовательно будет перебирать все записи из таблицы companies. Для каждой записи из companies будет просмотрена таблица persons. Как только будет найдена запись из persons, удосвлетворяющая условию WHERE, в результат добавится новый ряд, сформированный из полей name и address записи из companies и полей lname и fname записи из persons. Если же в persons не будет найдено ни одной записи, то при простом операторе SELECT информация о текущей записи из companies в результат не попадет, а в случае SELECT с OUTER - попадет, а поля lname и fname получат значение NULL:

Таблица companies: -------------T----------------------T------------------¬ ¦ company_id ¦ name ¦ address ¦ +------------+----------------------+------------------+ ¦ 101 ¦ АО Рога и Копыта ¦ Одесса, п/я 13 ¦ ¦ 105 ¦ ТОО Добро пожаловать ¦ Энск, 5-е авеню ¦ ¦ 107 ¦ АОЗТ Сделай сам ¦ Городская свалка ¦ L------------+----------------------+-------------------

Таблица persons: ----------T----------T---------¬ ¦ company ¦ lname ¦ fname ¦ +---------+----------+---------+ ¦ 101 ¦ Антонов ¦ Сергей ¦ ¦ 105 ¦ Шапокляк ¦ Алексей ¦ ¦ 102 ¦ Антонов ¦ Антон ¦ ¦ 101 ¦ Бендер ¦ Остап ¦ L---------+----------+----------

Результат простого оператора SELECT

SELECT name, address, lname, fname FROM companies, persons WHERE company_id = company

-----------------------T-----------------T----------T---------¬ ¦ name ¦ address ¦ lname ¦ fname ¦ +----------------------+-----------------+----------+---------+ ¦ АО Рога и Копыта ¦ Одесса, п/я 13 ¦ Антонов ¦ Сергей ¦ ¦ АО Рога и Копыта ¦ Одесса, п/я 13 ¦ Бендер ¦ Остап ¦ ¦ ТОО Добро пожаловать ¦ Энск, 5-е авеню ¦ Шапокляк ¦ Алексей ¦ L----------------------+-----------------+----------+----------

Результат оператора SELECT с указателем OUTER

SELECT name, address, lname, fname FROM companies, OUTER persons WHERE company_id = company

-----------------------T-----------------T----------T---------¬ ¦ name ¦ address ¦ lname ¦ fname ¦ +----------------------+-----------------+----------+---------+ ¦ АО Рога и Копыта ¦ Одесса, п/я 13 ¦ Антонов ¦ Сергей ¦ ¦ АО Рога и Копыта ¦ Одесса, п/я 13 ¦ Бендер ¦ Остап ¦ ¦ ТОО Добро пожаловать ¦ Энск, 5-е авеню ¦ Шапокляк ¦ Алексей ¦ ¦ АОЗТ Сделай сам ¦ Городская свалка¦ NULL ¦ NULL ¦ L----------------------+-----------------+----------+----------

Стоит или не стоит использовать OUTER - зависит от того, что Вы хотите получить в результате оператора SELECT. Относительно приведенного Выше примера, то если бы нас интересовали именно люди, то следовало бы выбрать оператор SELECT в первом варианте, без OUTER. Если же нам было интересно получить информацию о фирмах, а заодно и узнать кто там работает, то следует выбрать второй вариант - c OUTER.

Действие, производимое оператором SELECT при выборке из двух таблиц называют слияние таблиц (join), а если производится слияние с OUTER, то такое слияние таблиц называется внешним (outer join). Внутри одного запроса можно использовать несколько таблиц с OUTER (кстати, такие таблицы называют подчиненными, а таблицы без OUTER - ведущими).