|
Программирование >> Sql: полное руководство
Показать имя, офис и объем продаж каждого служащего. SELECT NAME, SALES, CITY FROM SALESREPS, OFFICES WHERE REP OFFICE = OFFICE Error: Ambiguous column name SALES Хотя в формулировке запроса на естественном языке подразумевается столбец sales из таблицы salesreps, созданный запрос SQL является неоднозначным Чтобы исключить разночтения, при указании столбцов необходимо использовать их полные имена. В главе 5 было сказано, что полное имя столбца содержит непосредственно имя столбца и имя таблицы, в которой он находится. Полные имена двух столбцов sales в учебной базе данных будут такими OFFICES.SALES и SALESREPS.SALES В инструкции select вместо простых имен столбцов всегда можно использовать полные имена. Таблица, заданная в полном имени столбца, должна, конечно, соответствовать одной из таблиц, указанных в предложении from. Вот исправленный вариант предыдущего запроса: Показать имя, офис и объем продаж каждого служащего. SELECT NAME, SALESREPS.SALES, CITY FROM SALESREPS, OFFICES WHERE REP OFFICE = OFFICE
Никогда не помешает использовать в многотабличных запросах полные имена Столбцов. Недостатком, естественно, является то, что запросы становятся длиннее. В интерактивном режиме можно сначала попробовать выполнить запрос с простыми именами столбцов, чтобы найти все сомнительные столбцы. Если выдается сообщение об ошибке, запрос редактируют и точно указывают столбцы с повторяющимися именами. Выборка всех столбцов Как уже говорилось в главе 6, инструкция select * используется для выборки всех столбцов таблицы, указанной в предложении from. В многотабличном запросе звездочка означает выбор всех столбцов из всех таблиц, указанных в предложении From. Например, таблица результатов следующего запроса состоит из пятнадцати столбцов (девять столбцов из таблицы salesreps и следом за ними шесть столбцов из таблицы offices): Сообщить всю информацию о служащих и офисах, в которых они работают. SELECT * FROM SALESREPS, OFFICES WHERE REP OFFICE = OFFICE Очевидно, что инструкция select * становится гораздо менее практичной, когда в предложении from указаны две, три или более таблицы. Многие диалекты SQL трактуют звездочку как особый вид универсального имени столбца, которое преобразуется в список всех столбцов. В этих диалектах звездочка наряду с именем таблицы используется вместо списка полных имен столбцов. В следующем запросе имя salesreps . * означает список имен всех столбцов таблицы salesreps: Сообщить всю информацию о служащих и офисах, где они работают. SELECT SALESREPS.*, CITY, REGION FROM SALESREPS, OFFICES WHERE REP OFFICE = OFFICE Таблица результатов запроса будет иметь одиннадцать столбцов - девять столбцов таблицы salesreps и следом за ними два столбца таблицы offices, указанных явно. Такой тип полных имен всех столбцов поддерживается многими СУБД. Он был запрещен в стандарте SQL1, но теперь стал частью стандарта SQL2. Самообъединения Некоторые многотабличные запросы используют отношения, существующие внутри одной из таблиц Предположим, например, что требуется вывести список имен всех служащих и их руководителей. Каждому служащему соответствует одна строка в таблице salesreps, а столбец manager содержит идентификатор служащего, являющегося руководителем. Столбцу manager следовало бы быть внешним ключом для таблицы, в которой хранятся данные о руководителях. И он им, фактически, является - это внешний ключ для самой таблицы salesreps! Если бы вы попытались создать этот запрос как любой другой запрос к двум таблицам с отношением первичный ключ - внешний ключ , то он выглядел бы так: SELECT NAME, NAME FROM SALESREPS, SALESREPS WHERE MANAGER = EMPL NaM Эта инструкция select является неправильной из-за двойной ссылки на таблицу salesreps в предложении from. Вы могли бы попробовать убрать вторую ссылку на таблицу salesreps- SELECT NAME, NAME FROM SALESREPS WHERE MANAGER = EMPL NUM Такой запрос будет правильным, но он не сделает того, что вам нужно. Это од-нотабличный запрос, поэтому СУБД поочередно просматривает все строки таблицы salesreps, чтобы найти те, которые удовлетворяют условию отбора: MANAGER EMPL NDM Этому условию удовлетворяют строки, в которых два столбца имеют одинаковые значения, т.е. служащий является своим руководителем. Таких строк нет, поэтому запрос не даст никакого результата. Чтобы понять, как в SQL решается эта проблема, представим себе, что имеются две идентичные копии таблицы salesreps. Одна копия называется emps и содержит список служащих, а другая называется mgrs и содержит список руководителей (рис 7.9). Столбец manager таблицы emps является внешним ключом для таблицы mgrs, и следующий запрос будет работать Вывести список всех служащих и их руководителей. SELECT EMPS.NAME, MGRS.NAME FROM EMPS, MGRS WHERE EMPS.MANAGER = MGRS.EMPL NUM Так как столбцы в двух таблицах имеют идентичные имена, все ссылки на столбцы являются полными Иначе гспоря, этот запрос выглядит как обычный запрос к двум таблицам. Таблица MGRS (копия таблицы SALESREPS)
Таблица EMPS (копия таблицы SALESREPS)
Puc. 7.9. Самообьвф внив таблицы SAIiBSREFS Для объединения таблицы с самой собой в SQL применяется именно такой Подход: использование воображаемой копии . Вместо того чтобы на самом деле сделать копию таблицы, СУБД просто позволяет вам сослаться на нее, используя другое имя, которое называется псевдонимом таблицы. Вот тот же самый запрос, записанный с использованием псевдонимов emps и mgrs для таблицы salesreps:
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |