Перейти к оглавлению
        8. ЗАПРАШИВАНИЕ МНОГОЧИСЛЕНЫХ ТАБЛИЦ ТАКЖЕ КАК ОДНОЙ.
 
 
 
 
   ДО ЭТОГО,  КАЖДЫЙ  ЗАПРОС КОТОРЫЙ МЫ ИССЛЕДОВАЛИ основывался на оди-
 ночной таблице.  В этой главе,  вы узнаете как сделать  запрос  любого
 числа таблиц с помощью одной команды.  Это - чрезвычайно мощное средс-
 тво потому что оно не только объединяет вывод из многочисленых таблиц,
 но и определяет связи между ними.  Вы обучитесь различным формам кото-
 рые могут использовать эти связи, а также устанавливать и использовать
 их чтобы удовлетворять возможным специальным требованиям.
 
 
             =============  ОБЪЕДИНЕНИЕ ТАБЛИЦ ============
 
 
   Одна из  наиболее  важных особенностей запросов SQL - это их способ-
 ность определять связи между многочислеными таблицами и  выводить  ин-
 формацию из них в терминах этих связей, всю внутри одной команды. Этот
 вид операции называется - объединением,  которое является одним из ви-
 дов  операций  в реляционных базах данных.  Как установлено в Главе 1,
 главное в реляционном подходе это связи которые можно создавать  между
 позициями данных в таблицах. Используя обьединения, мы непосредственно
 связываем информацию с любым номером таблицы, и таким образом способны
 создавать связи между сравнимыми фрагментами данных.  При обьединении,
 таблицы представленые списком в предложении FROM  запроса,  отделяются
 запятыми. Предикат запроса может ссылаться к любому столбцу любой свя-
 занной таблицы и,  следовательно, может использоваться для связи между
 ими.  Обычно, предикат сравнивает значения в столбцах различных таблиц
 чтобы определить, удовлетворяет ли WHERE установленному условию.
 
 
                        ИМЕНА ТАБЛИЦ И СТОЛБЦОВ
 
 
   Полное имя столбца таблицы фактически состоит из имени таблицы, соп-
 ровождаемого точкой и затем именем столбца. Имеются несколько примеров
 имен :
                   Salespeople.snum
                   Salespeople.city
                   Orders.odate
 
 
   До этого,  вы  могли опускать имена таблиц потому что вы запрашивали
 только одну таблицу одновременно, а SQL достаточно интелектуален чтобы
 присвоить соответствующий префикс, имени таблицы. Даже когда вы делае-
 те запрос многочисленых таблиц,  вы еще можете опускать имена  таблиц,
 если все ее столбцы имеют различные имена.  Но это не всегда так быва-
 ет.  Например,  мы имеем две типовые таблицы со столбцами  называемыми
 city.
   Если мы должны связать эти столбцы( кратковременно ), мы будем долж-
 ны указать их с именами Salespeople.city или Customers.city, чтобы SQL
 мог их различать.
 
 
                          СОЗДАНИЕ ОБЬЕДИНЕНИЯ
 
 
   Предположим что вы хотите поставить в соответствии  вашему  продавцу
 ваших заказчиков в городе в котором они живут,  поэтому вы увидите все
 комбинации продавцов и заказчиков для этого города.  Вы будете  должны
 брать  каждого  продавца и искать в таблице Заказчиков всех заказчиков
 того же самого города. Вы могли бы сделать это, введя следующую коман-
 ду ( вывод показывается в Рисунке 8.1 ):
 
 
           SELECT Customers.cname, Salespeople.sname,
            Salespeople.city
              FROM Salespeople, Customers
              WHERE Salespeople.city = Customers.city;
 
 
                ===============  SQL Execution Log ============
               | SELECT Customers.cname, Salespeople.sname,    |
               | Salespeople.city                              |
               | FROM  Salespeople, Customers                  |
               | WHERE Salespeople.city = Customers.city       |
               | ============================================= |
               |   cname       cname            city           |
               |  -------     --------          ----           |
               |  Hoffman     Peel              London         |
               |  Hoffman     Peel              London         |
               |  Liu         Serres            San Jose       |
               |  Cisneros    Serres            San Jose       |
               |  Hoffman     Motika            London         |
               |  Clemens     Motika            London         |
                 =============================================
 
 
 Рисунок 8.1: Объединение двух таблиц
 
 
   Так как это поле city имеется и в таблице Продавцов и таблице Заказ-
 чиков, имена таблиц должны использоваться как префиксы. Хотя это необ-
 ходимо только когда два или более полей имеют одно и то же имя,  в лю-
 бом  случае  это  хорошая  идея включать имя таблицы в обьединение для
 лучшего понимания и непротиворечивости.  Несмотря на это,  мы будем, в
 наших примерах далее,  использовать имена таблицы только когда необхо-
 димо, так что будет ясно, когда они необходимы а когда нет.
   Что SQL  в  основном делает в обьединении - так это исследует каждую
 комбинацию строк двух или более возможных таблиц, и проверяет эти ком-
 бинации  по  их предикатам.  В предыдущем примере,  требовалась строка
 продавца Peel из таблицы Продавцов и объединение ее с  каждой  строкой
 таблицы Пользователей, по одной в каждый момент времени. Если комбина-
 ция производит значение которое делает предикат верным,  и  если  поле
 city из строк таблиц Заказчика равно London, то Peel - это то запраши-
 ваемое значение которое комбинация выберет для вывода. То же самое бу-
 дет затем выполнено для каждого продавца в таблице Продавцов ( у неко-
 торых из которых небыло никаких заказчиков в этих городах).
 
 
 
 
            ОБЪЕДИНЕНИЕ ТАБЛИЦ ЧЕРЕЗ СПРАВОЧНУЮ ЦЕЛОСТНОСТЬ
 
 
   Эта особенность  часто  используется  просто для эксплуатации связей
 встроенных в базу данных.  В предыдущем примере,  мы установили  связь
 между  двумя таблицами в обьединении.  Это прекрасно.  Но эти таблицы,
 уже были соединены через snum поле.  Эта связь  называется  состоянием
 справочной целостности,  как мы уже говорили в Главе 1. Используя обь-
 единение можно извлекать данные в терминах этой связи. Например, чтобы
 показать  имена  всех  заказчиков соответствующих продавцам которые их
 обслуживают, мы будем использовать такой запрос:
 
 
              SELECT Customers.cname, Salespeople.sname
                 FROM Customers, Salespeople
                 WHERE Salespeople.snum = Customers.snum;
 
 
   Вывод этого запроса  показывается в Рисунке 8.2.
 
 
   Это - пример обьединения, в котором столбцы используются для опреде-
 ления предиката запроса,  и в этом случае,  snum столбцы из обеих таб-
 лиц, удалены из вывода. И это прекрасно. Вывод показывает какие заказ-
 чики  каким продавцом обслуживаются;  значения поля snum которые уста-
 навливают связь - отсутствуют.  Однако если вы введете их в вывод,  то
 вы должны или удостовериться что вывод понятен сам по себе или обеспе-
 чить коментарий к данным при выводе.
 
 
                ===============  SQL Execution Log ============
               | SELECT Customers.cname, Salespeople.sname,    |
               | FROM  Salespeople, Customers                  |
               | WHERE Salespeople.snum = Customers.snum       |
               | ============================================= |
               |   cname       sname                           |
               |  -------     --------                         |
               |  Hoffman     Peel                             |
               |  Giovanni    Axelrod                          |
               |  Liu         Serres                           |
               |  Grass       Serres                           |
               |  Clemens     Peel                             |
               |  Cisneros    Rifkin                           |
               |  Pereira     Motika                           |
                 =============================================
 
 
 Рисунок 8.2:  Объединение продавцов с их заказчикам
 
 
      ОБЪЕДИНЕНИЯ ТАБЛИЦ ПО РАВЕНСТВУ ЗНАЧЕНИЙ В СТОЛБЦАХ И ДРУГИЕ
                            ВИДЫ ОБЪЕДИНЕНИЙ
 
 
   Обьединения которые  используют  предикаты  основанные на равенствах
 называются - объединениями по равенству. Все наши примеры в этой главе
 до настоящего времени,  относились именно к этой категории, потому что
 все условия в предложениях WHERE базировались на математических  выра-
 жениях  использующих знак равно ( = ).  Строки 'city = 'London' и 'Sa-
 lespeople.snum = Orders.snum ' - примеры таких типов равенств  найден-
 ных в предикатах. Объединения по равенству - это вероятно наиболее об-
 щий вид объединения,  но имеются и другие.  Вы можете, фактически, ис-
 пользовать любой из реляционных операторов в обьединении.  Здесь пока-
 зан пример другого вида  объединения  (вывод  показывается  в  Рисунке
 8.3):
 
 
                SELECT sname, cname
                    FROM Salespeople, Customers
                    WHERE sname < cname
                       AND rating < 200;
 
 
                ===============  SQL Execution Log ============
               | SELECT sname, cname                           |
               | FROM  Salespeople, Customers                  |
               | WHERE sname < cname                           |
               | AND rating < 200;                             |
               | ============================================= |
               |     sname       cname                         |
               |    --------    -------                        |
               |    Peel        Pereira                        |
               |    Motika      Pereira                        |
               |    Axelrod     Hoffman                        |
               |    Axelrod     Clemens                        |
               |    Axelrod     Pereira                        |
               |                                               |
                 =============================================
 
 
 Рисунок 8.3: Обьединение основанное на неравенстве
 
 
   Эта команда не часто бывает полезна.  Она воспроизводит все комбина-
 ции имени продавца и имени заказчика так, что первый предшествует пос-
 леднему в алфавитном порядке, а последний имеет оценку меньше чем 200.
 Обычно,  вы не создаете сложных связей подобно этой, и, по этой причи-
 не,  вы вероятно будете строить наиболее общие объединения по  равенс-
 тву, но вы должны хорошо знать и другие возможности.
 
 
                     ОБЪЕДИНЕНИЕ БОЛЕЕ ДВУХ ТАБЛИЦ
 
 
   Вы можете  также  создавать  запросы объединяющие более двух таблиц.
 Предположим что мы хотим найти все порядки заказчиков не находящихся в
 тех городах где находятся их продавцы.Для этого необходимо связать все
 три наши типовые таблицы ( вывод показывается в Рисунке 8.4 ):
 
 
           SELECT onum, cname, Orders.cnum, Orders.snum
              FROM Salespeople, Customers,Orders
              WHERE Customers.city < > Salespeople.city
                 AND Orders.cnum = Customers.cnum
                 AND Orders.snum = Salespeople.snum;
 
 
             ===============  SQL Execution Log ==============
            |                                                 |
            | SELECT onum, cname, Orders.cnum, Orders.snum    |
            | FROM  Salespeople, Customers, Orders            |
            | WHERE Customers.city < > Salespeople.city       |
            | AND Orders.cnum = Customers.cnum                |
            | AND Orders.snum = Salespeople.snum;             |
            | =============================================== |
            |   onum    cname        cnum     snum            |
            |  ------  -------      -----    -----            |
            |   3001   Cisneros      2008     1007            |
            |   3002   Pereira       2007     1004            |
            |   3006   Cisneros      2008     1007            |
            |   3009   Giovanni      2002     1003            |
            |   3007   Grass         2004     1002            |
            |   3010   Grass         2004     1002            |
              ===============================================
 
 
 Рисунок 8. 4: Объединение трех таблиц
 
 
   Хотя эта команда выглядит скорее как комплексная,  вы можете  следо-
 вать  за  логикой,  просто проверяя - что заказчики не размещены в тех
 городах где размещены их продавцы ( совпадение двух snum  полей  ),  и
 что  перечисленные порядки - выполнены с помощью этих заказчиков( сов-
 падение порядков с полями cnum и snum в таблице Порядков ).
 
 
 
 
               ===============   РЕЗЮМЕ   ===============
 
 
   Теперь вы  больше не ограничиваетесь просмотром одной таблицы в каж-
 дый момент времени.  Кроме того,  вы можете делать  сложные  сравнения
 между  любыми полями любого числа таблиц и использовать полученные ре-
 зультаты чтобы решать какую информацию вы бы хотели видеть.  Фактичес-
 ки, эта методика настолько полезна для построения связей, что она час-
 то используется для создания их внутри одиночной  таблицы.  Это  будет
 правильным: вы сможете объединить таблицу с собой, а это очень удобная
 вещь.
   Это будет темой Главы 9.
 
 
               ************** РАБОТА С SQL **************
 
 
 1. Напишите  запрос который бы вывел список номеров порядков сопровож-
    дающихся именем заказчика который создавал эти порядки.
 2. Напишите  запрос  который бы выдавал имена продавца и заказчика для
    каждого порядка после номера порядков.
 3. Напишите  запрос  который  бы выводил всех заказчиков обслуживаемых
    продавцом с комиссионными выше 12%  .  Выведите имя заказчика,  имя
    продавца, и ставку комиссионных продавца.
 4. Напишите запрос который вычислил бы сумму комиссионных продавца для
    каждого порядка заказчика с оценкой выше 100.
 
 
 ( См. Приложение A для ответов. )
 
 
 
Перейти к оглавлению
Hosted by uCoz