ГЛАВА 5 Язык sql- Формирование запросов к...

38
ГЛАВА 5 Язык SQL- Формирование запросов к базе данных История развития SQL SQ£ (Structured Query Language) Структурированный Язык Запросов - стан- дартный язык запросов по работе с реляционными БД. Язык SQL появился по- сле реляционной алгебры, и его прототип был разработан в конце 70-х годов в компании IBM Research. Он был реализован в первом прототипе реляционной СУБД фирмы IBM System R. В дальнейшем этот язык применялся во многих коммерческих СУБД и в силу своего широкого распространения постепенно стал стандартом «де-факто» для языков манипулирования данными в реляционных СУБД. Первый международный стандарт языка SQL был принят в 1989 г. (далее мы будем называть его SQL/89 или SQL1). Иногда стандарт SQU также называют стандартом ANSI/ISO, и подавляющее большинстро доступных на рынке СУБД поддерживают этот стандарт полностью. Однако развитие информационных тех- нологий, связанных с базами данных, и необходимость реализации переноси- мых приложений потребовали в скором времени доработки и расширения пер- вого стандарта SQL. В конце 1992 г. был принят новый международный стандарт языка SQL, кото- рый в дальнейшим будем называть SQL/92 или SQL2. И он не лишен недостат- ков, но в то же время является существенно более точным и полным, чем SQL/89. В настоящий момент большинство производителей СУБД внесли изменения в свои продукты так, чтобы они в большей степени удовлетворяли стандарту SQL2, В 1999 году появился новый стандарт, названный SQL3. Если отличия между стандартами SQL1 и SQL2 во многом были количественными, то стандарт SQL3 соответствует качественным серьезным преобразованиям* В SQL3 введены но- вые типы данных, при этом предполагается возможность задания сложных

Upload: others

Post on 06-Jul-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

ГЛАВА 5 Язык SQL-Формированиезапросов к базеданных

История развития SQLSQ£ (Structured Query Language) — Структурированный Язык Запросов - стан-дартный язык запросов по работе с реляционными БД. Язык SQL появился по-сле реляционной алгебры, и его прототип был разработан в конце 70-х годов вкомпании IBM Research. Он был реализован в первом прототипе реляционнойСУБД фирмы IBM System R. В дальнейшем этот язык применялся во многихкоммерческих СУБД и в силу своего широкого распространения постепенно сталстандартом «де-факто» для языков манипулирования данными в реляционныхСУБД.Первый международный стандарт языка SQL был принят в 1989 г. (далее мыбудем называть его SQL/89 или SQL1). Иногда стандарт SQU также называютстандартом ANSI/ISO, и подавляющее большинстро доступных на рынке СУБДподдерживают этот стандарт полностью. Однако развитие информационных тех-нологий, связанных с базами данных, и необходимость реализации переноси-мых приложений потребовали в скором времени доработки и расширения пер-вого стандарта SQL.В конце 1992 г. был принят новый международный стандарт языка SQL, кото-рый в дальнейшим будем называть SQL/92 или SQL2. И он не лишен недостат-ков, но в то же время является существенно более точным и полным, чем SQL/89.В настоящий момент большинство производителей СУБД внесли измененияв свои продукты так, чтобы они в большей степени удовлетворяли стандартуSQL2,В 1999 году появился новый стандарт, названный SQL3. Если отличия междустандартами SQL1 и SQL2 во многом были количественными, то стандарт SQL3соответствует качественным серьезным преобразованиям* В SQL3 введены но-вые типы данных, при этом предполагается возможность задания сложных

Page 2: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

История развития SQL - 67

структурированных типов данных, которые в большей степени соответствуютобъектной ориентации. Наконец, добавлен раздел, который вводит стандарты насобытия и триггеры, которые ранее не затрагивались в стандартах, хотя давноуже широко использовались в коммерческих СУБД. В стандарте определенывозможности четкой спецификации триггеров как совокупности события и дей-ствия. Б качестве действия могут выступать не только последовательность опе-раторов SQL, но и операторы управления ходом выполнения программы, В рам-ках управления транзакциями произошел возврат к старой модели транзакций,допускающей точки сохранения (savepoints), и возможность указания в операто-ре отката RQQLBACK точек возврата позволит откатывать транзакцию не в на-чало, а в промежуточную ранее сохраненную точку. Такое решение повышаетгибкость реализации-сложных алгоритмов обработки информации.

А зачем вообще нужны эти стандарты? Зачем их изобретают и почему надо изу-чать их? Текст стандарта SQL2 занимает 600 станиц сухого формального текста,это очень много, и кажется, что это просто происки разработчиков стандартов,а не то, что необходимо рядовым разработчикам, Однако ни один серьезныйразработчик, работающий с базами данных, не должен игнорировать стандарт,и для этого существуют весьма веские причины. Разработка любой информа-ционной системы, ориентированной на технологию баз данных (а других ин-формационных систем на настоящий момент, и не бывает), является трудоем-ким процессом, занимающим несколько десятков ц даже сотен человеко-месяцев.Следует отдавать себе отчет, что нельзя разработать сколько-нибудь серьезнуюсистему за несколько дней. Кроме того, развитие вычислительной техники, сис-тем телекоммуникаций и программного обеспечения столь стремительно, чтопроект может устареть еще до момента внедрения. Но развивается не тольковычислительная техника, изменяются и реальные объекты, поведение которыхмоделируется использованием как самой БД, так и процедур обработки инфор-мации в ней, то есть конкретных приложений, которые составляют реальное на-полнение разрабатываемой информационной системы, Именно поэтому проектинформационной системы должен быть рассчитан на расширяемость и перено-симость на другие платформы, Большинство поставщиков аппаратуры и про-граммного обеспечения следуют стратегии поддержки стандартов, в'противномслучае пользователи просто не будут их покупать. Однако каждый поставщикстремится улучшить свой продут введением дополнительных возможностей, невходящих в стандарт. Выбор разработчиков, следовательно, таков; ориентиро-ваться только на экзотические особенности данного продукта либо старатьсяв основном придерживаться стандарта. Во втором случае весь -интеллектуаль-ный труд, вкладываемый в разработку, становится более защищенным, так каксистема приобретает свойства переносимости, И в случае появления более пер-спективной платформы проект, ориентированный в большей степени на стан-дарты, может быть легче перенесен на нее, чем тот, который в основном ориен-тировался на особенности конкретной платформы. Кроме того, стандарты — этоверный ориентир для разработчиков, так как все поставщики СУБД в своихперспективных разработках обязательно следуют стандарту, и можно быть уве-ренным, что в конце концов стандарт будет реализован практически во всехперспективных СУБД. Так произошло со стандартом SQ.L1, так происходит состандартом SQL2 и так будет происходить со стандартом SQL3.

Page 3: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

68 Глава 5. Язык SQL. Формирование запросов к базе данных

Для поставщиков СУБД стандарт — это путеводная звезда, которая гарантируетправильное направление работ. А вот эффективность реализации стандарта '—это гарантия успеха.

SQL нельзя в полной мере отнести к традиционным языкам программирования,он не содержит традиционные операторы, управляющие ходом выполнения про-граммы, операторы описания типов и многое другой, он содержит только наборстандартных операторов доступа К данным, хранящимся в базе данных. Опера-торы SQL встраиваются в базовый язык программирования, которым может бытьлюбой стандартный язык типа C++, PL, COBOL и т. д. Кроме того, операторыSQL могут выполняться непосредственно в интерактивном режиме.

Структура SQLВ отличие от реляционной алгебры, где были представлены только операциизапросов к БД, SQL является полным языком, в нем присутствуют не толькооперации запросов, но и операторы, соответствующие DDL — Data DefinitionLanguage — языку описания данных. Кроме того, язык содержит операторы, пред-назначенные для управления (администрирования ) БД.

SQL содержит разделы, представленные в таблице 5.1:

Таблица 5.1. Операторы определения данных DDL

Оператор

CREATE TABLE

DROP TABLE

ALTER TABLE

CREATE VIEW

ALTER VIEW

DROP VIEW

CREATE INDEX

DROP INDEX

Смысл

Создать таблицу

Удалить таблицу

Изменить таблицу

Создать представление

Изменить представление

Удалить представ л ei те

Создать индекс

Удалить индекс

Действие

Создаст новую таблицу в БД

Удаляет таблицу из БД

Изменяет структуру существующейтаблицы или ограниченияцелостности, задаваемые дляданной таблицы

Создает виртуальную таблицу,соответствующую некоторому SQI--запросу

Изменяет ранее созданноепредставление

Удаляет ранее созданноепреде гавлсние

Создаст индекс для некоторойтаблицы для обеспечения быстрогодоступа по атрибутам, «ходящимв индекс

Удаляет ранее созданный индекс

Page 4: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Структура SQL 69

Таблица 5.2. Операторы манипулирования даннымиData Manipulation Language (DMP)

Оператор

DELETE

INSERT

UPDATE

Смысл

Удалить строки

Вставить строку

Обновить строку

Действие

Удаляет одну или несколько строк,,соответствующих условиям фильтрации, из базовойтаблицы. Применение оператора согласуетсяс принципами поддержки целостности, поэтомуэтот оператор не всегда может быть выполненкорректно, даже если синтаксически он записанправильно

Вставляет одну строку в базовую таблицу.Допустимы модификации оператора, при которыхсразу несколько строк могут быть перенесеныиз о;июй таблицы или запроса в базовую таблицу

Обновляет значения одного или несколькихстолбцов в одной или нескольких строках,соответствующих условиям фильтрации

Таблица 5.3. Язык запросов Data Query Language (DQL)

Оператор

SELECT

Смысл

Выбрать строки

Действие

Оператор, заменяющий все операторыреляционной алгебры п позволяющийсформировать результирующее отношение,соответствующее запросу ,

Таблица 5.4. Средства управления транзакциями'

Оператор

COMMIT

ROLLBACK

SAVEPOINT

Смысл

Завершить транзакцию

Откатить транзакцию

Сохранитьпромежуточную точкувыполнения транзакции

Действие

Завершить комплекснуювзаимосвязанную обработку информации,объединенную в транзакцию

Отменить изменения, проведенные в ходевыполнения транзакции

Сохранить промежуточное состояние БД,пометить его для того, чтобы можно былов дальнейшем к нему вернуться

Таблица 5.5. Средства администрирования данных

Оператор

ALTER DATABASE

ALTER DBAREA

Смысл

Изменить БД

Изменить областьхрапения БД

Действие

Изменить набор бсиовпых объектови базе данных, ограничений, касающихсявеси базы данных

Изменить ранее созданную областьхранения

Page 5: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

70 Глава 5. Язык SQL Формирование запросов к базе данных

Таблица 5.5 (продолжение)

Оператор

ALTER PASSWORD

CREATE DATABASE

CREATE DBAREA

DROP DATABASE

DROP DBAREA

GRANT

REVOKE

Смысл

Изменить пароль

Создать БД

Создать областьхранения

Удалить БД

Удалить областьхранения БД

Предоставитьправа

Лишить прав

Действие

Изменить пароль для всей базы данных

Создать новую базу дачных, определивосновные параметры для нес

Создать новую область храненияи сделать се доступной для размещенияданных

Удалить существующую базу данных(только в том случае, когда вы имеетеправо выполнить это действие)

Удалить существующую областьхранения (если в ней на настоящиймомент не располагаются активныеданные)

Предоставить права доступа на ряддействий нал некоторым объектом БД

Лишить прав доступа к некоторомуобъекту или некоторым действиямнад объектом

Таблица 5*6. Программный SQL

Оператор

DECLARE

OPEN

FETCH

CLOSE

PREPARE

Смысл

Определяет курсордля запроса

Открыть курсор

Считать строкуиз множества строк,определенныхкурсором

Закрыть курсор

Подготовитьоператор SQLк динамическомувыполнению

Действие

Задает некоторое имя и определяетсвязанный с ним запрос к БД,который соответствует виртуальномунабору данных

Формирует виртуальный наборданных, соответствующий описаниюуказанного курсора и текущемусостоянию БД

Считывает очередную строку,заданную параметром командыиз виртуального набора данных,соответствующего открытому курсору

Прекращает доступ к виртуальномунабору данных, соответствующемууказанному курсору

Сгенерировать план выполнениязапроса, соответствующего заданномуоператору SQL

Page 6: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Типы данных 71

Onepafop

EXECUTE

Смысл

Выполнить операторSQL, ранееподготовленныйк динамическомувыполнению

Действие

Выполняет ранее подготовленныйплан запроса

В коммерческих СУБД набор основных операторов расширен. В большинствоСУБД включены операторы определения и запуска хранимых процедур и опе-раторы определения триггеров.

Типы данныхВ языке SQL/89 поддерживаются следующие типы данных;

Q CHARA'CTER(n) или CHAR(n) - символьные строки постоянной длиныв п символов. При задании данного типа под каждое значение всегда отво-дится п символов, и если реальное значение занимает менее, чем п символов,то СУБД автоматически дополняет недостающие символы пробелами.

a NUMERIC[(n,m)] — точные числа, здесь п — общее количество цифр в чис-ле, m — количество цифр слева от десятичной точки.

Q DECIMAL[(n,m)] — точные числа, здесь п - общее количество цифр в чис-ле, m — количество цифр слева от десятичной точки.

Q DEC[(n,m)] - то же, что и DEClMAL[(n,m)].Q INTEGER или INT - целые числа.Q SMALLINT - целые числа меньшего диапазона.

Несмотря на То, Что в стандарте SQL1 не определяется точно, что подразумева-ется под типом INT и SMALLINT (это отдано на откуп реализации), указанотолько соотношение между этими типами данных, в большинстве реализацийтип данных INTEGER соответствует целым числам, хранимым в четырех бай-тах, a SMALLINT - соответствует целым числам, хранимым в двух байтах. Вы-бор одного из этих типов определяется размером числа.

Q FLOAT[(n)] — числа большой точности, хранимые в форме с плавающей точ-кой. Здесь п - число байтов, резервируемое под хранение одного числа. Диа-пазон чисел определяется конкретной реализацией,

р REAL - вещественный тип чисел, который соответствует числам с плаваю-щей точкой, меньшей точности, чем FLOAT.

Q DOUBLE PRECISION специфицирует тип данных с определенной в реали-зации точностью большей, чем определенная в реализации точность для REAL.

В стандарте SQL92 добавлены следующие типы данных:

Q VARCHAR(n) - строки символов переменной длины.Q NCHAR(N) - строки локализованных символов постоянной длины.

Page 7: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

72 Глава 5. Язык SQL. Формирование запросов к базе данных

Q NCHAR VARYING(n) — строки локализованных символов переменной длины.

Q ВГГ(п) — строка битов постоянной длины.

Р BIT VARYING(n) — строка битов переменной длины.Q DATE — календарная дата.

Q TIMESTAMP(точность) — дата и время.

Q INTERVAL — временной интервал.

Большинство коммерческих СУБД поддерживают еще дополнительные типы дан-ных, которые не специфицированы в стандарте. Так, например, практически всеСУБД в том или ином виде поддерживают тип данных для представления не-структурированного текста большого объема. Этот тип аналогичен типу MEMOв настольных СУБД. Называются эти типы по-разному, например в ORACLEэтот тип называется LONG, в DB2 - LONG VARCHAR, в SYBASE и MS SQLServer - TEXT.

Однако следует отметить, что специфика реализации отдельных типов данныхсерьезным образом влияет на результаты запросов к БД. Особенно это касаетсяреализации типов данных DATE и TIMESTAMP. Поэтому при переносе прило-жений будьте внимательны, на разных платформах они могут работать по-раз-ному, и одной из причин может быть различие в интерпретации типов данных.

При выполнении сравнений в операциях фильтрации могут использоватьсяконстанты заданных типов. В стандарте определены следующие константы. Длячисловых типов данных определены константы в виде последовательности цифрс необязательным заданием знака числа и десятичной точкой. То есть правиль-ными будут константы:

213-314 612.716 +551.702

Константы с плавающей запятой задаются, как и в большинстве языков про-граммирования, путем задания мантиссы и порядка, разделенных символом Е,например:

2.9Е-4 -134.235Е7 0.54267Е18

Строковые константы должны быть заключены в одинарные кавычки;

'Крылов Ю . Д . 1 'Санкт-Петербург'

В некоторых реализациях, например MS SQL Server и Informix, допустимы двой-ные кавычки в строковых константах;

"Москва" "New York"

Однако следует отметить, что использование двойных кавычек может вызватьдополнительные проблемы при переносе приложении на другую платформу, по-этому мы рекомендуем по возможности, избегать такого представления символь-ных констант.

Константы даты, времени и временного интервала в реляционных СУБД пред-ставляются в виде строковых копстаит. Форматы этих констант отличаются вразличных СУБД. Кроме того, формат представления даты различен в разныхстранах, В большинстве СУБД реализованы способы настройки форматов пред-

Page 8: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Типы данных 73

ставления дат или специальные функции преобразования форматив дат, каксделано, например, в СУБД ORACLE. Приведем примеры констант в MS SQLServer:

March 15. 1999 Маг 15 1999 3/15/19993-15-99 1999 MAR 15

В СУБД ORACLE та же константа запишется как

15-MAR-99

Кроме пользовательских констант в СУБД могут существовать и специальныесистемные константы. Стандарт SQL1 определяет только одну системную кон-станту USER, которая соответствует имени пользователя, под которым вы под-ключились к БД.

В операторах SQL могут использоваться выражения, которые строятся по стан-дартным правилам применения знаков арифметических операций сложения (+),вычитания (-), умножения (*) и деления (/). Однако в ряде СУБД операцияделения (/) интерпретируется как деление нацело, поэтому при построениисложных выражений вы можете получить результат, не соответствующий тра-диционной интерпретации выражения. В стандарт SQL2 включена возможностьвыполнения операций сложения и вычитания над датами* В большинстве СУБДтакже определена операция конкатенации над строковыми данными, обознача-ется она, к сожалению, по-разному. Так, например, для DB2 операция конкате-нации обозначается двойной вертикальной чертой, в MS SQL Server — знакомсложения (+), поэтому два выражения, созданные в разных СУБД, эквивалентны:

'Mr./Mrs. ' |] NAME I j ' ' LASTJAME

'Mr./Mrs. ' + NAME + ' ' LASTJAME

В стандарте SQL1 не были определены встроенные функции, однако в боль-шинстве коммерческих СУБД такие функции были реализованы, л в стандартSQL2 уже введен ряд стандартных встроенных функций;

Q В IT_LENGTH (строка) — количество битов в строке;

Q СА5Т(значепие AS тип данных) - значение, преобразованное в заданныйтип данных;

Q CHAR_LENGTH(cTpoKa) — длина строки символов;Q CONVERT(CTpOKa USING функция) - строка, преобразованная в соответ-

ствии с указанной функцией;

Q CURRENTJDATE - текущая дата;Q CURRENT_TlME(T04HOCTb) — текущее время с указанной точностью;

ГЛ CURRENTJTIMESTAMPCKWiiocTb) - текущие дата и время с указанной точ-ностью;

Q LOWER(CTpoKa) — строка, преобразованная к верхнему регистру;

Q OCTED_LENGTH(cTpoi<a) - число байтов в строке символов;Q POSITION( первая строка IN вторая строка) — позиция, с которой начина-

ется вхождение первой строки во вторую;

Page 9: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

74 Глава 5. Язык SQL Формирование запросов к базе данных

Q SUBSTRING(cipoKa FROM n FOR длина) — часть строки, начинающаясяс n-го символа и имеющая указанную длину;

Q TRANSLATE(cTpOKa USING функция) - строка, преобразованная с исполь-зованием указанной функции;

Q TRIM(BOTH символ FROM строка) — строка, у которой удалены все пер-вые и последние символы;

Q TRIM(LEADING символ FROM строка ) — строка, в которой удалены всепервые указанные символы;

О TRIM(TRAILING символ FROM строка) — строка, в которой удалены nb-следние указанные символы;

Q UPPER(cTpoKa) — строка, преобразованная к верхнему регистру.

Оператор выбора SELECTЯзык запросов (Data Query language) в SQL состоит из единственного операто-ра SELECT. Этот единственный оператор поиска реализует все операции реляци-онной алгебры. Как просто, всего один оператор. Однако писать запросы наязыке SQL (грамотные запросы) сначала совсем не просто. Надо учиться, также как надо учиться решать математические задачки или составлять алгоритмыдля решения непростых комбинаторных задач. Один и тот же запрос может бытьреализован несколькими способами, и, будучи все правильными, они, тем не ме-нее, могут существенно отличаться по времени исполнения, и это особенно важ-но для больших баз данных.

Синтаксис оператора SELECT имеет следующий вид:

SELECT [ALL j DISTINCT] «писок полей> | *)

FROM <Список таблиц>

[WHERE <Предикат-условие выборки или соединения;*][GROUP BY <Список полей результата:*]

[HAVING <Предикат-условие для группы>][ORDER BY <Список полей, по который упорядочить вывод>]

Здесь ключевое слово ALL означает, что в результирующий набор строк включа-ются все строки, удовлетворяющие условиям запроса. Значит, в результирующийнабор могут попасть одинаковые строки. И это нарушение принципов теорииотношений (в отличие от реляционной алгебры, где по умолчанию предполага-ется отсутствие дубликатов в каждом результирующем отношении). Ключевоеслово DISTINCT означает, что в результирующий набор включаются только раз-личные строки, то есть дубликаты строк результата не включаются в набор.

Символ *. (звездочка) означает, что в результирующий набор включаются всестолбцы из исходных таблиц запроса.

В разделе FROM задается перечень исходных отношений (таблиц) запроса.

Page 10: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Оператор выбора SELECT 75

В разделе WHERE задаются условия отбора строк результата или условия соедине-ния кортежей исходных таблиц, подобно операции условного соединения'в ре-ляционной алгебре.

В разделе GROUP BY задается список полей группировки.В разделе HAVING задаются предикаты-условия, накладываемые на каждую группу,

В Части ORDER BY задается список полей упорядочения результата, то есгь списокполей, который определяет порядок сортировки в результирующем отношении.Например, если первым полем списка будет указана Фамилия, а вторым Номергруппы, то в результирующем отношении сначала будут собраны в алфавтномпорядке студенты, и если найдутся однофамильцы, то они будут расположены' впорядке возрастания номеров групп,

В выражении условий раздела WHERE могут быть использованы следующие пре-дикаты:

Q Предикаты сравнения { =. <>, >,<, >=,<« }, которые имеют традиционныйсмысл,

Q Предикат Between A and В — принимает значения между А и В. Предикатистинен, когда сравниваемое значение попадает в заданный диапазон, вклю-чая границы диапазона. Одновременно в стандарте задан и противополож-ный предикат Not Between A and В, который истинен тогда, когда сравниваемоезначение не попадает в заданный интервал, включая его границы.

Q Предикат вхождения в множество IN (нноиество) истинен тогда, когда срав-ниваемое значение входит в множество заданных значений. При этом мно-жество значений может быть задано простым перечислением или встроен-ным подзапросом. Одновременно существует противоположный предикатNOT IN (множество), который истинен тогда, когда сравниваемое значение невходит в заданное множество,

Q Предикаты сравнения Q образцом LJKE и NOT LIKE. Предикат LIKE требует зада-ния шаблона, с которым сравнивается заданное значение, предикат истинен,если сравниваемое значение соответствует шаблону, и ложен в противномслучае. Предикат NOT LIKE имеет противоположный смысл.По стандарту в шаблон могут быть включены специальные символы:О символ подчеркивания (J — для обозначения любого одиночного символа;О символ процента (*) — для обозначения любой произвольной последова-

тельности символов;О остальные символы, заданные в шаблоне, обозначают самих себя,

d Предикат сравнения с неопределенным значением IS NULL. Понятие неопре-деленного значения было внесено в концепции баз данных позднее. Неопре-деленное значение интерпретируется в реляционной модели как значение,неизвестное на данный момент времени. Это значение при появлении Допол-нительной информации в любой момент времени может быть заменено нанекоторое конкретное значение. При сравнении неопределенных значений недействуют стандаргные правила сравнения: одно неопределенное значениеникогда не считается равным другому неопределенному значению, Для вы-

Page 11: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

76 Глава 5. Язык SQL Формирование запросов к базе данных

явления равенства значения некоторого атрибута неопределенному применя-ют специальные стандартные предикаты;

<имя атрибута>15 NULL и <имя, атрибута> IS NOT NULL.

Если в данном кортеже (в данной строке) указанный атрибут имеет неопреде-ленное значение, то предикат IS NULL принимает значение «Истина» (TRUE), а пре-дикат IS NOT NULL — «Ложь» (FALSE), в лротивпом случае предикат IS NULL прини-мает значение «Ложь», а предикат IS NOT NULL принимает значение «Истина».

'Введение Null-значений вызвало необходимость модификации классической дву-значной логики и превращения ее в трехзначную. Все логические операции, про-изводимые с неопределенными значениями, подчиняются этой логике в соот-ветствии с заданной таблицей истишюсти:

А

TRUE

TRUE

TRUE

FALSE

FALSE

FALSE

Null

Null

Null

В

TRUE

FALSE

Null ' '

TRUE

FALSE

Null

TRUE

FALSE

Null

Not A

FALSE

FALSE

FALSE

TRUE

TRUE

TRUE

Null

Null

Null

А Л В

TRUE

FALSE

Null

FALSE

FALSE

FALSE

Null

FALSE

Null

A V B

TRUE

TRUE

TRUE

TRUE

FALSE

Null

TRUE

Null

Null

Q Предикаты существования EXIST и несуществования NOT EXIST. Эти предика-ты относятся к встроенным подзапросам, и подробнее мы рассмотрим их, ко-гда коснемся вложенных подзапросов.

В условиях поиска могут быть использованы все рассмотренные ранее предикаты.Отложив иа время знакомство с группировкой, рассмотрим детально первые тристроки оператора SELECT;

D SELECT — ключевое слово, которое сообщает СУБД, что эта команда — запрос.Все запросы начинаются этим словом с последующим пробелом. За ним мо-жет следовать способ выборки — с удалением дубликатов (DISTINCT) или безудаления (ALL, подразумевается по умолчанию). Затем следует список перс-численных через запятую столбцов, которые выбираются запросом из таб-лиц, или символ '*' (звездочка) для выбора всей строки. Любые столбцы, неперечисленные здесь, не будут включены в результирующее отношение, со-ответствующее выполнению команды. Это, конечно, не значит, что они будутудалены или их информация будет стерта из таблиц, потому что запрос невоздействует на информацию в таблицах — он только показывает данные.

Q FROM — ключевое слово, подобно SELECT, которое должно быть предсгавлеиов каждом запросе. Оно сопровождается пробелом и затем именами таблиц,

Page 12: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Оператор выбора SELECT 77

используемых в качестве источника информации. В случае если указано бо-лее одного имени таблицы, неявно подразумевается, что над перечисленнымитаблицами осуществляется операция декартова произведет гя. Таблицамможно присвоить имена-псевдонимы,'что бывает полезно для осуществленияоперации соединения таблицы с самой собою или для доступа из вложенно-го подзапроса к текущей записи внешнего запроса (вложенные подзапросыздесь не рассматриваются).

Все последующие разделы оператора SELECT являются необязательными.

Самый простои запрос SELECT без необязательных частей соответствует простодекартову произведению. Например, выражение

SELECT *

FROM Rl, R2

соответствует декартову произведению таблиц R1 и R2.

Выражение

SELECT Rl.A. R2.B

FROM Rl. R2

соответствует проекции декартова произведения двух таблиц на два столбца Аиз таблицы R1 и В из таблицы R2, при этом дубликаты всех строк сохранены, в от-личие от операции проектирования в реляционной алгебре, где при проектиро-вании по умолчанию все дубликаты кортежей уничтожаются.

Q WHERE — ключевое слово, за которым следует предикат — условие, налагае-мое на запись в таблице, которому она должна удовлетворять, чтобы попастьв выборку, аналогично операции селекции в реляционной алгебре.

Рассмотрим базу данных, которая моделирует сдачу сессии в некотором учеб-ном заведении, Пусть она состоит из трех отношений RI, R2, Кз- Будем считать,что они представлены таблицами Rl, R2 и R3 соответственно.

RI •= (ФИО, Дисциплина, Оценка); R2

и (ФИО, Группа);

Кз " (Группы, Дисциплина )

R1

ФИО

Пе1ров Ф. И.

Сидоров К. А.

Миронов Л. В.

Степанова К. Е.

Крылова Т. С.— •- .. 1 1 1 "• • ' '" •

Сидоров К. Л.

Степанова 1C Е.

Крылова Т. С.

Дисциплина

Базы данных

Базы данных

Базы данных

Базы данных

Базы данных

Теория информации

Теория информации

Теория информации

Оценка

5

Л

2

2

5

4

2

5

Page 13: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

78 Глава 5. Язык SQL Формирование запросов к базе данных

R1

ФИО

Миронов А. В.

Владимиров В. А.

Трофимов П. А.

Иванова Е. А.

Уткина Н. В.

Владимиров В. А.

Трофимов П. А.

Иванова Е. А.

Петров Ф. И.

Дисциплина

Теория информации

Базы данных

Сети и телекоммуникации

Сети и телекоммуникации

Сети и телекоммуникации

Английский язык

Английский язык

Английский язык

Английский язык

Оценка

Null

5

4

5

5

4

5

3

5

R2

ФИО

Петров Ф. И.

Сидоров К. А.

Миронов А. В.

Крылова Т. С.

Владимиров В. А.

Трофимов П.. А,

Иванова Е. А.

Уткина Н. В.

Группа

4906

4906

4906

4906

4906

4807

4807

4807

R3

Группа

4906

4906

4906

4807

4807

Дисциплина

Базы данных

Теория информации

Английский язык

Английский язык

Сети и телекоммуникации

Приведем несколько примеров использования оператора SELECT.

Q Вывести список всех групп (без повторений), где должны пройти экзамены,

SELECT DISTINCT Группы

FROM R3

Page 14: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Оператор выбора SELECT 79

Результат:

Q Вывести список студентов, которые сдали экзамен по дисциплине «Базы дан-ных» на «отлично».

SELECT ФИОFROM R1WHERE Дисциплина = "Базы данных" AND Оценка » 5

Результат:

Q Вывести список всех студентов, которым надо сдавать экзамены с указаниемназваний дисциплин, по которым должны проводиться эти экзамены.

SELECT ФИО.ДисциплинаFROM R2.R3WHERE R2,Группа - R2,Группа;

Здесь часть WHERE задает условия соединения отношений R2 и R3, при отсут-ствии условий соединения в части WHERE результат будет эквивалентен рас-ширенному декартову произведению, и в этом случае каждому студенту былибы приписаны все дисциплины из отношения R3» а не те, которые должнасдавать его группа.Результат:

ФИО

Петров Ф, И,Сидоров К. А.

Миронов А. В,

Степанова К. Е,Крылова Т. С.Владимиров В. А.Петров Ф. И.Сидоров К. А.Миронов А. В,

Степанова К. Е,

ДисциплинаБазы данныхБазы данных

Базы данныхБазы данных

Базы данныхБазы данныхТеория информацииТеория информацииТеория информацииТеория информации

Группа

4906

4807

ФИОПетров Ф. И.Крылова Т. С.

Page 15: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

80 Глава 5. Язык SQL. Формирование запросов к базе данных

ФИО

Крылова Т. С.

Владимиров В, А.

Петров Ф. И.

Сидоров К. А.

Миронов А. В.

Степанова К. Е.

Крылова Т. С.

Владимиров В. А.

Трофимов П. А.

Иванова Е. А.

Уткина Н. В.

Трофимов П. А.

Иванова Е. А.

Уткина Н, В.

Дисциплина

Теория информации

Теория информации

Английский язык

Английский язык

Английский язык

Английский язык

Английский язык

Английский язык

Сети и телекоммуникации

Сети и телекоммуникации

Сети и телекоммуникации

Английский язык

Английский язык

Английский язык

Q Вывести список лентяев, имеющих несколько двоек.

SELECT DISTINCT Ш.ФИО

FROM Rl a, Rl b

WHERE a.ФИО = Ь.ФИО AND

a.Дисциплина о b.Дисциплина ANDа.Оценка <=* 2 AND b,Оценка <= 2;

Здесь мы использовали псевдонимы для именования отношения RI а и Ь, таккак для записи'условий поиска нам необходимо работать сразу с двумя экзем-плярами данного отношения.Результат:

Из этих примеров хорошо видно, что логика работы оператора выбора (декар-тово произведеиие-селекция-проекция) не совпадает с порядком описанияв нем данных (сначала список полей для проекции, потом список таблиц дляДекартова произведения, потом условие соединения). Дело в том, что SQL изна-чально разрабатывался для применения конечными пользователями, и его стре-мились сделать возможно ближе к языку естественному, а не к языку алгорит-мическому. По этой причине SQL на первых порах вызывает путаницу ираздражение у начинающих его изучать профессиональных программистов, ко-торые привыкли разговаривать с машиной именно на алгоритмических языках.

ФИО

Степанова К. Е.

Page 16: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Задания для самостоятельной работы 81

Наличие неопределенных (Null) значений повышает гибкость обработки инфор-мации, хранящейся в БД. В наших примерах мы можем предположить ситуа-цию, когда студент пришел на экзамен,' но не сдавал его по некоторой причине,в этом случае оценка по некоторой дисциплине для данного студента имеет не-определенное значение. В данной ситуации, можно поставить вопрос: «Найтистудентов, пришедших па экзамен, но не сдававших его с указанием названиядисциплины». Оператор SELECT будет выглядеть следующим образом:

SELECT ФИО, Дисциплина

FROM R1

WHERE Оценка IS NULL

Результат;

ФИО

Миронов А. В.

Дисциплина

Теория информации

Применение агрегатных функцийи вложенных запросовв операторе выбораВ SQL добавлены дополнительные функции, которые позволяют вычислять обоб-щенные групповые значения. Для применения агрегатных функций предполага-ется предварительная операция группировки. В чем состоит суть операциигруппировки? При группировке все множество кортежей отношения разбивает-ся на группы, в Которых собираются кортежи, имеющие одинаковые значенияатрибутов, которые заданы в списке группировки.

Например, сгруппируем отношение R1 по значению столбца Дисциплина. Мы по-лучим 4 группы, для которых можем вычислить некоторые групповые значения»например количество кортежей в группе, максимальное или минимальное зна-чение столбца Оценка.

Это делается с помощью агрегатных функций. Агрегатные функции вычисляютодиночное значение для всей группы таблицы. Список этих функций представ-лен в таблице 5.7.

Таблица 5.7. Агрегатные функции

Функция

COUNT

SUM

AVG

MIN

MAX

Результат

Количество строк пли непустых значений нолей, которые ныбрал запрос

Сумма всех выбранных значений данного ноля

Среднеарифметическое значение

Наименьшее из всех выбранных

Наибольшее из иссх выбранных

всех выбранных значений данного поля

знамений данного поля

значений данного ноля

Page 17: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

82 Глава 5. Язык SQL Формирование запросов к базе данных

R1

Группа 1

Группа 2

Группа 3

Группа 4

ФИО

Петров Ф. И»

Сидоров К. А.

Миронов А. В.

Степанова К. Е

Крылова Т. С.

Владимиров В. А.

Сидоров К. А.

Степанова К. Е.

Крылова Т. С.

Миронов А. В.

Трофимов П. А.

Иванова Е. А.

Уткина Н. В.

Владимиров В, А.

Трофимов П, А,

Иванова Е. А.

Петров Ф. И.

Дисциплина

Базы данных

Базы данных

Базы данных

Базы данных

Базы данных

Базы данных

Теория информации

Теория информации

Тдория информации

Теория информации

Сети и телекоммуникации

Сети и телекоммуникации

Сети и телекоммуникации

Английский язык

Английский язык

Английский язык

Английский язык

Оценка

5

4

2

2

5

5

4

2

5

Null

4

5

5

4

5

3

5

Агрегатные функции используются подобно именам полей в операторе SELECT,но с одним исключением: они берут имя поля как аргумент. С функциями SUMи AVG могут использоваться только числовые поля. С функциями COUNT, MAX и MINмогут использоваться как числовые, так и символьные поля. При использова-нии с символьными полями МАХ и MIN будут транслировать их в эквивалентASCII кода и обрабатывать в алфавитном порядке, Некоторые СУБД позволя-ют использовать вложенные агрегаты, но это является отклонением от стандар-та ANSI со всеми вытекающими отсюда последствиями.Например, можно вычислить количество студентов, сдававших экзамены по каж-дой дисциплине, Для этого надо'выполнить запрос с группировкой по полю«Дисциплина* и вывести в качестве результата название дисциплины и количе-ство строк в группе по данной дисциплине. Применение символа * в качествеаргумента функции COUNT означает подсчет всех строк в группе.

SELECT ^.Дисциплина, COUNT(*)FROM Rl

GROUP BY Rl.Дисциплина

Результат;

Page 18: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Применение агрегатных функций и вложенных запросов в операторе выбора 83

Дисциплина

Базы данных

Теория информации

Сети и телекоммуникации

Английский язык

COUNTH

6

4

3

4

Если же мы хотим сосчитать количество сдавших экзамен по какой-либо дисци-плине, то нам необходимо исключить неопределенные значения из исходногоотношения перед группировкой. В этом случае запрос будет выглядеть следую-щим образом:

SELECT R1.Дисциплина, С01Ш*)

