|
Программирование >> Формирование связанных подзапросов
Соединение, использующее предикаты, основаннхе на равенствах, назхвается эквисоединением. Рассмотреннхй пример соединения таблиц относятся к виду так называемого внутрен него (INNER) соединения. При этом соединяются только те строки таблиц, для которых истинным является предикат, задаваемый в предложении ON выполняемого запроса. Приведеннхй вхше запрос может бхть записан иначе, с использованием ключевого слова JOIN. SELECT STUDENT.SURNAME,UNIVERSITY.UNIV NAME, STUDENT.CITY FROM STUDENT INNER JOIN UNIVERSITY ON STUDENT.CITY = UNIVERSITY.CITY; Ключевое слово INNER в запросе может бхть опущено, так как эта опция в операторе JOIN действует по умолчанию. Рассмотренный выше случай полного соединения (декартова произведения) таблиц с использованием ключевого слова JOIN будет выглядеть следующим образом: SELECT * FROM STUDENT JOIN UNIVERSITY; что эквивалентно SELECT * FROM STUDENT, UNIVERSITY ; Заметим, что в СУБД Oracle задаваемый стандартом языка SQL оператор JOIN не поддерживается. .19.1. Операции соединения таблиц посредством ссылочной целостности Информация в таблицах STUDENT и EXAMMARKS уже связана посредством поля STUDENTID. В таблице STUDENT поле STUDENTID является первичным ключом, а в таблице EXAMMARKS - сс1лающимся на него внешним ключом. Состояние связанных таким образом таблиц называется состоянием ссхлочной целостности. В данном случае ссхлочная целостность этих таблиц подразумевает, что каждому значению поля STUDENTID в таблице EXAMMARKS обязательно соответствует такое же значение поля STUDENT ID в таблице STUDENT. Другими словами, в таблице EXAMMARKS не может быть записей, имеющих идентификаторы студентов, которых нет в таблице STUDENT. Стандартное применение операции соединения состоит в извлечении данных в терминах этой связи. Чтобы получить список фамилий студентов с полученнхми ими оценками и идентификаторами предметов, можно использовать следующий запрос: SELECT SURNAME, MARK, SUBJ ID FROM STUDENT,EXAM MARKS WHERE STUDENT.STUDENT ID = EXAM MARKS.STUDENT ID; Тот же результат может быть получен при использовании в запросе для задания операции соединения таблиц ключевого слова JOIN. Запрос с оператором JOIN выглядит следующим образом: SELECT SURNAME, MARK FROM STUDENT JOIN EXAM MARKS ON STUDENT.STUDENT ID = EXAM MARKS.STUDENT ID; Хотя выше речь шла о соединении двух таблиц, можно сформировать запросы путем соединения более чем двух таблиц. Пусть требуется найти фамилии всех студентов, получивших неудовлетворительную оценку, вместе с названиями предметов обучения, по которым получена эта оценка. SELECT SUBJ NAME, SURNAME, MARK FROM STUDENT,SUBJECT,EXAM MARKS WHERE STUDENT.STUDENT ID = EXAM MARKS.STUDENT ID AND SUBJECT.SUBJ ID = EXAM MARKS.SUBJ ID AND EXAM MARKS.MARK = 2; To же самое с использованием оператора JOIN: SELECT SUBJ NAME, SURNAME, MARK FROM STUDENT JOIN SUBJECT JOIN EXAM MARKS ON STUDENT.STUDENT ID = EXAM MARKS.STUDENT ID AND SUBJECT.SUBJ ID = EXAM MARKS.SUBJ ID AND EXAM MARKS.MARK = 2; 2.19.2. Внешнее соединение таблиц Как отмечалось ранее, при использовании внутреннего (INNER) соединения таблиц соединяются только те их строки, в которых совпадают значения полей, задаваемые в запросе предложением WHERE. Однако во многих случаях это может привести к нежелательной потере информации. Рассмотрим еще раз приведенный выше пример запроса на выборку списка фамилий студентов с полученными ими оценками и идентификаторами предметов. При использовании, как это б1ло сделано в рассматриваемом примере, внутреннего соединения в результат запроса не попадут студенты, которые еще не сдавали экзамены, и которые, следовательно, отсутствуют в таблице EXAMJMARKS. Если же необходимо иметь записи об этих студентах в выдаваемом запросом списке, то можно присоединить сведения о студентах, не сдававших экзамен, путем использования оператора UNION с соответствующим запросом. Например, следующим образом: se surname, cast mark as CHARdV cast subjid as char (10) from student,exam marks where STUDENT.STUDENTID = exam marks.student id union se surname, cast null as char(1), cast null as char(10) from student where not exist (select * from exammarks where STUDENT.STUDENT ID = exam marks.student id); (здесь функция преобразования типов CAST используется для обеспечения совместимости типов полей объединяемых запросов). Нужный результат может быть получен и путем использования внешнего соединения, точнее, одной из его разновидностей - левого внешнего соединения, с применением которого запрос будет выглядеть следующим образом: SELECT SURNAME, MARK FROM STUDENT LEFT OUTER JOIN EXAM MARKS ON STUDENT.STUDENT ID = EXAM MARKS.STUDENT ID;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |