ЛАБОРАТОРНАЯ РАБОТА №9 ЗАПРОСЫ Язык SQL используется для реализации всех функциональных возможностей, необходимых для управления БД, в том числе и для : - организации данных - обработки данных - управления доступом. 1. Сформировать базу данных для своего проекта (таблицы должны быть в НФБН или 4 НФ). 2. Сформулировать и реализовать запросы следующих типов для своей базы данных: 1. С использованием оператора SELECT, с помощью которого можно получить доступ к данным, представленным как совокупность таблиц любой сложности. Синтаксис: SELECT <Список_выбора> [INТО<Новая_таблица>] FROM <Исходная_таблица> [WHERE <Условие_отбора>] [GROUP ВY<Ключи_группировки>] [HAVING<Условие_отбора>] [ORDER ВY<Ключи_сортировки> [ASC|DESC]]; Из приведенного синтаксиса видно,что обязательными являются только разделы SELECT и FROM, а остальные могут быть опущены. Очень часто требуется тем или иным образом ограничить набор строк, помещаемых в результирующую таблицу запроса. Это достигается с помощью указания в запросе предложения WHERE. Оно состоит из ключевого слова WHERE, за которым следует перечень условий поиска, определяющих те строки, которые должны быть выбраны при выполнении запроса. Существует пять основных типов условий поиска (или предикатов, если пользоваться терминологией ISO). • Сравнение. Сравниваются результаты вычисления одного выражения с результатами вычисления другого выражения. • Диапазон, Проверяется, попадает ли результат вычисления выражения в заданный диапазон значений. • Принадлежность к множеству. Проверяется, принадлежит ли результат вычисления выражения к заданному множеству значений. • Соответствие шаблону. Проверяется, отвечает ли некоторое строковое значение заданному шаблону. • Значение NULL. Проверяется, содержит ли данный столбец определитель NULL (неизвестное значение). В языке SQL можно использовать следующие операторы сравнения: = равенство < меньше > больше <= меньше или равно >= больше или равно <> не равно (стандарт ISO) != не равно (используется в некоторых диалектах) ЗАДАНИЕ: Создайте сравнение условий поиска. SELECT<Список_выбора> FROM<Исходная_таблица> WHERE<Условие _отбора>; 2. Более сложные предикаты могут быть построены с помощью логически операторов AND, OR или NOT, а также с помощью скобок, используемых для определения; порядка вычисления выражения (если это необходимо ил желательно). Вычисление выражений в условиях выполняется по следующим правилам. • Выражение вычисляется слева направо. • Первыми вычисляются подвыражения в скобках. • Операторы NOT выполняются до выполнения операторов AND и OR. • Операторы AND выполняются до выполнения операторов OR. ЗАДАНИЕ: Создайте сложные условия поиска. SELECT<Список_выбора> FROM<Иcxoднaя_тaблицa> WHERE<Условие _отбора> OR <Условие_отбора> ;. 3. Создайте диапазон (BETWEEN) SELECT<Cписок_выбора> FROM<Иcxoднaя_тaблицa> WHERE<Выражение> BETWEEN<нaчaлo_диaпaзoнa> АND<конец_диапазона>; 4. Создайте условие поиска с проверкой вхождения во множество ([NOT]IN) SELECT<Список_выбора> FROM<Иcxoднaя_тaблицa> WHERE<выражение> [NOT] IN(<выражение1 >,...,<выражениеN>); 5. Создайте условие поиска с указанием шаблонов (LIKE/ NOT LIKE) С помощью оператора LIKE можно выполнять сравнение выражения символьного типа с заданным шаблоном. SELECT<Список_выбора> FROM<Исходная_таблица> WHERE «Символьное выражение>[NOT] LIKE <образец>; <Образец> задает символьный шаблон для сравнения и заключается кавычки. % Символ процента представляет любую последовательность из нуля или более символов. Пример: SELECT .......... FROM ............ WHERE должность LIKE '%np%' - % может быть заменен в символьном выражении любым количеством произвольных символов. Например, %кош% позволяет отобрать слова: 'кошка', 'окошко', 'лукошко' и т.д. может быть заменен в символьном выражении любым, но только одним символом. Например 'программ_' позволяет отобрать слова 'программа', 'программы', но не 'программист'. 6. В общем случае строки в результирующей таблице SQL-запроса не упорядочены каким-либо определенным образом. Однако их можно требуемым образом отсортировать, для чего в оператор SELECT помещается фраза ORDER BY. Фраза ORDER BY включает список разделенных запятыми идентификаторов столбцов, по которым требуется упорядочить результирующую таблицу запроса. Идентификатор столбца может представлять собой либо его имя, либо номер, который идентифицирует элемент списка SELECT его позицией в этом списке. Самый левый элемент списка имеет номер 1, следующий — номер 2 и т.д. Номера столбцов могут использоваться в тех случаях, когда столбцы, по которым следует упорядочить результат, являются вычисляемыми, а фраза AS с указанием имени этого столбца в операторе SELECT отсутствует. Фраза ORDER BY позволяет упорядочить выбранные записи в порядке возрастания (ASC) или убывания (DESC) значений любого столбца или комбинации столбцов, независимо от того, присутствуют эти столбцы в таблице результатов или нет. Однако в некоторых диалектах требуется, чтобы фраза ORDER BY обязательно присутствовала в списке выборки оператора SELECT. В любом случае фраза ORDER BY всегда должна быть последним элементом в операторе SELECT. Полный синтаксис раздела ORDER BY следующий: ORDER BY {<условие_сортировки> [ASC| DESC]} [,...,n] Параметр <условие_сортировки> требует задания выражения, в соответствии с которым будет осуществляться сортировка строк. ЗАДАНИЕ: Создайте сортировку по значению одного столбца SELECT<Список__выбора> FROM<Иcxoднaя_тaблицa> . ORDER BY <условие сортировки> DESC; 7. Данные можно отсортировать по нескольким столбцам. Для этого необходимо ввести имена столбцов через запятую по порядку сортировки. Сначала данные сортируются по столбцу, имя которого было указано в разделе ORDER BY. Затем, если имеется множество строк с одинаковыми значениями в первом столбце, выполняется дополнительная сортировка этих строк по второму столбцу и т.д. ЗАДАНИЕ: Создайте сортировку по нескольким столбцам. 8. Создайте условия для вычисления полей Пример: Создайте отчет о ежемесячной зарплате всего персонала с указанием табельного номера, имени, фамилии и суммы зарплаты. SELECT sno, fname, Iname, salary/12 FROM staff; Значение salary- сумма зарплаты за год. В данном случае желаемый результат может быть достигнут простым делением суммы зарплаты за год на 12. 9. Очень часто в отчетах требуется формировать и промежуточные итоги. Для этой цели в операторе SELECT может указываться фраза GROUP BY. За прос, в котором присутствует фраза GROUP BY, называется группирующим запросом, поскольку в нем группируются данные, полученные в результате выполнения операции SELECT, после чего для каждой отдельной группы создается единственная суммарная строка. Столбцы, перечисленные во фразе GROUP BY, называются группируемыми столбцами, Стандарт ISO требует, чтобы предложение SELECT и фраза GROUP BY были тесно связаны между собой. При использовании в операторе SELECT фразы GROUP BY каждый элемент списка в предложении SELECT должен иметь единственное значение для всей группы. Более того, предложение SELECT может включать только следующие типы элементов. • имена столбцов; • обобщающие функции; • константы; • выражения, включающие комбинации перечисленных выше элементов. Все имена столбцов, приведенные в списке предложения SELECT, должны присутствовать и во фразе GROUP BY — за исключением случаев, когда имя столбца используется в обобщающей функции. Обратное правило не является справедливым — во фразе GROUP BY могут присутствовать имена столбцов отсутствующие в списке предложения SELECT. Если совместно с фразой GROUP BY используется предложение WHERE, то оно обрабатывается первым а группированию подвергаются только те строки, которые удовлетворяют условию поиска. Стандартом ISO определено, что при проведении группирования вес отсутствующие значения рассматриваются как равные. Если две строки таблицы в одном и том же группируемом столбце содержат значения NULL и идентичные значения во всех остальных непустых группируемых столбцах, они помещаются в одну и ту же группу. Во многих функциях допускается использование ключевых слов ALL и DISTINCT. Ключевое слово ALL выполняет агрегирование всех строк исходного набора данных. При указании ключевого слова DISTINCT будет выполнятся агрегирование только уникальных строк. Все повторяющиеся строки будут проигнорированы. По умолчанию выполняется агрегирование всех строк, то есть используется ключевое слово ALL. Синтаксис: GROUP BY [АLL]<условие_группировки> [,.. .,n] ЗАДАНИЕ: Создайте условие, которое позволяет выполнить группировку по каким -либо критериям .(для вашей базы) 10. Функция AVG()- вычисляет среднее значение для указанного столбца. Имеет синтаксис: AVG ([ALL| DISTINCT]<выражение>) ЗАДАНИЕ: Создайте условие вычисление среднего значения для вашего столбца ( может быть для зарплаты, количества и т.п.) 11. Функция COUNT()- подсчитывает количество строк в группе (при выполнении группировки) или количество строк результата запроса. Синтаксис функции COUNT: COUNT ({[АLL|DISTINCT]<выражение>}| *) Параметр <выражение> в простейшем случае представляет собой имя столбца. Указание символа (*) предписывает считать общее количество строк независимо от того, содержат ли они значения NULL или нет. ПРИМЕР: Определите количество персонала, работающего в каждом из отделений компании, а также их суммарную заработную плату. SELECT bno, COUNT(sno) AS count, SUM(salary) AS sum FROM staff GROUP BY bno ORDER BY bno; ЗАДАНИЕ : Создайте условие для счета количества строк. 12. Функция МАХ() - возвращает максимальное значение в указанном диапазоне. Эта функция может использоваться как в обычных запросах, так и в запросах, так и в запросах с группировкой. Синтаксис : МАХ ([ALL|DISTINCT]<Выражение>) ПРИМЕР: Вычисление максимальной заработной платы. SELECT MAX(salary) AS max, FROM staff; ЗАДАНИЕ: Создайте условие для определения максимального значения. 13. Функция MIN()- возвращает минимальное значение в указанном диапазоне. MIN ([ALL|DISTINCT]<выражение>) ПРИМЕР: Вычисление минимальной заработной платы. SELECT MIN(salary) AS min FROM staff; 14. Функция SUM()- выполняет обычное суммирование значений в указанном диапазоне. SUM ([АLL|DISTINCT]<выражение>) ЗАДАНИЕ: Создайте условие для выполнения суммирования значений. 15. Фраза Having предназначена для использования совместно с фразой GROUP BY для задания ограничений, указываемых с целью отбора тех групп, которые будут помещены в результирующую таблицу запроса. Хотя фраза Having и предложение WHERE имеют сходный синтаксис, их назначение различно. Предложение WHERE предназначено для фильтрации отдельных строк, используемых для группирования или помещаемых в результирующую таблицу запроса, тогда как фраза HAVING используется для фильтрации групп, помещаемых в результирующую таблицу запроса. Стандарт ISO требует, чтобы имена столбцов, используемые во фразе HAVING, обязательно присутствовали в списке фразы GROUP BY или применялись в обобщающих функциях. На практике условия поиска во фразе HAVING всегда включают, по меньшей мере, одну обобщающую функцию, в противном случае эти условия поиска должны быть помещены в предложение WHERE и применяться для отбора отдельных строк. (Не забывайте, что обобщающие функции не могут использоваться в предложении WHERE.) Фраза HAVING не является необходимой частью языка SQL — любой запрос, написанный с использованием фразы HAVING, может быть представлен в ином виде, без ее применения. ПРИМЕР: Для каждого отделения компании с численностью персонала более одного человека определите количество работающих и сумму их заработной платы. SELECT bno, COUNT(sno) AS count, SUM(salary) AS sum FROM staff GROUP BY bno HAVING COUNT(sno) > 1 ORDER BY bno; здесь используются дополнительные ограничения, указывающие на то, что нас интересуют сведения только о тех отделениях компании, в которых работает больше одного человека. Подобное требование налагается на группы, поэтому в запросе следует использовать фразу HAVING. ЗАДАНИЕ: Создайте условие для вашего ограничения 15. Использование законченных операторов SELECT, внедренных в тело другого оператора SELECT. Внешний (второй) оператор SELECT использует результат выполнения внутреннего (первого) оператора для определения содержания окончательного результата всей операции. Внутренние запросы могут быть помещены в предложения WHERE и HAVING внешнего оператора SELECT — в этом случае они получают название подзапросов, или вложенных запросов. Кроме того, внутренние операторы SELECT могут использоваться в операторах INSERT, UPDATE и DELETE . Существует три типа подзапросов. • Скалярный подзапрос возвращает значение, выбираемое из пересечения одного столбца с одной строкой, — т.е. единственное значение. В принципе, скалярный подзапрос может использоваться везде, где требуется указать единственное значение. • Строковый подзапрос возвращает значения нескольких столбцов таблицы, но в виде единственной строки. Строковый подзапрос может использоваться везде, где применяется конструктор строковых значений — обычно это предикаты. • Табличный подзапрос возвращает значения одного или больше столбцов таблицы, размещенные в более чем одной строке. Табличный подзапрос может использоваться везде, где допускается указывать таблицу — например, как операнд предиката IN. Подзапрос представляет собой инструмент создания временной таблицы, содержимое которой извлекается и обрабатывается внешним оператором. Подзапрос может указываться непосредственно после операторов сравнения (т.е. операторов =, <, >, <=, >=, о) в предложениях WHERE и HAVING. Текст подзапроса должен быть заключен в скобки. ЗАДАНИЕ: Создайте подзапрос для проверки неравенств. ПРИМЕР: Составьте список персонала, работающего в отделении компании, расположенном, на улице'Main St в доме 163. SELECT sno, fname, Iname, position FROM staff WHERE bno = (SELECT bno FROM branch WHERE street = ‘163 Main St’); Внутренний оператор SELECT (SELECT bno FROM branch ...) предназначен для определения номера отделения компании, расположенного по адресу 463 Main St. (Существует только одно подобное отделение компании, поэтому данный пример является примером скалярного подзапроса.) После получения номера требуемого ! отделения выполняется внешний подзапрос, предназначенный для выборки подробных сведений о работниках этого отделения. Иначе говоря, внутренний оператор SELECT возвращает таблицу, состоящую из единственного значения 'ВЗ'. Оно представляет собой номер того отделения компании, которое расположено в доме 163 на улице Main Street. В результате внешний оператор SELECT приобретает следующий вид: SELECT sno, fname, Iname, position FROM staff WHERE bno = ‘B3’; 16. Создайте подзапрос с использованием предиката IN ПРИМЕР: Составьте перечень сдаваемых в аренду объектов, за которые отвечают работники отделения компании, расположенного на улице 'Main St' в доме 163. SELECT pno, street, area, city, pcode, type, rooms, rent FROM property for rent WHERE sno IN (SELECT sno FROM staff WHERE bno = (SELECT bno FROM branch WHERE street = '163 Main St')); Первый, самый внутренний, запрос предназначен для определения номера отделения компании, расположенного по адресу '163 Main St'. Второй, промежуточный, запрос осуществляет выборку сведений о персонал е, работающем в этом отделении. В данном случае выбирается более одной строки данных, и поэтому во внешнем запросе нельзя использовать оператор сравнения =. Вместо него необходимо использовать ключевое слово IN. Внешний запрос осуществляет выборку сведений о сдаваемых в аренду объектах, за которые отвечают те работники компании, данные о которых были получены в результате выполнения промежуточного запроса. 17. Ключевые слова ANY и ALL могут использоваться с подзапросами, возвращающими один столбец чисел. Если подзапросу будет предшествовать ключевое слово ALL, условие сравнения считается выполненным только в том случае, если оно выполняется для всех значений в результирующем столбце подзапроса. Если записи подзапроса предшествует ключевое слово ANY., то условие сравнения будет считаться выполненным, если оно выполняется хотя бы для одного из значений в результирующем столбце подзапроса. Если в результате выполнения подзапроса будет получено пустое значение, то для ключевого слова ALL условие сравнения будет считаться выполненным, а для ключевого слова Ш — невыполненным. Согласно стандарту ISO дополнительно можно использовать ключевое слово SOME, являющееся синонимом ключевого слова ANY. ПРИМЕР: Найдите всех работников, чья зарплата превышает зарплату хотя бы одного работника отделения компании под номером 'ВЗ'. SELECT sno, fname, Iname, position, salary FROM staff WHERE salary > SOME (SELECT salary FROM staff WHERE bno =БЗ'); Хотя этот запрос может быть записан с использованием подзапроса, определяющего минимальную зарплату персонала отделения под номером 'ВЗ', после чего внешний подзапрос сможет выбрать сведения обо всем персонале компании, чья зарплата превосходит это значение , возможен и другой подход, заключающийся в использовании ключевых слов SOME/ANY. В этом случае внутренний подзапрос создает набор числовых значений (12 000, 18 000, 24 000), а внешний запрос выбирает сведения о тех работниках, чья зарплата больше любого из значений в этом наборе (фактически, больше минимального значения — 12 000). Подобный альтернативны метод можно считать более естественным, чем определение в подзапросе минимальной зарплаты. ЗАДАНИЕ: Создайте подзапрос с использованием одного из ключевых слов. 18. Для того чтобы объединить в результирующей таблице столбцы из нескольких исходных таблиц, необходимо выполнить операцию соединения. В языке SQL операция соединения используется для объединения информации из двух таблиц посредством образования пар связанных строк, выбранных из каждой таблицы. Помещаемые в объединенную таблицу пары строк составляются по равенству входящих в них значений указанных столбцов. Если необходимо получить информацию более чем из одной таблицы, то можно либо применить подзапрос, либо выполнить соединение таблиц. Если результирующая таблица запроса должна содержать столбцы из разных исходных таблиц, то целесообразно использовать механизм соединения таблиц. Для выполнения соединения достаточно в предложении FROM указать имена двух и более таблиц, разделив их запятыми, после чего включить в запрос предложение WHERE с определением столбцов, используемых для соединения указанных таблиц. Кроме того, вместо имен таблиц можно использовать назначенные им в предложении FROM псевдонимы. В этом случае имена таблиц и назначаемые им псевдонимы должны разделяться пробелами. Псевдонимы могут использоваться с целью квалификации имен столбцов во всех тех случаях, когда возможно появление неоднозначности. Кроме того, псевдонимы могут использоваться как сокращения имен таблиц. Если для таблицы определен псевдоним, он может использоваться в любом месте, где требуется указание имени этой таблицы. ПРИМЕР: Составьте список имен всех клиентов, которые уже осмотрели хотя бы один сдаваемый в аренду объект и сообщили свое мнение по этому поводу. SELECT r.rno, fname, Iname, pno, comment FROM renter r, viewing v WHERE r.rno = v.rno; В этом отчете требуется представить сведения как из таблицы Renter, так и из таблицы Viewing, поэтому при построении запроса мы воспользуемся механизмом соединения таблиц. В предложении SELECT перечисляются все столбцы, которые должны быть помещены в результирующую таблицу запроса. Обратите внимание, что для столбца с номером клиента (Rno) необходимо указать квалификатор — этот столбец может быть выбран из любой соединяемой таблицы, поэтому необходимо явно указать, значения какой таблицы нас интересуют. (В данном примере с тем же успехом можно было выбирать значения столбца Rno из таблицы Viewing.) Квалифицирование имени осуществляется посредством указания перед именем столбца имени той таблицы (или ее псевдонима), из которой он выбирается. В нашем примере используется значение 'г', заданное как псевдоним таблицы Renter. Для построения результирующих строк используются те строки исходных таблиц, которые имеют идентичное значение в столбце Rno. Это условие определяется посредством задания условия поиска r.rno=v.rno. Подобные столбцы исходных таблиц называют сочетаемыми столбцами. ЗАДАНИЕ : Создайте простое соединение таблиц. 19. В языке SQL можно использовать обычные операции над множествами — объединение (union), пересечение (intersection) и разность (difference), — позволяющие комбинировать результаты выполнения двух и более запросов в единую результирующую таблицу. Объединением двух таблиц А и В называется таблица, содержащая все строки, которые имеются в первой таблице (А), во второй таблице (В) или в обеих этих таблицах сразу. Пересечением двух таблиц называется таблица, содержащая все строки, присутствующие в обеих исходных таблицах одновременно. Разностью двух таблиц А и В называется таблица, содержащая все строки, которые присутствуют в таблице А, но отсутствуют в таблице В. Все эти операции над множествами графически представлены на рис. 1. (а)объединение (b)пересечение (с)разность Рис.1. Графическое представление операций над множествами (соединение, пересечение и разность) На таблицы, которые могут комбинироваться с помощью операций над множествами, накладываются определенные ограничения. Самое важное из них состоит в том, что таблицы должны быть совместимы по соединению — т.е. они должны иметь одну и ту же структуру. Это означает, что таблицы должны иметь одинаковое количество столбцов, причем в соответствующих столбцах должны размещаться данные одного и того же типа и длины. Обязанность убедиться в том, что значения данных соответствующих столбцов принадлежат одному и тому же домену, возлагается на пользователя. Например, мало смысла в том, чтобы объединять столбец с данными о возрасте работников с информации о количестве комнат в сдаваемых в аренду объектах, хотя оба столбца будут иметь один и тот же тип данных — SMALL INT. Три операции над множествами, предусмотренные стандартом ISO, носят название UNION, INTERSECT и EXCEPT. В каждом случае формат предложения с операцией над множествами должен быть следующим: operator [ALL] [CORRESPONDING [BY {columnl [,...]}]] Синтаксис UNION: Спецификация запроса_1> UNION[ALL] Спецификация запроса_2> UNION [ALL]] <Спецификация запроса_п> При указании фразы CORRESPONDING BY операция над множествами выполняется для указанных столбцов. Если задано только ключевое слово CORRESPONDING, а фраза BY отсутствует, операция над множествами выполняется для столбцов, которые являются общими для обеих таблиц. Если указано ключевое слово ALL, результирующая таблица может содержать дублирующиеся строки. Одни диалекты языка SQL не поддерживают операций INTERSECT и EXCEPT, а в других вместо ключевого слова EXCEPT используется ключевое слово MINUS. ПРИМЕР: Использование операции UNION Создайте список всех регионов, в которых либо находится отделение компании, либо располагаются сдаваемые в аренду объекты. (SELECT area или (SELECT * FROM branch FROM branch WHERE area IS NOT NULL) WHERE area IS NOT NULL) ONION UNION CORRESPONDING BY area (SELECT area (SELECT * FROM property for rent FROM property for rent WHERE area IS NOT NULL); WHERE area IS NOT NULL); Этот запрос выполняется посредством подготовки результирующей таблицы первого запроса и результирующей таблицы второго запроса с последующим слиянием обеих таблиц в единую результирующую таблицу, которая включает все строки из обеих промежуточных таблиц, но с удалением дублирующихся строк ЗАДАНИЕ : Создайте условия для объединения результатов выборки.