FROM R1

WHERE R1.Оценка IS NOT NULL

GROUP BY Rl.Дисциплина

Получим результат:

Дисциплина

Базы данных

Теория информации

Сети и телекоммуникации

Английский язык

COUNT(*)

63'

3

4

не попадет в набор кортежей перед группировкой, поэтому количество корте-жей в группе для дисциплины «Теория информации» будет на 1 меньше,

Можно применять агрегатные функции также п без операции предварительнойгруппировки, в этом случае все отношение рассматривается как одна группа идля этой группы можно вычислить одно значение на группу.

Обратившись снова к базе данных «Сессия» (таблицы Rl, R2, R3), найдем коли-чество успешно сданных экзаменов:

SELECT COUNT(*)

FROM Rl

WHERE Оценка > 2:

Это, конечно, отличается от выбора поля, поскольку всегда возвращается оди-ночное значение, независимо от того, сколько строк находится в таблице. Аргу-ментом агрегатных функций могут быть отдельные столбцы таблиц. Но для

Миронов А. В. Теория информации Null

В этом случае строка со студентом

Page 19: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

84 Глава6. Язык SQL. Формирование запросов к базе данных

того, чтобы вычислить, например, количество различных значений некоторогостолбца в группе, необходимо применить ключевое слово DISTINCT совместнос именем столбца. Вычислим количество различных оценок, полученных по каж-дой дисциплине:

SELECT ^.Дисциплина. COUNTCDISTINCT R1.Оценка)

FROM R1

WHERE Rl-Оценка IS NOT NULL

GROUP BY Rl.Дисциплина

Результат:

Дисциплина

Вазы данных

Теория информации

Сети и телекоммуникации

Английский язык

COUNT(DISTINCT R1 .Оценка)

3

3

2

3

В результат можно включить значение поля группировки и несколько агрегат-ных функций, а в условиях группировки можно использовать несколько полей.При этом группы образуются по набору заданных полей группировки. Опера-ции с агрегатными функциями могут быть применены к объединению множест-ва исходных таблиц. Например, поставим вопрос: определить для каждой груп-пы и каждой дисциплины количество успешно сдавших экзамен и средний баллпо дисциплине.

SELECT R2.Группа. R1.Дисциплина. COUNTt*). AVR(04eHKa)

FROM R1.R2

WHERE Rl.WO •= R2.ФИО AND

Rl.Оценка IS NOT NULL AND

Rl.Оценка > 2

GROUP BY R2.Группа. К.Дисциплина

Результат:

Дисциплина

Базы данных

Теория информации

Сети и телекоммуникации

Английский язык

COUNTO6

3

3

4

АУВ(Оценка)

3.83

3.67

4.66

4.25

Мы не можем использовать агрегатные функции в предложении WHERE, потомучто предикаты оцениваются в терминах одиночной строки, а агрегатные функ-ции — в терминах групп строк.

Page 20: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Применение агрегатных функций и вложенных запросов в операторе выбора 85

Предложение GROUP BY позволяет определять подмножество значений в особомполе в терминах другого поля и применять функцию агрегата к подмножеству,Это дает возможность объединять поля и агрегатные функции в едином предло-жении SELECT. Агрегатные функции могут применяться как в выражении выводарезультатов строки SELECT, так и в выражении условия обработки сформирован-ных групп HAVING. В этом случае каждая агрегатная функция вычисляется длякаждой выделенной группы. Значения, полученные при вычислении агрегатныхфункций, могут быть использованы для вывода соответствующих результатовили для условия отбора групп.

