Практическая работа 1. Проектирование базы данных
Скачать 2.91 Mb.
|
Тема Примеры создания запросов с отбором строк по условию. SQL дает возможность определить критерии отбора необходимых строк во фразе WHERE предложения SELECT. В этом случае строки исходных таблиц будут включены в результирующую только если строка соответствует указанным критериям. Условие - это выражение, которое может быть истинным или ложным (логическое выражение или предикат), то есть принимать логические значения TRUE или FALSE соответственно. В результирующую таблицу включаются только те строки, для которых указанное во фразе WHERE условие равно TRUE (иными словами, которые удовлетворяют заданному условию). В случае одной таблицы механизм работы предложения SELECT с фразой WHERE следующий. 1. Из таблицы, указанной во фразе FROM, выбирается очередная строка. 2. Она проверяется на соответствие условию во фразе WHERE. 3. Если результат равен TRUE, строка включается в результирующую таблицу и форматируется всоответствии с фразой SELECT, а если он равен FALSE, строка пропускается. 109 Далее будут рассмотрены основные выражения, допустимые для условия во фразе WHERE. Использование простейших условий Простейшими считаются условия, в которых используются операторы сравнения и логические операторы. Хотя такие условия являются простейшими в смысле семантики конструкций, они могут иметь довольно сложную структуру из многих операторов сравнений и вложенных друг в друга логических связок. Операторы сравнения Особенностью операторов сравнения является то, что независимо от типов операндов их результатом являются логические значения. Предположим, вы хотите получить список всех профессоров. Создайте новый запрос, введите sql-запрос, выполните его, сохраните его в рабочую папку ЛАБ6_SQL под именем 1.sql. Запрос 1. Вывести фамилии профессоров. SELECT NAME_TEACHER AS ‘Cписок профессоров’ FROM TEACHER WHERE DOLGNOST = 'профессор'; Чтобы выполнить sql-команду нажмите на панели редактора кнопку . В результате выполнения данного кода будут выданы все профессора. Например, Слово 'npофeccop' в запросе является строковой константой, поэтому ее следует заключить в кавычки. Обратите внимание, что мы указали фразу SELECT без ключевого слова DISTINCT, так как тогда от нас была бы скрыта информация о существовании среди профессоров однофамильцев. Чтобы при выводе результирующий столбец имел содержательный заголовок, мы поименовали его как Список профессоров. Это первый пример использования предиката над строковым типом данных. Здесь столбец строкового типа сравнивается со строковой константой. Запрос выполнен правильно, однако нужно всегда помнить о том, что предикаты над строками являются чувствительными к регистру букв. Например, предикат 'ИВАНОВ' = 'Иванов' будет ложным. Поэтому, если для некоторого профессора его должность была введена в таблицу TEACHER как 'Профессор', он не будет найден по условию WHERE DOLGNOST = 'профессор'. Чтобы на предикаты над строками не влиял регистр букв, нужно использовать обычно имеющиеся в СУБД функции преобразования букв в прописные и строчные. В стандарте SQL, например, указаны функции UPPER и LOWER, выполняющие такие преобразования. Следовательно, для предыдущего запроса правильней будет записать 110 условие фразы WHERE одним из следующих способов: WHERE LOWER(DOLGNOST) = 'профессор' WHERE UPPER(DOLGNOST) = 'ПРОФЕССОР' Самостоятельно измените в исходном запросе строку условия с использованием функции изменения регистра. Чтобы сохранить запрос нажмите правую кнопу и из контекстного меню выберите Сохранить в файл. Присвойте имя 1.sql и сохраните в папку ЛАБ5_SQL. Запрос 2. Найти всех студентов с стипендией, превышающим 300 грн. В sql-редакторе создайте новый запрос и введите следующий код: SELECT SUTNAME, SUTFNAME FROM STUDENT WHERE STIPEND > 300; Выполните его. Приведем несколько примеров использования операторов сравнения для столбцов строкового и временного типа. Обратите внимание, что сравнивать можно не только значение столбца с константой, но и значения столбцов между собой. Запрос 3. Вывести фамилии и должности преподавателей, принятых на работу после 01.01.2002. SELECT NAME_TEACHER AS 'Фамилия', DOLGNOST AS 'Должность' FROM TEACHER WHERE DATA_HIRE > '1/01/2002'; Запрос 4. Вывести фамилии и должности преподавателей, фамилии которых в алфавитном порядке располагаются после фамилии Сычева. SELECT NAME_TEACHER, DOLGNOST FROM TEACHER WHERE UPPER(NAME_TEACHER) > 'Сычева'; Самостоятельно создайте запрос 5. Вывести фамилии преподавателей, у которых надбавка меньше ставки в 2,5 и более раз. Логические операторы Операндами и результатом логических операторов являются логические значения. Стандартными логическими операторами являются AND, OR и NOT. Их действие показано в так называемых истинностных таблицах. Использование операторов сравнения вместе с логическими операторами предоставляет возможность формулировать составные условия для отбора строк таблиц. Использование логического оператора AND Логический оператор AND во многих случаях действует как связка ‘и’ в русском языке. Рассмотрим несколько примеров с использованием этого оператора. Запрос 6. Вывести фамилии студентов, проживающих в городе Макарово и имеющих стипендию больше 100 грн. 111 SELECT SUTFNAME FROM STUDENT WHERE CITY = 'Макарово'AND STIPEND >100; Самостоятельно создайте запрос 7. Вывести фамилии преподавателей, которые являются профессорами иставка которых превышает 4500. Самостоятельно создайте запрос 8. Вывести фамилии студентов учащихся на кафедре под порядковым номером 2 (Прикладная математика) с стипендией в диапазоне 100-500 грн. Использование логического оператора OR Логический оператор OR во многих случаях действует как связка ‘или’ в русском языке. Рассмотрим несколько примеров. Запрос 9. Вывести названия кафедр, расположенных либо в 1 либо в 8 корпусе. SELECT NAME_KAFEDRU, NUM_KORPUSA FROM KAFEDRA WHERE NUM_KORPUSA =1 OR NUM_KORPUSA =8; Использование логического оператора NOT Логический оператор NOT в русском языке передается словами ‘не’ и ‘кроме’. Запрос 10. Вывести названия всех факультетов, кроме факультета математики и информатики. SELECT NAME_FACULTETA FROM FACULTET WHERE NOT LOWER(NAME_FACULTETA) = 'математики и информатики'; Обратите внимание, что оператор NOT должен предшествовать выражению сравнения, а не ставиться перед оператором сравнения. То есть запись LOWER(NAME_FACULTETA) NOT =''математики и информатики'' будет неверной. Учитывая, что отрицанием оператора = является оператор <>, вместо указанного условия можно было бы записать LOWER(NAME_FACULTETA) <> ''математики и информатики''. Это относится ко всем операторам сравнения, так как каждый из них имеет оператор, являющийся его отрицанием. Комбинирование логических операторов Логические операторы можно объединять, формируя составные условия. Возможность комбинирования обеспечивается тем, что любой логический оператор возвращает истинностное значение, а значит, его результат может использоваться в другом логическом операторе. Рассмотрим несколько примеров. Запрос 11. Вывести фамилии, должность, ставку и надбавку ассистентов, у которых либо ставка меньше 550, либо надбавка больше 60. SELECT NAME_TEACHER, DOLGNOST, Salary, Rise FROM TEACHER WHERE LOWER(DOLGNOST) ='ассистент' AND (Salary < 550 OR Rise > 60); 112 Использование выражений над столбцами До сих пор в выражениях фразы WHERE мы использовали в качестве значения одного или обоих аргументов имена столбцов. Однако аргументами могут быть и выражения над столбцами. Запрос 12. Показать фамилии преподавателей, чья зарплата (ставка плюс надбавка) превышает 3500. SELECT NAME_TEACHER AS ‘Фамилия преподавателя’, Salary + Rise AS ‘Его зарплата’ FROM TEACHER WHERE Salary + Rise > 3500; Запрос 13. Показать фамилии преподавателей, половина зарплаты которых превышает пятикратную надбавку. SELECT NAME_TEACHER FROM TEACHER WHERE (Salary + Rise) / 2 > 5 * Rise; Использование специальных операторов В SQL имеются операторы сравнения, позволяющие проверять значения столбцов и выражений над ними на соответствие некоторым специальным условиям: принадлежность множеству; принадлежность диапазону; соответствие шаблону; соответствие регулярному выражению; неопределенное значение. В этом разделе вы узнаете, как их использовать и как с их помощью создавать составные условия. Проверка на принадлежность множеству Оператор IN позволяет проверить, входит ли значение в указанное множество значений. В простейшем случае этот оператор имеет следующий синтаксис: имя_столбца [NOT] IN (список_эначений) Здесь список значений представляет собой перечень разделенных запятыми констант, тип которых должен соответствовать типу столбца, чье имя приведено слева. Семантика этого предиката такова: он принимает значение TRUE, если значение столбца соответствует одной из констант списка. Приведем пример. Запрос 14. Вывести названия и номер корпуса кафедр, расположенных в корпусах 1, 3, 12. SELECT Name_Kafedru, NUM_KORPUSA FROM KAFEDRA WHERE NUM_KORPUSA IN ('1', '3', '12'); Использование отрицания Так как предикат IN возвращает истинностное значение, к нему можно применить логическое отрицание. Для этого следует воспользоваться нотацией NOT IN. В этом случае предикат будет истинным, если значение столбца не входит в указанный список. 113 Запрос 15. Вывести названия и номер корпуса кафедр, расположенных в любых корпусах, кроме 1, 3, или 12. SELECT Name_Kafedru AS ‘Название кафедры’, NUM_KORPUSA AS “Корпус’ FROM KAFEDRA WHERE NUM_KORPUSA NOT IN (‘1', 'З', '12'); Использование выражений над столбцами В левой части оператора IN вместо имени столбца можно использовать любое допустимое над столбцами таблицы выражение языка. Запрос 16. Вывести фамилии преподавателей, зарплата которых (ставка + надбавка) равна 800, 900, 1000, 1100 или 1200. SELECT NAME_TEACHER AS ‘Фамилия преподавателя’, Salary + Rise AS ‘Зарплата преподавателя’ FROM TEACHER WHERE Salary + Rise IN (1150, 2400, 3150, 4300); Более того, элементами списка в правой части оператора IN тоже могут быть выражения над столбцами, как это показано в следующем примере: Запрос 17. SELECT NAME_TEACHER, Salary, Salary + Rise FROM TEACHER WHERE Salary + Rise IN (Salary + 100, Salary + 200, Salary + 300, Salary + 400, Salary + 500); Проверка на принадлежность диапазону значений Еще одной формой проверки вхождения элемента во множество является проверка на его принадлежность диапазону значений. Для этого применяется предикат BETWEEN, который определяет нахождение значения столбца между указанными минимальным и максимальным значениями. Синтаксис предиката следующий: имя_столбца [NOT] BETWEEN минимум AND максимум Проверять можно значения числовых, строковых и временных типов (для строк символов предполагается алфавитное упорядочение). Оператор BETWEEN является включающим - это означает, что крайние значения диапазона включаются в допустимые. Запрос 18. Вывести фамилии преподавателей со ставкой в диапазоне 1000- 2000. SELECT NAME_TEACHER FROM TEACHER WHERE Salary BETWEEN 1000 AND 2000; Использование строковых значений Использование в операторе BETWEEN в качестве границ диапазона строковых значений имеет особенности, связанные с упорядочением (это же относится и к другим операторам сравнения). Запрос 19. Вывести фамилии преподавателей, начинающиеся на буквы от ‘3’ до ‘Л’. SELECT NAME_TEACHER FROM TEACHER 114 WHERE UPPER(NAME_TEACHER) BETWEEN 'З' AND 'Л'; Среди строк результата нет фамилий, начинающихся на букву ‘Л’. Дело в том, что при сравнении строк символов разной длины SQL предварительно дополняет более короткую строку символами пробела, а он в упорядочениях символов предшествует всем остальным. Поэтому строка, состоящая из буквы ‘Л’ (дополненная пробелами), всегда будет меньше любой другой строки, в которой за начальной буквой 'Л’ следуют отличающиеся от пробела символы. Чтобы это учесть, в качестве верхнего значения диапазона лучше всего указывать следующую по алфавиту букву (в данном случае — ‘М’). Использование отрицания Так как предикат BETWEEN возвращает истинностное значение, к нему можно применить логическое отрицание. Для этого следует воспользоваться нотацией NOT BETWEEN, в которой предикат будет истинным, только если значение столбца не входит в указанный диапазон. Представление отрицания нотацией NOT BETWEEN введено в язык для большей наглядности, так как с предикатом BETWEEN можно стандартным образом использовать логический оператор NOT (то есть ставить отрицание ко всему выражению, а не к предикату): NOT (имя_столбца BETWEEN минимум AND максимум) Круглые скобки в данном случае можно и опустить, так как они не меняют порядка исполнения операторов. В нотации NOT BETWEEN крайние значения в диапазон не включаются. Запрос 20. Вывести названия и номер корпуса кафедр, которые не расположены в корпусах 1 и 3. SELECT Name_Kafedru, NUM_KORPUSA FROM KAFEDRA WHERE NUM_KORPUSA NOT BETWEEN ‘1’ AND '3'; SELECT Name_Kafedru, NUM_KORPUSA FROM KAFEDRA WHERE NOT (NUM_KORPUSA BETWEEN ‘1’ AND '3'); Использование выражений над столбцами Как и в предикате IN, вместо имени столбца и границ диапазона можно использовать любое допустимое в языке выражение над столбцами таблицы, включая и функции. Запрос 21. Показать фамилии преподавателей, принятых на работу между 01.01.2000 и 12.12.2001. SELECT NAME_TEACHER, DATA_HIRE FROM TEACHER WHERE DATA_HIRE BETWEEN ‘01/01/2000’ AND '12/12/2001'; Запрос 22. Вывести данные преподавателей, зарплата которых (ставка + надбавка) находится в диапазоне от удвоенной величины надбавки до утроенной надбавки плюс 50. SELECT NAME_TEACHER, Salary + Rise, 2 * Rise, 3 * Rise + 50 FROM TEACHER WHERE Salary + Rise BETWEEN 2 * Rise AND 3 * Rise + 50; 115 Проверка на соответствие шаблону Когда необходимо отобрать строки таблицы, в которых значение некоторого столбца совпадает с заданной строкой символов, следует использовать обычное сравнение, как это показано выше. Однако во многих случаях можно не знать точное представление в базе данных интересующего значения. Название одной и той же кафедры, например, может храниться в одном из следующих вариантов: ‘базы данных’, ‘организация баз данных’, ‘информационные системы и базы данных’, ‘базы данных и знаний’. Такая же ситуация возникает, когда не известно точное написание фамилии преподавателя, название дисциплины, факультета и т. п. Специально для таких случаев предназначен оператор сравнения LIKE, позволяющий отобрать из таблицы строки на основе частичного соответствия. Упрощенный синтаксис оператора следующий: имя_столбца [NOT] LIKE шаблон [ESCAPE символ_пропуска] Его можно использовать только с символьными значениями. Использование шаблона Оператор LIKE сравнивает значение столбца с множеством значений, определяемых шаблоном. Он представляет собой строку, в которой помимо обычных символов, составляющих основу поискового выражения, можно использовать так называемые подстановочные символы (иногда они называются групповыми символами). Имеется всего два подстановочных символа, различающихся тем, что именно на их месте может стоять: % — любая последовательность символов, включая их отсутствие; _ — один любой символ. Подстановочные символы могут находиться в любом месте шаблона в любом наборе. Например, шаблону '%Иван%' соответствуют строки 'Иван', 'Иванов', 'Иванченко', 'Петр Иванович', а шаблону 'л_с_' - 'лист', 'леса', 'лоск' (ноне 'лес', 'листок', 'плес'). Оператор LIKE, как и все другие, работающие с символьными строками, чувствителен к регистру букв, поэтому при его использовании мы рекомендуем использовать уже известные вам функции UPPER() и L0WER(). Запрос 23. Найти фамилии преподавателей на букву ‘М’. SELECT NAME_TEACHER FROM TEACHER WHERE UPPER(NAME_TEACHER) LIKE 'М%'; Имейте в виду, что если вы запишете условие фразы WHERE как UPPER(NAME_TEACHER) = 'М%' или даже как 'М%' LIKE UPPER(NAME_TEACHER), фамилии преподавателей будут сравниваться со строкой ' М%'. Во втором случае выражение является синтаксически правильным оператором LIKE, однако в нем строка 'М%' не выступает в качестве шаблона, так как расположена перед ключевым словом LIKE. Запрос 24. Указать преподавателей, в фамилиях которых первой буквой является ‘М’, а четвертой – ‘ы’. SELECT NAME_TEACHER FROM TEACHER 116 WHERE NAME_TEACHER LIKE 'М__ ы%’; Запрос 25. Вывести названия кафедр, в которых присутствует словосочетание ‘анализ’ (в различных грамматических формах). SELECT Name_Kafedru FROM KAFEDRA WHERE LOWER(Name_Kafedru) LIKE '%анализ%'; В левой части оператора LIKE может находиться не только имя столбца, но и любое допустимое над столбцами выражение, как это показано в следующем примере. Запрос 26. Указать преподавателей, в фамилию и название должности которых входит в сумме не меньше пяти букв ‘о’. SELECT NAME_TEACHER, DOLGNOST FROM TEACHER WHERE LOWER(NAME_TEACHER + DOLGNOST) LIKE '%o%o%o%o%o%'; Проверка на неопределенное значение Как мы уже отмечали, наличие значения NULL во фразе WHERE приводит к тому, что условие принимает истинностное значение UNKNOWN и соответствующая строка не включается в результат. Детальное описание работы с неопределенным значением вы можете найти в уроке 10, а здесь мы покажем, как обрабатывать значение NULL во фразе WHERE. Чтобы проверить столбец на неопределенное значение, следует применить унарный оператор IS NULL, имеющий такой синтаксис: имя_столбца IS [NOT] NULL Этот оператор принимает истинностное значение TRUE, если столбец имеет неопределенное значение, и FALSE — в противном случае. В нотации IS NOT NULL его действие обратное. Запрос 27. Вывести фамилии преподавателей, у которых не задан номер телефона или идентификационный код. SELECT NAME_TEACHER, INDEF_KOD, TEL_TEACHER FROM TEACHER WHERE INDEF_KOD IS NULL OR TEL_TEACHER IS NULL; Задание для практической работы №5 Для созданной базы данных, согласно номеру варианта, самостоятельно создать на языке Transact-SQL 15 запросов с отбором строк по условию: - 3 простейших запроса с использованием операторов сравнения; - 3 запроса с использованием логических операторов AND, OR и NOT; - 1 запрос на использование комбинации логических операторов; - 1 запрос на использование выражений над столбцами; - 2 запроса с проверкой на принадлежность множеству; - 2 запроса с проверкой на принадлежность диапазону значений; - 2 запроса с проверкой на соответствие шаблону; - 1 запрос с проверкой на неопределенное значение. Все программные инструкции команд SQL сохранять в файлах с расширением *.sql в папке ФИО_студента/Лаб5. 117 Для каждого запроса сформулировать текстовое задание, которое должно быть выполнено к базе данных. Создать текстовый отчет, в котором отобразить sql-команды разработанных запросов и скриншоты результатов работы из СУБД SQL Server Management Studio. 118 ПРАКТИЧЕСКАЯ РАБОТА №6. СОЗДАНИЕ МНОГОТАБЛИЧНЫХ ЗАПРОСОВ. ЗАПРОСЫ НА СОЕДИНЕНИЕ 6.1. Цель практической работы Изучить используемый в реляционных СУБД оператор извлечения данных из таблиц. Получить навыки работы с оператором SELECT в программе ‘SQL Server Managmant Studio’. 6.2. Исходные данные Исходными данными является индивидуальное задание и результат предыдущих практических работ. 6.3. Используемые программы Программы ‘ SQL Server Managmant Studio ‘. 6.4. Теоретические сведения При проектировании стремятся создавать таблицы, в каждой из которых содержалась бы информация об одном и только одном типе сущности. Это облегчает модификацию базы данных и поддержку ее целостности. Именно так мы поступили, создавая учебную базу данных. Однако сущности могут быть взаимосвязанными. Кафедры связаны с факультетами по признаку вхождения в их состав, преподаватели работают на кафедрах, студенты учатся на кафедрах и т. д. Связь между таблицами устанавливается за счет размещения специального столбца первичного ключа одной таблицы, которая называется родительской, в другой таблице, которая называется дочерней. Столбец (или совокупность столбцов) дочерней таблицы, определенный для связи с родительской таблицей, называется внешним ключом. Наличие внешних ключей является основной для инициирования поиска по многим таблицам. Одна из наиболее важных особенностей предложения SELECT — это способность использования связей между различными таблицами, а также вывода содержащейся в них информации. Операция, которая приводит к соединению из двух таблиц всех пар строк, для которых выполняется заданное условие, называется соединением таблиц. Для того чтобы указать соединяемые таблицы, их следует перечислить через запятую во фразе FROM. Декартово произведение таблиц Соединение таблиц - это частный случай операции декартового произведения (или просто произведения). Декартово произведение двух таблиц — это таблица, состоящая из всех возможных пар строк обеих таблиц. Это определение можно естественным образом расширить на любое количество таблиц. В SQL декартово произведение выражается указанием имен перемножаемых таблиц во фразе FROM и указанием всех их столбцов во фразе SELECT. Так, произведение таблиц FACULTET и KAFEDRA выражается следующим образом: SELECT * FROM FACULTET, KAFEDRA Так как результирующая таблица содержит много столбцов и они не помещаются по ширине страницы, мы приведем только интересующие нас столбцы произведения этих таблиц. 119 Запрос 28. Декартово произведение таблиц. SELECT FACULTET.Name_faculteta, FACULTET. Kod_faculteta, KAFEDRA. Kod_faculteta, KAFEDRA.Name_Kafedru FROM FACULTET, KAFEDRA; Каждая строка таблицы факультетов оказалась соединенной с каждой строкой таблицы кафедр, в результате получилось 27 строк (3 факультета х 9 кафедр = 27 комбинаций). В произведении может участвовать много таблиц. Например, произведение таблиц факультетов, кафедр и преподавателей записывается следующим образом: SELECT * FROM FACULTET, KAFEDRA, TEACHER Условие соединения Соединение таблиц может быть указано во фразе WHERE или во фразе FROM. Сначала рассмотрим первый вариант. Большинство запросов, имеющих несколько таблиц во фразе FROM, содержат фразу WHERE, в которой указаны условия, попарно сравнивающие столбцы из различных таблиц. Такое условие называется условием соединения. В этом случае SQL предполагает сцепление только тех пар строк из разных таблиц, для которых условие соединения принимает истинное значение. Теоретически при соединении сначала выполняется декартово произведение указанных таблиц в одну, а затем из нее отбираются строки согласно условию соединения. Естественно, ни одна СУБД не работает таким образом. Фраза WHERE помимо условия соединения может также содержать другие условия, каждое из которых ссылается на столбцы соединенной таблицы. Эти условия производят отбор строк соединенной таблицы. Соединения можно разделить на следующие категории. Внутренние соединения (типичные операции соединения, использующие такие операторы сравнения, как = или <>). Они включают эквивалентные соединения и естественные соединения. Внутренние соединения используют оператор сравнения для установки соответствия строк из двух таблиц на основе значений общих столбцов в каждой таблице. Примером может быть получение всех строк, в которых идентификационный номер студента одинаковый как в таблице students, так и в таблице courses. Внешние соединения. Внешние соединения бывают левыми, правыми и полными. Если внешние соединения задаются в предложении FROM, они указываются с одним из следующих наборов ключевых слов. LEFT JOIN или LEFT OUTER JOIN Результирующий набор левого внешнего соединения включает все строки из левой таблицы, заданной в предложении LEFT OUTER, а не только те, в которых соединяемые столбцы соответствуют друг другу. Если строка в левой таблице не имеет совпадающей строки в правой таблице, результирующий набор строк содержит значения NULL для всех столбцов списка выбора из правой таблицы. RIGHT JOIN или RIGHT OUTER JOIN Правое внешнее соединение является обратным для левого внешнего соединения. Возвращаются все строки правой таблицы. Для левой таблицы возвращаются значения NULL каждый раз, когда строка правой таблицы не имеет совпадающей строки в левой таблице. 120 FULL JOIN или FULL OUTER JOIN Полное внешнее соединение возвращает все строки из правой и левой таблицы. Каждый раз, когда строка не имеет соответствия в другой таблице, столбцы списка выбора другой таблицы содержат значения NULL. Если между таблицами имеется соответствие, вся строка результирующего набора содержит значения данных из базовых таблиц. Перекрестные с соединения Перекрестное соединение возвращает все строки из левой таблицы. Каждая строка из левой таблицы соединяется со всеми строками из правой таблицы. Перекрестные соединения называются также декартовым произведением. Таблицы или представления в предложении FROM могут указываться в любом порядке с внутренним соединением или полным внешним соединением. Однако важен порядок таблиц или представлений, заданных при использовании левого или правого внешнего соединения. Соединение таблиц по равенству Если таблицы соединяются по равенству значений пары столбцов (группы столбцов) из различных таблиц, такая операция называется соединением таблиц по равенству. Соединение по равенству, в отличие от декартового произведения, позволяет соединить только те пары строк, которые действительно взаимосвязаны друг с другом. Так, например, мы можем соединить таблицы факультетов и кафедр по условию FACULTET.Kod_faculteta = KAFEDRA.Kod_faculteta. В таком варианте мы соединяем таблицы осмысленно, так как каждая строка таблицы FACULTET соединяется только со строками соответствующих кафедр. На базе таблиц FACULTET и KAFEDRA мы получаем таблицу со столбцами из обеих таблиц, имеющую строки с понятным смыслом. Можно также сказать, что в таблицу KAFEDRA вместо столбца Kod_faculteta мы вставляем все характеристики (столбцы) соответствующего факультета из таблицы FACULTET. Соединение таблиц используется, когда необходимо вывести значения столбцов: – разных таблиц; – одной таблицы, но отвечающих условию, заданному на другой таблице. Эти два варианта, а также их комбинация, характерны для любого вида соединения, а не только по равенству. Перейдем к рассмотрению примеров. Вывод столбцов разных таблиц Этот вид запросов характерен тем, что фраза WHERE содержит только условие соединения, а список фразы SELECT содержит имена столбцов из различных таблиц. Запрос 29. Вывести названия кафедр и номера их групп. SELECT Name_Kafedru, [Group] FROM KAFEDRA, STUDENT WHERE KAFEDRA.kod_kafedru = STUDENT.kod_kafedru; или SELECT Name_Kafedru, student.[GROUP] FROM KAFEDRA, STUDENT WHERE KAFEDRA.kod_kafedru = STUDENT.kod_kafedru; 121 Мы привели два варианта запроса. В первом имена столбцов не уточняются именами таблиц, а во втором — уточняются. В данном случае это не имеет значения, оба запроса корректны. Уточнение имен столбцов До тех пор, пока запрос относится к одной таблице, обращение к столбцам по их именам не вызывает проблем — в таблице все имена столбцов должны быть неповторяющимися. Однако как только запрос соединяет несколько таблиц, может возникнуть неоднозначность при ссылках на столбцы с одинаковыми именами из разных таблиц. Для разрешения этой неоднозначности во фразах SELECT и WHERE (как и в некоторых других фразах) имена столбцов необходимо уточнять именами таблиц. Запрос 30. Вывести названия факультетов и их кафедр. SELECT FACULTET.NAME_FACULTETA, KAFEDRA.Name_Kafedru FROM FACULTET, KAFEDRA WHERE FACULTET.Kod_faculteta = KAFEDRA.Kod_faculteta; В этом запросе мы уточнили имена столбцов во фразах SELECT и WHERE, хотя во втором случае это не обязательно, так как используются неповторяющиеся имена. Тем не менее, рекомендуем при соединении таблиц для наглядности уточнять имена столбцов. Обратите внимание на то, что в предыдущем примере отсутствует факультет математики — на нем нет кафедр. Вывод столбцов с условием отбора Вариант, когда отбираются строки одной таблицы, а условие задается с участием другой, используется довольно часто. Приведем примеры. Запрос 31. Вывести названия кафедр факультета Математики и информатики. SELECT KAFEDRA.Name_Kafedru AS ‘Кафедры факультета математики и информатики’ FROM FACULTET, KAFEDRA WHERE FACULTET. Kod_faculteta = KAFEDRA. Kod_faculteta AND LOWER(FACULTET.NAME_FACULTETA) = 'математики и информатики'; Запрос 32. Вывести фамилии доцентов кафедры информатики. SELECT TEACHER.NAME_TEACHER AS ‘Доценты кафедры информатики’ FROM KAFEDRA, TEACHER WHERE KAFEDRA.kod_kafedru = TEACHER. kod_kafedru AND LOWER(KAFEDRA.Name_Kafedru) = ‘информатики' AND LOWER(TEACHER.DOLGNOST) = 'доцент'; В последнем запросе помимо условия соединения используется также отбор строк по условиям, заданным для разных таблиц. Синонимы таблиц Синонимы таблиц часто используются для задания более лаконичного имени таблицы, по которому можно сослаться на нее в любых других местах запроса. Приведем пример. 122 Запрос 33. Вывести названия кафедр, на которых имеются студенты со стипендией >200 грн. SELECT DISTINCT k.Name_Kafedru FROM KAFEDRA k, STUDENT s WHERE k.Kod_kafedru = s. Kod_kafedru AND s.Stipend > 400; Запросы по трем и более таблицам SQL позволяет формулировать запросы, которые предполагают использование трех и более таблиц. При этом следует применять ту же методику соединения, что и для двух таблиц. Рассмотрим простой пример соединения трех таблиц. Запрос 34. Вывести названия тех кафедр факультета математики и информатики, на которых работают профессора. SELECT DISTINCT KAFEDRA.Name_Kafedru FROM FACULTET, KAFEDRA, TEACHER WHERE FACULTET.Kod_faculteta = KAFEDRA.Kod_faculteta AND KAFEDRA.Kod_kafedru = TEACHER.Kod_kafedru AND FACULTET.Name_faculteta ='Математики и информатики' AND TEACHER.DOLGNOST = 'профессор'; Для ответа на запрос необходимы три таблицы: на таблицах факультетов и преподавателей заданы условия отбора, а из таблицы кафедр следует вывести столбец названий. Поэтому три необходимые таблицы указываются во фразе FROM, а во фразе WHERE производится их соединение по условию равенства первичного и внешнего ключей: FACULTET. Kod_faculteta = KAFEDRA. Kod_faculteta -- соединение таблиц факультетов и кафедр KAFEDRA. Kod_kafedru = TEACHER. Kod_kafedru -- соединение таблиц кафедр и преподавателей Таблица, образующаяся в результате соединений, будет иметь столько же строк, сколько имеется в таблице преподавателей (если все преподаватели работают на кафедрах). Выясним, почему это так, но сначала заметим, что результат соединения таблиц не зависит от порядка соединения. Поэтому рассмотрим случай, когда сначала мы соединяем таблицы кафедр и преподавателей, а затем результат соединяем с таблицей факультетов. Так как между таблицами кафедр и преподавателей существует связь типа один- ко-многим, их соединение фактически означает приписывание к строке каждого преподавателя данных о его кафедрах. Количество строк этого соединения будет равным количеству преподавателей. Связь между таблицами факультетов и кафедр также имеет тип один-ко-многим, поэтому второе соединение означает, что к каждой строке таблицы, полученной после первого соединения, приписываются данные о факультете кафедры. Таким образом, количество строк останется равным числу преподавателей. Вернемся к запросу. Последние два условия фразы WHERE отбирают строки из соединенной таблицы, а во фразе SELECT указан выводимый столбец. Ключевое слово DISTINCT указано в нем потому, что названия кафедр в соединенной таблице могут повторяться. 123 Запрос 35. Вывести фамилии ассистентов факультета математики и информатики. SELECT TEACHER.NAME_TEACHER AS ‘Ассистенты ф-та математики и информатики’ FROM FACULTET, KAFEDRA, TEACHER WHERE FACULTET.Kod_faculteta = KAFEDRA.Kod_faculteta AND KAFEDRA.Kod_kafedru = TEACHER.Kod_kafedru AND FACULTET.Name_faculteta ='Математики и информатики' AND TEACHER.DOLGNOST = 'ассистент'; В этом случае для ответа нужны две таблицы — факультетов и преподавателей. Однако они связаны между собой опосредованно, через таблицу кафедр. Поэтому для соединения таблиц факультетов и преподавателей следует использовать таблицу кафедр. Сформулируем общую процедуру составления многотабличного запроса и приведем пример ее использования. 1. Определить множество таблиц, необходимых для ответа на запрос. В это множество должны входить таблицы, на столбцах которых сформулированы условия, а также те, столбцы которых необходимо вывести. Это так называемые базовые таблицы запроса. 2. В структуре взаимосвязанных таблиц найти путь, соединяющий базовые таблицы. Это так называемый путь вычисления запроса. В результате вы получите перечень таблиц, необходимых для формулировки запроса. Это так называемые таблицы запроса. 3. Во фразе FROM перечислить необходимые таблицы. 4. Во фразе WHERE соединить таблицы запроса и при необходимости задать условия отбора строк в базовых таблицах запроса. 5. Во фразе SELECT перечислить выводимые столбцы. Вывод всех столбцов соединяемой таблицы В многотабличном запросе конструкция SELECT * означает выбор всех столбцов соединенной таблицы. Например, результирующая таблица следующего запроса состоит из 21 столбца: 5 столбцов таблицы факультетов, 6 столбцов таблицы кафедр и 10 столбцов таблицы преподавателей. Запрос 36. SELECT * FROM FACULTET f, KAFEDRA k, TEACHER t WHERE f.Kod_faculteta = k.Kod_faculteta AND k.Kod_kafedru = t.Kod_kafedru; При наличии в запросе многих таблиц конструкция SELECT * становится не очень практичной. В связи с этим в различных СУБД предоставляется возможность использовать во фразе SELECT многотабличных запросов выражение имя_таблицы.* для указания вывода всех столбцов конкретной таблицы. Например: SELECT f.*, k.FIO_ZAVKAF, t.* FROM FACULTET f, KAFEDRA k, TEACHER t WHERE f.Kod_faculteta = k.Kod_faculteta AND k.Kod_kafedru = t.Kod_kafedru; Другие виды соединений no равенству 124 Логическая связь между таблицами поддерживается взаимосоответствием столбцов первичного и внешнего ключей. Все рассмотренные до сих под запросы для соединения таблиц использовали именно эту связь. Однако SQL позволяет связывать таблицы по любой паре столбцов, которые имеют сравнимые типы данных, независимо от того, имеет ли эта связь какой-либо смысл. Рассмотрим ряд примеров. Запрос 37. Если фамилия заведующего кафедры совпадает с фамилией декана какого-нибудь из факультетов, вывести название этой кафедры вместе с названием соответствующего факультета. SELECT k.Name_Kafedru AS ‘Название кафедры’, f.NAME_FACULTETA AS ‘Название факультета’ FROM FACULTET f, KAFEDRA k WHERE f.FIO_DECANA = k.FIO_ZAVKAF; Запрос 38. Вывести пары названий кафедр и фамилий преподавателей, у которых совпадают первичные ключи. SELECT k.Name_Kafedru AS ‘Название кафедры’, t.Name_Teacher AS ‘Фамилия преподавателя’ FROM KAFEDRA k, TEACHER t WHERE k.Kod_kafedru = t.Kod_kafedru; Если первый запрос не лишен смысла, то последний абсолютно бессмысленный, так как в учебной базе данных первичные ключи лишены какого-либо содержания и используются только для идентификации строк своих таблиц. Самосоединение таблицы Как правило, взаимосвязи существуют и в пределах одной таблицы. В одних случаях эти связи являются явными, например, когда внешний ключ ссылается на первичный ключ той же самой таблицы. В других случаях эта связь присутствует неявно, например, кафедры могут быть связаны между собой на основании того свойства, что располагаются в одном корпусе. Для ответа на такие запросы следует осуществлять соединение таблицы со своей копией. Такое соединение иногда называют самосоединением таблицы. Несмотря на кажущуюся искусственность идеи самосоединения таблиц, существует множество запросов, которые требуют именно такого соединения. На приводимых далее примерах вы убедитесь в этом. Чтобы произвести соединение таблицы со своей копией, необходимо указать во фразе FROM имя одной и той же таблицы два или большее количество раз, а во фразе WHERE — условие их самосоединения. Однако в этом случае возникает следующая проблема — как ссылаться на столбцы различных копий таблицы- До сих пор проблема ссылки на столбцы с одинаковыми именами из разных таблиц разрешалась уточнением имени столбца именем таблицы. В нашем же случае соединяемые таблицы имеют одинаковые имена. Для разрешения этой проблемы без синонимов таблиц уже не обойтись. В нашем случае различным вхождениям одной и той же таблицы приписываются различные синонимы и именно по этим синонимам производится обращение к столбцам. Приведем примеры использования самосоединения. Запрос 39. Вывести фамилии преподавателей, зарплата которых больше, чем у преподавателя Сидорова. 125 SELECT needed.NAME_TEACHER FROM TEACHER needed, TEACHER given WHERE needed.Salary + needed.Rise > given.Salary + given.Rise AND given.NAME_TEACHER = 'Игнатьева Олеся Владимировна'; Симметричное соединение и удаление избыточности При самосоединении по равенству обычно возникают избыточные строки. Рассмотрим следующий запрос. Запрос 40. Вывести названия кафедр, располагающихся в том же корпусе, что и кафедра информатики. SELECT needed.Name_Kafedru FROM KAFEDRA needed, KAFEDRA given WHERE needed.NUM_KORPUSA = given.NUM_KORPUSA AND given.Name_Kafedru = 'Информатики'; Обратите внимание, что в результат включена и сама кафедра информатики. Для того чтобы избавиться от ненужной результирующей строки, следует добавить условие отбора: needed.Name_Kafedru <> ' Информатика’ При самосоединении по равенству можно получить симметричную результирующую таблицу. Суть симметричности заключается в том, что в таблице содержатся строки: с одинаковыми значениями всех столбцов; со всеми возможными перестановками значений столбцов. Запрос 41. Вывести пары номеров групп, которые принадлежат одной кафедре. SELECT g1.[Group], g2.[Group], g1.kod_kafedru FROM STUDENT g1, STUDENT g2 WHERE g1.kod_kafedru = g2.kod_kafedru; ПРИМЕЧАНИЕ В этом запросе мы дополнительно вывели столбец с номером (первичным ключом) кафедры для большей наглядности. Результирующая таблица оказалась симметричной, и в связи с этим содержит избыточные строки. Простой способ избежать этого состоит в том, чтобы наложить ограничение на выбираемые пары значений таким образом, чтобы первое выдаваемое значение было меньше другого (или предшествовало ему в алфавитном порядке). Это делает результат асимметричным, поэтому пары с одинаковыми значениями, а также пары, заданные в обратном порядке, не будут появляться. Покажем это на примере варианта предыдущего запроса. SELECT g1.[Group], g2.[Group], g1.kod_kafedru FROM STUDENT g1, STUDENT g2 WHERE g1.kod_kafedru = g2.kod_kafedru AND g1.[Group] Проверка правильности данных 126 Самосоединение можно использовать для проверки корректности данных. Например, мы точно знаем, что в нашем вузе нет однофамильцев, занимающих разные должности. С помощью самосоединения таблицы преподавателей мы можем убедиться, что их нет и в базе данных. Запрос 42. Указать преподавателей-однофамильцев, которые занимают различные должности. SELECT tch1.NAME_TEACHER AS ‘Препод. с различ. должностями’ FROM TEACHER tch1, TEACHER tch2 WHERE tch1.NAME_TEACHER = tch2.NAME_TEACHER AND tch1.DOLGNOST <> tch2.DOLGNOST; Внешнее соединение таблиц Предположим, необходимо вывести список факультетов и их кафедр. Это достигается соединением таблиц FACULTET и KAFEDRA по равенству значений первичного и внешнего ключей и выбором столбцов с названиями факультетов и кафедр. Но в таком случае, если на факультете кафедр нет, он не будет включен в результат. Для того чтобы в списке присутствовали все факультеты, даже без кафедр, необходимо использовать внешнее соединение, которое расширяет возможности обычного соединения. Внешнее соединение возвращает строки, которые удовлетворяют условию соединения, а также те строки одной из таблиц, для которых в другой не нашлось удовлетворяющих условию соединения строк. Внутренние соединения возвращают результат, когда в обеих таблицах есть хотя бы одна строка, соответствующая условиям соединения. Внутренние соединения исключают строки, не соответствующие ни одной строке в другой таблице. Однако внешние соединения возвращают все строки хотя бы из одной таблицы или представления, упомянутых в предложении FROM, если они удовлетворяют условиям поиска WHERE или HAVING. Все строки, получаемые из левой таблицы, образуют левое внешнее соединение, а строки, получаемые из правой таблицы, — правое внешнее соединение. Все строки их обеих таблиц возвращаются в полном внешнем соединении. Для внешних соединений в предложении FROM SQL Server использует ключевые слова ISO: LEFT OUTER JOIN или LEFT JOIN; RIGHT OUTER JOIN или RIGHT JOIN; FULL OUTER JOIN или FULL JOIN. Работа с левыми внешними соединениями Рассмотрим примеры. Рассмотрим соединение таблиц KAFEDRA и TEACHER по столбцам kod_kafedru. В результате будут выведены только те кафедры, для которых были написаны преподаватели. Чтобы включить в результаты все кафедры, независимо от того, были ли написаны их преподаватели, используйте левое внешнее соединение ISO. Пример запроса: Запрос 43. Вывести фамилии всех преподавателей с указанием их кафедры, если она есть. SELECT KAFEDRA.Name_Kafedru AS 'название кафедры', TEACHER.NAME_TEACHER AS 'фамилия преподавателя' FROM KAFEDRA LEFT OUTER JOIN TEACHER ON KAFEDRA.kod_kafedru = TEACHER.kod_kafedru; 127 Ключевые слова LEFT OUTER JOIN включают в вывод все строки таблицы KAFEDRA независимо от того, есть ли для них соответствующие значения в столбце kod_kafedru таблицы TEACHER . Обратите внимание на то, что в результатах, где для кафедры нет соответствующего преподавателя, строки содержат значение NULL в столбце Фамилия преподавателя Работа с правыми внешними соединениями Рассмотрим соединение таблиц KAFEDRA и TEACHER по столбцам kod_kafedru. Оператор правого внешнего соединения ISO, RIGHT OUTER JOIN, включает в результаты все строки второй таблицы независимо от того, есть ли для них совпадающие данные в первой таблице. Чтобы включить в результаты всех преподавателей независимо от того, есть ли связанные с ними кафедры, используйте правое внешнее соединение ISO. Пример запроса Transact-SQL и результаты правого внешнего соединения: Запрос 44. Вывести названия всех кафедр с указанием фамилий преподавателей, если они есть. SELECT KAFEDRA.Name_Kafedru AS 'название кафедры', TEACHER.NAME_TEACHER AS 'фамилия преподавателя' FROM KAFEDRA RIGHT OUTER JOIN TEACHER ON KAFEDRA.kod_kafedru = TEACHER.kod_kafedru; Внешнее соединение и условие отбора При внешнем соединении можно применять и дополнительные условия отбора строк. Как видно из следующих двух примеров, если условие относится к столбцам таблицы, к которой не применяется оператор внешнего соединения, то внешнее соединение происходит. Запрос 45. Вывести названия всех кафедр корпуса 1 с указанием их преподавателей, если они есть. SELECT KAFEDRA.Name_Kafedru AS 'название кафедры', TEACHER.NAME_TEACHER AS 'фамилия преподавателя' FROM KAFEDRA LEFT OUTER JOIN TEACHER ON KAFEDRA.kod_kafedru = TEACHER.kod_kafedru 128 WHERE KAFEDRA.NUM_KORPUSA = '1'; Запрос 46. Вывести названия всех кафедр с указанием их преподавателей, если они есть, ставка которых больше 3000. SELECT KAFEDRA.Name_Kafedru AS 'Название кафедры', TEACHER.NAME_TEACHER AS 'Фамилия преподавателя' FROM KAFEDRA RIGHT OUTER JOIN TEACHER ON KAFEDRA.kod_kafedru = TEACHER.kod_kafedru WHERE TEACHER.salary > 3000; Работа с полными внешними соединениями Чтобы сохранить в выводе не соответствующие друг другу строки из обеих таблиц, включив их в результаты соединения, используйте полное внешнее соединение. SQL Server предоставляет оператор полного внешнего соединения, FULL OUTER JOIN, включающий все строки из обеих таблиц вне зависимости от того, есть ли в них совпадающие значения. Использование перекрестных соединений Перекрестное соединение, не имеющее предложения WHERE, выполняет декартово произведение таблиц, вовлеченных в объединение. Размер результирующего набора декартова произведения вычисляется, как произведение количества строк в первой таблице на количество строк во второй таблице. Следующий пример показывает перекрестное соединение Transact-SQL. SELECT KAFEDRA.Name_Kafedru AS 'название кафедры', TEACHER.NAME_TEACHER AS 'фамилия преподавателя' FROM KAFEDRA CROSS JOIN TEACHER ORDER BY KAFEDRA.kod_kafedru; Результирующий набор содержит 297 строк (в KAFEDRA имеется 11 строк, а в таблице TEACHER существует 27 строк; 11, умноженное на 27, равно 297). Внешнее соединение трех и более таблиц В запросе может быть использовано внешнее соединение более чем двух таблиц. Хотя в операции соединения указываются всего две таблицы, предложение FROM может содержать несколько операций объединения. Это позволяет соединять в одном запросе несколько таблиц. При этом следует помнить, что если к столбцу таблицы А применен оператор внешнего соединения с таблицей В, то никакой другой столбец таблицы А не может содержать оператор внешнего соединения с таблицей, отличающейся от В. В следующем примере внешнее соединение применяется для трех таблиц — факультетов, кафедр и преподавателей. Запрос 47. Вывести список всех факультетов с указанием их кафедр и преподавателей. SELECT f.NAME_FACULTETA AS 'Факультет', k.Name_Kafedru AS 'Кафедра', t.NAME_TEACHER AS 'Преподаватель' FROM FACULTET f JOIN KAFEDRA k ON f.kod_faculteta =k.kod_faculteta JOIN TEACHER t ON k.kod_kafedru = t.kod_kafedru; 129 Следующий запрос Transact-SQL выполняет поиск наименований всех факультетов определенной кафедры и имена преподавателей этих кафедр. Обратите внимание, что ни один из соединяемых столбцов — ни kod_faculteta, ни kod_kafedru, не включается в результаты. Тем не менее, соединение возможно только при использовании Kafedrа в качестве промежуточной таблицы. Среднюю таблицу соединения, Kafedrа, можно назвать таблицей преобразования, или промежуточной таблицей, так как Kafedrа является промежуточной точкой объединения, которая находится между двумя другими участвующими в объединении таблицами. При наличии в инструкции нескольких операторов соединения, применяющихся либо при соединении более двух таблиц, либо при соединении более двух пар столбцов, выражения соединения могут быть связаны операторами AND или OR. Задание для практической работы №6 Для созданной базы данных, согласно номеру варианта, самостоятельно создать на языке Transact-SQL 15 многотабличных запросов: - 1 запрос с использованием декартового произведения двух таблиц; - 3 запроса с использованием соединения двух таблиц по равенству; - 1 запрос с использованием соединения двух таблиц по равенству и условием отбора; - 1 запрос с использованием соединения по трем таблицам; - создать копии ранее созданных запросов на соединение по равенству на запросы с использованием внешнего полного соединения таблиц (JOIN). - 1 запрос с использованием левого внешнего соединения; - 1 запрос на использование правого внешнего соединения; - 1 запрос с использованием симметричного соединения и удаление избыточности. Все программные инструкции команд SQL сохранять в файлах с расширением *.sql в папке ФИО_студента/Лаб6. Для каждого запроса сформулировать текстовое задание, которое должно быть выполнено к базе данных. Создать текстовый отчет, в котором отобразить sql-команды разработанных запросов и скриншоты результатов работы из СУБД SQL Server Management Studio. 130 ПРАКТИЧЕСКАЯ РАБОТА №7. СОЗДАНИЕ ЗАПРОСОВ НА ГРУППИРОВКУ И СОРТИРОВКУ ДАННЫХ. ЗАПРОСЫ НА ИЗМЕНЕНИЕ. ИСПОЛЬЗОВАНИЕ ВСТРОЕННЫХ ФУНКЦИЙ. 7.1. Цель работы Изучить используемый в реляционных СУБД оператор извлечения данных из таблиц SELECT и выполнение группировки и сортировки данных. Изучить синтаксис языка модификации данных. Научится использовать встроенные функции в запросах. 7.2. Исходные данные Исходными данными является индивидуальное задание и результат предыдущих практических работ. 7.3. Используемые программы Программа SQL Server Managmant Studio. 7.4. Задание Практическую работу следует выполнять в следующем порядке: 1. Изучить синтаксис создания запросов с использованием функций, группировки и сортировки данных, язык манипулирования данных на примерах запросов, использовать встроенные функции к учебной базе данных "University.mdf". 2. Выполнить в окне "SQL Editor" 41 запросов к базе данных "University.mdf", согласно приведенным в практической работе образцам выполнения запросов и сохранить их в файле "Lab7.sql" в своей рабочей папке. |