Построим запрос, который выводит группы, в которых по одной дисциплине наэкзаменах получено больше одной двойки:

SELECT R2.Группа

FROM R1.R2

WHERE Rl.OMO - R2.0HO AND

R1.Оценка « 2GROUP BY R2.Группа . Rl.Дисциплина

HAVING count(*)> 1

В дальнейшем в качестве примера будем работать не с БД «Сессия», а с БД«Банк», состоящей из одной таблицы F, в которой хранится отношение F, содер-жащее информацию о счетах в филиалах некоторого банка:

F •= (N, ФИО, Филиал, ДатаОткрытия, ДатаЗакрытия, Остаток);

Q, = (Филиал, Город);

поскольку на этой базе можно ярче проиллюстрировать работу с агрегатнымифункциями и группировкой.

Например, предположим, что мы хотим найти суммарный остаток на счетахD филиалах. Можно сделать раздельный запрос для каждого из них, выбравЗимсОстаток) из таблицы для каждого филиала. GROUP BY, однако, позволит помес-тить их все в оДну команду:

SELECT Филиал. SUM(OcTaroK)

FROM F

GROUP BY Филиал;

GROUP BY применяет агрегатные функции независимо для каждой группы, опре-деляемой с помощью значения поля Филиал. Группа состоит из строк с одина-ковым значением поля Филиал, п функция SUM применяется отдельно для каждойтакой группы, то есть суммарный остаток па счетах подсчитывается отдельноДля каждого филиала. Значение поля, к которому применяется GROUP BY, имеет,по определению, только одно значение на группу вывода, Как и результат рабо-ты агрегатной функции. Поэтому мы можем совместить в одном запросе агре-гат и поле. Вы можете также использовать GROUP BY с несколькими полями.Предположим, что мы хотели бы увидеть только те суммарные значения остат-ков на счетах, которые превышают $5000. Чтобы увидеть суммарные остатки

Page 21: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

86 Глава 5, Язык SQL. Формирование запросов к базе данных

свыше $5000, необходимо использовать предложение HAVING. Предложение HAVINGопределяет критерии, используемые, чтобы удалять определенные группы из вы-вода, точно так же как предложение WHERE делает это для индивидуальных строк.Правильной командой будет следующая:

SELECT Филиал, SUM(QcTaTOK)

FROM F

GROUP BY Филиал

HAVING $им(0статок> > 5000;

Аргументы в предложении HAVING подчиняются тем же самым правилам, что ив предложении SELECT, где используется GROUP BY. Они должны иметь однозначение на группу вывода.Следующая команда будет запрещена:

SELECT Филиал,ЗиМ(Остаток)

FROM F

GROUP ВУ ФилиалHAVING ДатаОткрытия - 27/12/1999:

Поле ДатаОткрытия не может быть использовано в предложении HAVING, потомучто оно может иметь больше чем одно значение на группу вывода. Чтобы избе-жать такой ситуации, предложение HAVING должно ссылаться только на агрегатыи поля, выбранные GROUP BY. Имеется правильный способ сделать вышеупомяну-тый запрос:

SELECT Филиал,5иМ(Остаток)

-FROM F

WHERE ДатаОткрытия - '27/12/1999'

GROUP BY Филиал;

Смысл данного запроса следующий: найти сумму остатков по каждому филиалусчетов, открытых 27 декабря 1999 года.Как и говорилось ранее, HAVING может использовать только аргументы, которыеимеют одно значение на группу вывода. Практически, ссылки па агрегатныефункции — наиболее общие, но и поля, выбранные с помощью GROUP BY, такжедопустимы. Например, мы хотим увидеть суммарные остатки на счетах филиа-лов в Санкт-Петербурге, Пскове и Урюпинске:

SELECT Филиал, SUH(OcraTOK)FROM F.Q

WHERE F.Филиал = Q.ФилиалGROUP BY Филиал

HAVING Филиал IN ("Санкт-Петербург". "Псков", "Урюпинск");

Поэтому в арифметических выражениях предикатов, входящих в условие вы-борки раздела HAVING, прямо можно использовать только спецификации столб-

Page 22: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Вложенные запросы 87

цов, указанных в качестве столбцов группирования в разделе GROUP BY. Осталь-ные столбцы можно специфицировать только внутри спецификаций агрегатныхфункций COUNT, SUM, AVG, MIN и MAX, вычисляющих в данном случае некоторое агре-гатное значение для всей группы строк. Аналогично обстоит дело с подзапроса-ми» входящими в предикаты условия выборки раздела HAVING: если в подзапросеиспользуется характеристика текущей группы, то она может задаваться толькопутем ссылки на столбцы группирования.

Результатом выполнения раздела HAVING является сгруппированная таблица, со-держащая только те группы строк, для которых результат вычисления условияпоиска есть TRUE, В частности, если раздел HAVING присутствует в табличном вы-ражении, не содержащем GROUP BY, то результатом его выполнения будет либопустая таблица, либо результат выполнения предыдущих разделов табличноговыражения, рассматриваемый как одна группа без столбцов группирования.

Вложенные запросыТеперь вернемся к БД «Сессиям и рассмотрим на ее примере использованиевложенных запросов,

С помощью SQL можно вкладывать запросы внутрь друг друга. Обычно внут-ренний запрос генерирует значение, которое проверяется в предикате внешнегозапроса (в предложении WHERE или HAVING),' определяющего, верно оно или нет.Совместно с подзапросом можно использовать предикат EXISTS, который возвра-щает истицу, если вывод подзапроса не п^ст.

В сочетании с другими возможностями оператора выбора, такими как группи-ровка, подзапрос представляет собой мощное средство для достижения нужно-го результата. В части FROM оператора SELECT допустимо применять синонимык именам таблицы, если при формировании запроса нам требуется более чемодин экземпляр некоторого отношения. Синонимы задаются с использованиемключевого слова AS, которое может быть вообще опущено. Поэтому часть FROMможет выглядеть следующим образом:

FROM Rl AS A, Rl AS В

или

FROM Rl A, Rl В;

оба выражения эквивалентны и рассматриваются как применения оператораSELECT к двум экземплярам таблицы R1.Например, покажем, как выглядят на SQL некоторые запросы к БД «Сессия»:

Q Список iex, кто сдал все положенные экзамены.

SELECT ФИО

FROM Rl as a

WHERE Оценка > 2

GROUP BY ФИО

HAVING COUNTC*) <= (SELECT COUNT**}

Page 23: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

88 Глава 5. Язык SQL. Формирование запросов к базе данных

FROM R2.R3

WHERE R2.Fpynna=R3.Группа

АШФИО=а.ФИО)

Здесь во встроенном запросе определяется общее число экзаменов, которыедолжен сдавать каждый студент, обучающийся в группе, в которой учитсяданный студент, и это число сравнивается с числом экзаменов, которые сдалданный студент,

D Список тех, кто должен был сдавать экзамен по БД, но пока еще не сдавал.

SELECTOR

FROM R2 a, R3

WHERE R2.rpynna=R3.Группа AND Дисциплина * "БД" AND NOT EXISTS (SELECT ФИО

FROM Rl

WHERE ФИО=а.ФИО AND Дисциплина = "БД")

Предикат EXISTS ( SubQuery) истинен, когда подзапрос SubQuery не пуст, тоесть содержит хотя бы один кортеж, в противном случае предикат EXISTS ложен.Предикат NOT EXISTS обратно — истинен только тогда, когда подзапрос SubQueryпуст.

Обратите внимание, каким образом NOT EXISTS с вложенным запросом позволяетобойтись без операции разности отношений. Например, формулировка запросасо словом «все» может быть выполнена как бы с двойным отрицанием. Рассмот-рим пример базы, которая моделирует поставку отдельных деталей отдельнымипоставщиками, она представлена одним отношением SP «Поставщики—детали»со схемой

SP (Нонер_поставщика. номер_детали)Р (номер^детали, наименование)

Вот каким образом формулируется ответ на запрос; «Найти поставщиков, кото-рые поставляют все детали».

SELECT DISTINCT НОМЕР_ПОСТАВЩИКА

FROM SP SP1

WHERE NOT EXISTS

(SELECT номер_детали

FROM P

WHERE NOT EXISTS

(SELECT * FROM SP SP2

WHERE 5Р2.нонер_пютавщикаиЗР1.нонер_поставщика AND

зр2.номер_детали » Р.номер_детали));

Фактически мы переформулировали этот запрос так: «Найти поставщиков таких,что не существует детали, которую бы они не поставляли». Следует отмерить, чтоэтот запрос может быть реализован а через агрегатные функции с подзапросом;

Page 24: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Внешние объединения 89

SELECT DISTINCT Нонер_постаещика

FROM SP

GROUP ВУ'Нонер_поставщика

HAVING CounUDISTINCT номер_детали) =

(SELECT CountC нонер^детали)

FROM P)

В стандарте SQL92 операторы сравнения расширены до многократных сравне-ний с использованием ключевых слов ANY и ALL. Это расширение используетсяпри сравнении значения определенного столбца со столбцом данных, возвра-щаемым вложенным запросом.

Ключевое слово ANY, поставленное в любом предикате сравнения, означает, чтопредикат будет истинен, если хотя бы для одного значения из подзапроса пре-дикат сравнения истинен. Ключевое слово ALL требует, чтобы предикат сравне-ния был бы истинен при сравнении со всеми строками подзапроса.

Например, найдем студентов, которые сдали все экзамены на оценку не нижечем «хорошо». Работаем с той же базой «Сессия», но добавим к ней еще одно от-ношение R4, которое характеризует сдачу лабораторных работ в течение семестра:

RI = (ФИО, Дисциплина, Оценка);

R2 - (ФИО, Группа);

Кз = (Группы, Дисциплина )

RI = (ФИО, Дисциплина, Номер_лаб_раб, Оценка);

Select Rl-Фио

From Rl

Where 4 > ° All (Select Rl.Оценка

From Rl as Rll

Where Rl-Фио « Ш.Фио)

Рассмотрим еще один пример:Выбрать студентов, у которых оценка по экзамену не меньше, чем хотя бы однаоценка по сданным им лабораторным работам по данной дисциплины:

Select В1.Фио

From Rl

Where Rl.Оценка >= ANY (Select R4.Оценка

From R4Where Rl.Дисциплина •= R4. Дисциплина AND Rl-Фио « R4.*iio)

Внешние объединенияСтандарт SQL2 расширил понятие условного объединения. В стандарте SQL1при объединении отношений использовались только условия, задаваемые в час-

Page 25: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

90 Глава 5. Язык SQL. Формирование запросов к базе данных

ти WHERE оператора SELECT, и в этом случае в результирующее отношение попада-ли только сцепленные по заданным условиям кортежи исходных отношений,для которых эти условия были определены и истинны. Однако в действитель-ности часто необходимо объединять таблицы таким образом, чтобы в результатпопали все строки из первой таблицы, а вместо тех строк второй таблицы, длякоторых не выполнено условие соединения, в результат попадали бы неопреде-ленные значения. Или наоборот, включаются все строки из правой (второй)таблицы, а отсутствующие части строк из первой таблицы дополняются неопре-деленными значениями. Такие объединения были названы внешними в проти-воположность объединениям, определенным стандартом SQ.L1, которые Сталиназываться внутренними.

В общем случае синтаксис части FROM в стандарте SQ.L2 выглядит следующимобразом: '

FROM <список исходных таблиц> |,< выражение естественного объединения > |< выражение объединения > |< выражение перекрестного объединения > |< выражение запроса на объединение >

<список исходных таблицм;» <имя_таблицы_1> [ имя синонима таблицы_1] [ ...][,<имя_таблицы_п>[ <иня синонима таблицы_п> ] ]

выражение естественного объединениям: »<иня_таблицы 1> NATURAL { INNER | FULL [OUTER] |LEFT [OUTER] | RIGHT [OUTER]} JOIN <имя_таблицы_2>

выражение перекрестного объединениям: = <имя_таблицы_1>CROSS JOIN <имя_таблицы_2>

выражение запроса на объединением :=<имя_таблицы_1> UNION JOIN <иня_таблицы_2>

выражение объединениями <иия таблицы 1> { INNER |FULL [OUTER] | LEFT [OUTER] ~| RIGHT TAUTER]}

JOIN (ON условие [ [USING (список столбцов)]} <имя_таблицы_2>

В этих определениях INNER — означает внутреннее объединение, LEFT — левоеобъединение, то есть в результат входят все строки таблицы 1, а части резуль-тирующих кортежей, для которых не было соответствующих значений в таб-лице 2, дополняются значениями NULL (неопределено). Ключевое слово RIGHTозначает правое внешнее объединение, и в отличие от левого объединения в этомслучае в результирующее отношение включаются все строки таблицы 2, а не-достающие части из таблицы 1 дополняются неопределенными значениями, Клю-чевое слово FULL определяет полное внешнее объединение: и левое и правое. Приполном внешнем объединении выполняются и правое и левое внешние объеди-нения и в результирующее отношение включаются все строки из таблицы 1» до-полненные неопределенными значениями, и все строки из таблицы 2, также до-полненные неопределенными значениями.

Page 26: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Внешние объединения 91

Ключевое слово OUTER означает внешнее, но если заданы ключевые слова FULL,LEFT, RIGHT, то объединение всегда считается внешним.Рассмотрим примеры выполнения внешних объединений. Снова вернемся к БД«Сессия». Создадим отношение, в котором будут стоять все оценки, полученныевсеми студентами по всем экзаменам, которые они должны были сдавать. Еслистудент не сдавал данного экзамена, то вместо оценки у него будет стоять не-определенное значение. Для этого выполним последовательно естественное внут-реннее объединение таблиц R2 и R3 по атрибуту Группа, а полученное отношениесоединим левым внешним естественным объединением с- таблицей R1, исполь-зуя столбцы ФИО и Дисциплина. При этом в стандарте разрешено использовать ско-бочную структуру, так как результат объединения может быть одним из аргу-ментов в части FROM оператора SELECT.

SELECT Rl.WO. R1.Дисциплина, Rl.ОценкаFROM (R2 NATURAL INNER JOIN R3 > LEFT JOIN Rl USING ( ФИО. Дисциплина)

Результат:

ФИО

Петров Ф. И.

Сидоров К. А.

Миронов А. В.

Степанова К. Е.

Крылова Т. С.

Владимиров В. Л.

Петров Ф. И.

Сидоров К, А.

Миронов А. В.

Степанова 1C Е,

Крылова Т. С.

Владимиров В, А.

Петров Ф. И.

Сидоров К, А.

Миронов А. В.

Степанова К. Е.

Крылова Т. С.

Владимиров В. А,

Трофимов П. А,

Иванова Е. А.

Дисциплина

Базы данных

Базы данных

Базы данных

Базы данных

Базы данных

Базы данных

Теория информации

Теория информации

Теория информации

Теория информации

Теория информации

Теория информации

Английский язык ,

Английский язык

Английский язык

Английский язык

Английский язык

Английский язык

Сети и телекоммуникации

Сети и телекоммуникации

Оценка ,

5

4 '

2

2

5

5

Null

4

Null

2

5

Null

5

Null> - —Null

Null

Null

4

4

5

Page 27: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

92 Глава 5. Язык SQL Формирование запросов к базе данный

ФИО

Уткина И, В.

Трофимов П. Л.

Иванова Е. Л.

Уткина Н. В.

Дисциплина

Сети и телекоммуникации

АНГЛИЙСКИЙ язык

Английский язык

Английский язык

Оценка

5

5

3

Null

Рассмотрим еще один пример, для этого возьмем БД «Библиотека», Она состо-ит из трех отношений, имена атрибутов здесь набраны латинскими буквами, чтоявляется необходимым в большинстве коммерческих СУБД.

BOOKSCISBN, TITL, AUTOR. COAUTOR. YEARIZD, PAGES)

READER(NUM_READER, NAMEJEADER, AORESS. HOOM_PHONE. WORK_PHONE. BIRTH_DAY)

EXEMPLAREONV. ISBN, YES JO. NUMJEADER. DATEJN, OATE_OUT)

Здесь таблица BOOKS описывает все книги, присутствующие в библиотеке, онаимеет следующие атрибуты;

U ISBN — уникальный шифр книги;Q TITL — иазпание книги;

Q AUTOR — фамилия автора;

Q COAUTOR — фамилия соавтора;Q YEARIZD - год издания;Р PAGES — число страниц.

Таблица READER хранит сведения обо всех читателях библиотеки, и она содержитследующие атрибуты:

Q NUM_READER — уникальный номер читательского билета;Р NAME_READER — фамилию и инициалы читателя;Q ADRESS — адрес читателя;

Q HOOH_PHONE — номер домашнего телефона;Q WORK_PHONE — номер рабочего телефона;Q BIRTHJJAY — дату рождения читателя.

Таблица EXEMPLARE содержит сведения о текущем состоянии всех экземпля-ров всех книг. Она включает в себя следующие столбцы:

Р INV — уникальный инвентарный номер экземпляра книги;a ISBN - шифр книги, который определяет, какая это книга, и ссылается на

сведения из первой таблицы;Р YESJO - признак наличия или отсутствия в библиотеке данного экземпляра

в текущий момент;Р NUMJEADER — номер читательского билета, если книга выдана читателю, и Null

в противном случае;

Page 28: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Внешние объединения 93

Q DATEJN — если книга у читателя, то это дата, когда она выдана читателю;

Q DATEJWT — дата, когда читатель должен вернуть книгу в библиотеку.

Определим перечень книг у каждого читателя; если у читателя пет книг, то но-мер экземпляра книги равен NULL. Для выполнения этого поиска нам надо ис-пользовать левое внешнее объединение, то есть мы берем все строки из таблицыREADER и соединяем со строками из таблицы EXEMPLARE, если во второй таблиценет строки с соответствующим номером читательского билета, то в строке ре-зультирующего отношения атрибут EXEMPLARE.INV будет иметь неопределенноезначение NULL:

SELECT READER.NAME_READER, EXEMPLARE.INV

FROM READER RIGHT JOIN EXEMPLARE ON READER.NUM_READER*EXEMPLARE.NUM_READER

Операция внешнего объединения, как мы уже упоминали, может использовать-ся для формирования источников в предложении FROM, поэтому допустимым бу-дет, например, следующий текст запроса;

SELECT *

FROM С BOOKS LEFT JOIN EXEMPLARE}

LEFT JOIN

(READER NATURAL JOIN EXEMPLARE)

USING (ISBN)

При этом для книг, ии один экземпляр которых не находится на руках у читате-лей, значения номера читательского билета и дат взятия и возврата книги будутнеопределенными.

Перекрестное объединение в трактовке стандарта SQL2 соответствует операциирасширенного декартова произведения, то есть операции соединения двух таб-лиц, при которой каждая строка первой таблицы соединяется с каждой строкойвторой таблицы.

Операция запроса па объединение эквивалентна операции теоретико-множест-венного объединения в алгебре. При этом требование эквивалентности схем ис-ходных отношений сохраняется. Запрос на объединение выполняется по сле-дующей схеме:

SELECT - запрос

UNION

SELECT - запрос

UNION

SELECT - запрос

Все запросы, участвующие в операции объединения, не должны содержать вы-ражений, то есть вычисляемых полей.

Например, нужно вывести список читателей, которые держат па руках книгу«Идиот» или книгу «Преступление и наказание». Вот как будет выглядеть за-прос:

Page 29: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

94 Глава 5. Язык SQL. Формирование запросов к базе данные

SELECTREADER.NAME_READER

FROM READER, EXEMPLARE.BOOKS

WHERE EXEMPLARE.NUM_READER= REAPER.HUMJEADER AND

EXEMPLRE.ISBN - BOOKS.ISBN AND

BOOKS.TITLE = "Идиот"

UNION

SELECTREADER.NAMEJEADER

FROM READER. EXEMPLARE.BOOKS

WHERE EXEMPLARE.NUM_READER= READER.NUM_READER AND

EXEMPLRE.ISBN - BOOKS.ISBN AND

BOOKS.TITLE = "Преступление и наказание"

По умолчанию при выполнении запроса на объединение дубликаты кортежейвсегда исключаются. Поэтому, если найдутся читатели, у Которых находятся наруках обе книги, то они все равно в результирующий список попадут толькоодин раз.Запрос на объединение может объединять любое число исходных запросов.Так, к предыдущему запросу можно добавить еще читателей, которые держат наруках книгу «Замок»:

UNION

SELECTREADER.NAMEJEADER

FROM READER. EXEMPLARE.BOOKS

WHERE EXEMPLARE. NUMJEADER» READER.NUM_READER AND

EXEMPLRE.ISBN = BOOKSJSBN AND

BOOKS.TITLE = "Замок"

В том случае, когда вам необходимо сохранить все строки из исходных отно-шений, необходимо использовать ключевое слово ALL в операции объединения.В случае сохранения дубликатов кортежей схема выполнения запроса на объе-динение будет выглядеть следующим образом:

SELECT - запрос

UNION ALL

SELECT - запрос

UNION ALL

SELECT - запрос

Однако тот же результат можно получить простым изменением фразь^ WHEREпервой части исходного запроса, соединив локальные условия логической опе-рацией ИЛИ и исключив дубликаты кортежей.

SELECT DISTINCT READER.NAME_READER

FROM READER, EXEMPLARE,BOOKS

Page 30: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Операторы манипулирования данными 95

WHERE EXEMPLARE,NUM_READER« READERfNUM_READER AND

EXEMPLRE.ISBN = BOOKS.ISBN AND

BOOKS.TITLE = "Идиот" OR

BOOKS.TITLE = "Преступление и наказание" ORBOOKS.TITLE = "Замок"

Ни один из исходных запросов в операции UNION не должен содержать предло-жения упорядочения результата ORDER BY, однако результат объединения можетбыть упорядочен, для этого предложение ORDER BY с указанием списка столбцовупорядочения записывается после текста последнего исходного SELECT-запроса.

Операторы манипулированияданнымиВ операции манипулирования данными входят три операции; операция удале-ния записей — ей соответствует оператор DELETE, операция добавления или вво-да новых записей — ей соответствует оператор INSERT и операция изменения(обновления записей) — ей соответствует оператор UPDATE, Рассмотрим каждыйиз операторов подробнее.Все операторы манипулирования данными позволяют изменить данные тольков одной таблице.

Оператор ввода данных INSERT имеет следующий синтаксис:

INSERT INTO имя_таблицы С(<список столбцов>) ] VALUES (<список значений )̂

Подобный синтаксис позволяет ввести только одну строку 'в таблицу. Заданиесписка столбцов необязательно тогда, когда мы вводим строку с заданием значе-ний всех столбцов. Например, введем новую книгу в таблицу BOOKS

INSERT INTO BOOKS C ISBN.TITL.AUTOR.CQAUTOR.YEARIZD.PAGES)VALUES ("5-88782-290*2","Аппаратные средства IBM PC. Энциклопедия

ТукМ, "."",2000,816)

В этой книге только один автор, нет соавторов, но мы в списке столбцов задалистолбец COAUTOR, поэтому мы должны были ввести соответствующее значениев разделе VALUES. Мы ввели пустую строку, потому что мы знаем точно, что нетсоавтора. Мы могли бы ввести неопределенное значение NULL*Так как мы вводим полную строку, то мы можем не задавать список столбцов,ограничиться только заданием перечня значений, в этом случае оператор вводабудет выглядеть следующим образом:

INSERT INTO BOOKS VALUES ("5-88782-290-2"."Аппаратные средства IBM PC. Энциклопедия",Тук М."."",2000.816)

Результаты работы обоих операчоров одинаковые.Наконец, мы можем ввести неполный перечень значений, то есть не вводить со-автора, так как он отсугствует для данного издания. Но в этом случае мы должны

Page 31: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

96 Глава 5. Язык SQL. Формирование запросов к базе данных

задать список вводимых столбцов, тогда оператор ввода будет выглядеть сле-дующим образом:

INSERT INTO BOOKS ( ISBNJITL.AUTOR.YEARIZD.PAGES)

VALUES ("5-88782-290-2","Аппаратные средства IBM PC. Энциклопедия",Тук М.",2000.816}

Столбцу COAUTOR будет присвоено в этом случае значение NULL.

Кагате столбцы должны быть заданы при вводе данных? Это определяется тем,как описаны эти столбцы при описании соответствующей таблицы, и будет рас-смотрено более подробно при описании языка DDL (Data Definition Language)в главе 8. Здесь мы пока отметим, что если столбец или атрибут имеет признакобязательный (NOT NULL) при описании таблицы, то оператор INSERT долженобязательно содержать данные для ввода в каждую строку данного столбца. По-этому если в таблице все столбцы обязательные, то каждая вводимая строкадолжна содержать полный перечень вводимых значений, а указание имен столб-цов в этом случае необязательно. В противном случае, если имеется хотя быодин необязательный столбец и вы не вводите в него значений, задание спискаимен столбцов — обязательно.В набор значений могут быть включены специальные функции и выражения.Ограничением здесь является то, что значения этих функций должны быть опре-делены на момент ввода данных. Поэтому, например, мы можем сформироватьоператор ввода данных в таблицу EXEMPLAR следующим образом;

INSERT INTO EXEMPLAR UNV.ISBN,YES_NO.NUM_READER,DATEJN. DATE JUT)

VALUES (1872. "5-88782-290-2",NO,344,GetDate().DateAdd(d.GetDate().14»

И это означает, что мы выдали экземпляр книги с инвентарным номером 1872читателю с номером читательского билете 344, отметив, что этот экземпляр неприсутствует с этого момента в библиотеке, и определили дату выдачи книгикак текущую дату (функция GetDateO), а дату возврата задали двумя неделямипозднее, использовав при этом функцию DateAdd О, которая позволяет к однойдате добавить заданное количество интервалов даты и тем самым получить но-вое значение типа «дата». Мы .добавили 14 дней к текущей дате.Оператор ввода данных позволяет ввести сразу множество строк, если их мож-но выбрать из некоторой другой таблицы. Допустим, что у нас есть таблица состудентами и в ней указаны основные данные о студентах: их фамилии, адреса,домашние телефоны и даты рождения. Тогда мы можем сделать всех студентовчитателями нашей библиотеки одним оператором;

INSERT INTO READER (NAME READER. ADRESS, HOOM_PHONE. BIRTHJAY)SELECT (NAME STUDENT .~ADR£SS, HOOM PHONE, BIRTH JAY)FROM STUDENT"

При этом номер читательского билета может назначаться автоматически, поэто-му мы не вводим значения этого столбца в таблицу. Кроме того, мы предполага-ем, что у студентов дневного отделения еще ист работы и поэтому нет рабочеготелефона, и мы его не вводим.Оператор удаления данных позволяет удалить одну или несколько строк из таб-лицы в соответствии с условиями, которые задаются Для удаляемых строк.

Page 32: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Операторы манипулирований данными 97

Синтаксис оператора DELETE следующий:

DELETE FROM имя_таблицы [WHERE условия_отбора]

Если условия отбора не задаются, то из таблицы удаляются псе строки, однакоэто не означает, что удаляется вся таблица. Исходная таблица остается, но онаостается пустой, незаполненной.

Например, если нам надо удалить результаты прошедшей сессии, то мы можемудалить все строки из отношения R1 командой

DELETE FROM Rl

Условия отбора в части WHERE имеют тот же вид, что и условия фильтрации в опе-раторе SELECT. Эти условия определяют, какие строки из исходного отношениябудут удалены. Например, если мы исключим студента Миронова Л. В., то мыдолжны написать следующую команду;

DELETE FROM R2

WHERE ФИО « 'Миронов А. В. 1

В части WHERE может находиться встроенный запрос. Например, если нам надоисключить неуспевающих студентов, то по закону о высшем образовании неус-певающим считается студент, имеющий две и более задолженности по последнейсессии. Тогда нам в условиях отбора надо найти студентов, имеющих либо двеили более двоек, либо два и более нссДанных экзамена из числа тех, которыестудент сдавал. Для поиска таких горе-студентов нам надо выбрать из отноше-ния R1 все строки с оценкой 2 или с неопределенным значением, потом надосгруппировать полученный результат по атрибуту ФИО и, подсчитав количествострок в каждой группе, которое соответствует количеству несдапных экзаменовкаждым студентом, отобрать те группы, у которых количество строк не менеедвух. Теперь попробуем просто записать эту сложную конструкцию на SQL иубедимся, что этот сложный запрос записывается достаточно компактно.

DELETE FROM R2

WHERE R2.UHO IN

(SELECT Rl.OHO

FROM Rl

WHERE Оценка = 2 OR Оценка IS NULL

GROOP BY Rl.WO

HAVING COUNTC*) >* 2

Однако при выполнении операции DELETE, включающей сложный подзапрос,в подзапросе нельзя упоминать таблицу, из которой удаляются строки, поэтомуСУБД отвергнет такой красивый подзапрос, который попытается удалить всехне только сдававших, но и предававших студентов, которые имеют более двухзадолженностей.

DELETE FROM R2

WHERE R2.<№0 IN

Page 33: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

98 Глава 5. Язык SQL. Формирование запросов к базе данных

(SELECT R1.ФИО

FROM (R2 NATURAL INNER JOIN R3 ) LEFT JOIN Rl USING ( ФИО. Дисциплина)

WHERE Оценка = 2 OR Оценка IS NULL

GROOP BY Rl.WO

HAVING COUNT(*) >= 2

Все операции манипулирования данными связаны с понятием целостности базыданных, которое будет рассматриваться далее в главе 9. В настоящий моментмне бы хотелось отметить только то, что операции манипулирования даннымине всегда выполнимы, даже если синтаксически они написаны правильно. Дей-ствительно, если мы бы захотели удалить какую-нибудь группу из отношенияR3, то СУБД не позволила бы нам это сделать, так как в отношениях R1 и R2 естьстроки, связанные с удаляемой строкой в отношении R3. Почему так делается,мы узнаем позднее, а пока просто примем к сведению, что не все операторы ма-нипулирования выполнимы.

Операция обновления данных UPDATE требуется тогда, когда происходят измене-ния во внешнем мире и их надо адекватно отразить в базе данных, так как надовсегда помнить, что база данных, отражает некоторую предметную область. На-пример, в нашем учебном заведении произошло счастливое событие, котороесвязано с тем, что госпожа Степанова К. Е. пересдала экзамен по дисциплине«Базы данных» с двойки сразу на четверку. В этом случае нам надо срочновыполнить соответствующую корректировку таблицы R1. Операция обновленияимеет следующий формат;

UPDATE имя_таблицы

SET имя^столбца = новое_значение

[WHERE условие_ртбора]

Часть WHERE является необязательной, так же как и в операторе DELETE. Онаиграет здесь ту же роль, что и в операторе DELETE, — позволяет отобрать строки,к которым будет применена операция модификации. Если условие отбора не за-дается, то операция модификации будет применена ко всем строкам таблицы.

Для решения ранее поставленной задачи нам необходимо выполнить следую-щую операцию

UPDATE Rl

SET Rl,Оценка = 4

WHERE Rl-ФИО » "Степанова К.Е," AND Rl.Дисциплина « "Базы данных"

В каких случаях требуется провести изменение в нескольких строках? Это нетакая уж редкая задача. Например, если мы расширим нашу учебною базу дан-ных еще одним отношением, которое содержит перечень курсов, на которыхучатся наши студенты, то можно с помощью операции обновления промодели-ровать операцию перевода групп на следующий курс. Пусть новое отношение R4имеет следующую схему;

RI = <Группа, Курс>

Page 34: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Операторы манипулирования данными 99

R4

Группа

49,06

4807

Курс

3

4

В этом случае перевод па следующий курс можно выполнить следующей опера-цией обновления:

UPDATE R4

SET R4,Kypc = R4.Kypc + 1

И результат будет выглядеть следующим образом:

Группа

4906

4807

Курс

4

5

Операция модификации, так же как и операция удаления, может использоватьсложные подзапросы. Расширим нашу базу еще одним отношением, которое бу-дет содержать перечень студентов, получающих стипендию с указанием надбав-ки, которую они получают за отличную учебу. Исходно там могут находитьсявсе студенты с указанием неопределенного размера стипендии. По мере анализаотношения R1 мы можем постепенно заменять неопределенные значения на кон-кретные размеры стипендии. Отношение R5 имеет вид:

R5

ФИО

Петров Ф, И,

Сидоров К. Л.

Миронов А. В.

Крылова Т. С.

Владимиров В. Л.

Трофимов П. А.

Иванова Е. А,

Уткина Н. В.

Группа

4906

49QG

4906

4906

4906

4807

4807

4807

Стипендий

<Null>

<Null>

<NulI>

<NulI>

<N«11>

<Nul)>

<Null>

<Null>

Будем считать наличие трех пятерок по сессии признаком повышенной стипен-дии, + 50% к основной, наличие двух пятерок из сданных экзаменов и отсутст-вие двоек и троек на сданных экзаменах - признаком повышения стнпсиднц па25%, наличие хотя бы одной двойки среди сданных экзаменов - признаком сня-тия или отсутствия стипендии вообще, то есть -100% надбавки. При отсутствиитроек на сданных экзаменах назначим обычную стипендию с надбавкой 0%. Од-

Page 35: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

•J 00 Глава 5. Язык SQL Формирование запросов к база данных^

иако все эти изменения мы должны будем сделать отдельными операциями об-новления.Назначение повышенной стипендии:

UPDATE R5

SET НБ.Стипендия « 50Я

WHERE R5.0HO IN

(SELECT R1.ФИО

FROM Rl

WHERE Rl.Оценка - 5

GROOP BY Rl.OHO

HAVING COUNTC*) =3 )

Назначение стипендии с надбавкой 25%:

UPDATE R5SET R5.Стипендия = 252

WHERE К.ФИО IN

(SELECT И.ФИО

FROM Rl

WHERE Rl.OW NOT IN

(SELECT А.ФИО

FROM Rl A

WHERE А.Оценка <=3 OR А.Оценка IS NULL)

GROOP BY Н1.ФИО

HAVING COUNT(*)>=2 )

Назначение обычной стипендии:-

UPDATE R5

SET R5.Стипендия * ОЖ

WHERE R5.0MO IN

(SELECT И.ФИО

FROM Rl

WHERE Rl.Оценка >Ч AND Rl-ФИО NOT IN

(SELECT А.ФИО

FROM Rl A

WHERE А.Оценка <- 3 OR А.Оценка IS NULL) }

Снятие стипендии:

UPDATE R5

SET R5,Стипендия ° -100Ж

WHERE Рб.ФИО IN

Page 36: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Операторы манипулирования данными 101

(SELECT Rl.OMO

FROM Rl

WHERE Rl.Оценка <= 2 OR Rl.Оценка IS NULL)

Почему мы в первом запросе на обновление не использовали дополнительнуюпроверку па отсутствие двоек, троек и несданных экзаменов, как мы сделали этопри назначении следующих видов стипендии? Просто мы учли особенности на-шей предметной области: у нас в соответствии с исходными данными не только3 экзамена. Но если мы можем предположить, что число экзаменов может бытьпроизвольным и изменяться от семестра к семестру, то нам надо изменить нашзапрос. Запрос — это некоторый алгоритм решения конкретной задачи, которуюмы формулируем заранее па естественном языке. И оттого, что наша задача ре-шается всего одним оператором языка SQL, она не становится примитивной.Мощность языка SQL и состоит в том, что он позволяет одним предложени-ем сформулировать отпеты на достаточно сложные запросы, для реализациикоторых на традиционных языках понадобилось бы писать большую программу.Итак, подумаем, как нам надо изменить текст нашего запроса на обновление дляназначения повышенной стипендии при любом количестве сданных экзаменов.Прежде всего, каждая группа может иметь свое число экзаменов в сессию, этозависит от специальности и учебного плана, по которому учится данная группа.Поэтому для каждого студента нам надо знать, сколько экзаменов он долженбыл сдавать и сколько экзаменов он сдал на пять, и в том случае, когда эти двачисла равны, мы можем назначить ему повышенную стипендию.

Будем решать нашу задачу по шагам. В конечном счете нам все равно надо знать,сколько экзаменов должен сдавать каждый конкретный студент, поэтому снача-ла сосчитаем количество экзаменов, которые должна сдавать группа, в которойучится этот студент,

Это мы делать умеем, для этого надо сделать запрос SELECT над отношением R3,сгруппировав его по атрибуту Группа, и вывести для каждой группы количестводисциплин, по которым должны сдаваться экзамены. Если мы учтем, что и од-ной сессии по одной дисциплине не бывает более одного экзамена, то можнопросто подсчитывать количество строк в каждой группе.

SELECT R3,Группа, Число_экзаненов с COUNTf*)

FROM R3

GROOP BY R3.Группа

Однако нам нужен не этот запрос, нам нужен запрос, в котором мы определяемдля каждого студента количество экзаменов. Этот запрос мы должны строитьпо схеме встроенного запроса;

SELECT COUNT(*)

FROM R3

WHERE R2.Группа <= R3,Группа

GROOP BY R3.Группа

Page 37: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

102 Глава 5. Язык SQL. Формирование запросов к базе данных.

А почему мы здесь в части FROM не написали имя второго отношения R2? Мыимя этого отношения укажем для связи с вышестоящим запросом, когда будемформировать запрос полностью. Теперь попробуем сформулировать полностьюзапрос. Нам надо объединить отношения R1 и R2 по атрибуту ФИО, нам надо знатьгруппу, в которой учится каждый студент, далее надо выбрать все строки с оцеткой 5 и сгруппировать их по фамилии студента, сосчитав количество строк в каж-дой группе, а выбирать мы будем те группы, в которых число строк в групперавно числу строк во встроенном запросе, рассмотренном ранее, при условииравенства количества строк в группе результату подзапроса, который выводиттолько одно число.

SELECT R1.ФИО

FROM R1.R2

WHERE R1. ФИО * Р2.ФИО AND R1.Оценка = 5

GROOP BY Rl-ФИО

HAVING COUNT(*) = (SELECT COUNTC*)

FROM R3

WHERE R2.Группа = R3.ГруппаGROOP BY R3.Группа)

Ну а теперь нам осталась последняя простейшая операция: надо заменить ста-рый вложенный запрос, определявший отличников, получивших три пятерки насессии, на новый универсальный запрос:

UPDATE R5

SET R5.Стипендия = 50£

WHERE КБ.ФИО IN (SELECT Rl-ФИОFROM R1.R2

WHERE Rl. ФИО = Р2.ФИО AND Rl,Оценка = 5

GROOP BY Rl-ФИО

HAVING COUNTS) * (SELECT COUNT(*>

FROM R3

WHERE R2.Группа « R3.ГруппаGROOP BY R3.Группа»

Вот какой сложный запрос мы построили. Это ведь практически одни оператор,а какую сложную задачу он решает. Действительно, мощность языка SQL ино-гда удивляет даже профессионалов, кажется невозможно построить один запросдля решения конкретной задачи, но когда начинаешь поэтапно его конструиро-вать — все получается. Самое сложное - это сделать Переход от словесной фор-мулировки задачи к представлению се в терминах нашего SQL, по этот процесссродни процессу алгоритмизации при решении задач традиционного програм-мирования, а он всегда был самым трудным, творческим и лсформализуемымпроцессом. Недаром на заре развития программирования известный американ-ский специалист по программированию Дональд Е, Кнут озаглавил свой много-

Page 38: ГЛАВА 5 Язык SQL- Формирование запросов к …do.csu.ru/~iren/courses/book/KarpovaT/p5.pdfсобытия и триггеры, которые ранее

Задания для самостоятельной работы 103

томный капитальный труд по теории и практике программирования «Искусствопрограммирования для ЭВМ» («The art of computer programming»).

Задания для самостоятельнойработыЗадание 1. В отношении R5 отметить студентов — претендентов на отчисление.Считаем, что о отношении R1 находятся окончательные результаты сессии, и по-этому отчислению подлежат все студенты, которые не сдали пли не сдавали дваи более из положенных экзаменов в сессию. Для того чтобы зафиксировать этотфакт, нам потребуется добавить еще один столбец в отношение R5, назовем егорезультат_сессии, и там могут бь'пъ два допустимых значения: переведен на сле-дующий курс или отчислен. Запрос писать по универсальному алгоритму.

Задание 2. В отношении R5 отметить студентов, переведенных на следующийкурс.

Задание 3. Провести отчисление студентов по результатам текущей сессии. Об-ратите внимание, что это уже другая операция по сравнению с заданиями 1 и 2.