# Язык запросов SQL

Структурированный язык запросов SQL основан на реляционном исчислении с переменными кортежами. Язык имеет несколько стандартов: SQL1 был принят в 1989г., SQL2 - в 1992г. В 1999г. появился новый стандарт SQL3. Исходное название языка SEQUEL(Structured English QUEry Language). Язык SQL предназначен для выполнения операций над таблицами (создание, удаление, изменение структуры) и над данными таблиц (выборка, изменение, добавление и удаление). SQL является непроцедурным языком и не содержит операторов управления, организации подпрограмм, ввода-вывода и т. п. В связи с этим SQL автономно не используется, обычно он погружён в среду встроенного языка программирования СУБД (например, FoxPro СУБД Visual FoxPro, ObjectPal СУБД Paradox, Visual Basic for Application СУБД Access). Язык SQL не обладает функциями полноценного языка разработки, а ориентирован на доступ к данным, потому его включают в состав средств разработки программ. В этом случае его называют встроенным SQL. Различают два основных метода использования встроенного SQL: статический и динамический. При динамическом использовании языка (динамический SQL) предполагается динамическое построение вызовов SQL-функций и интерпретация этих вызовов, например, обращение к данным удалённой базы, в ходе выполнении программы. Динамический метод обычно применяется в случае, когда в приложении заранее не известен вид SQL-вызова и он строится в диалоге с пользователем.

## 5.1 Основные категории команд SQL.

Основные категории команд, реализующих в SQL выполнение различных функций:

- DDL (Data Definition Language – язык определения данных)
- DML (Data Manipulation Language – язык манипуляций данными)
- DQL (Data Query Language – язык запросов к данным)
- DCL (Data Control Language – язык управления данными)
- DAC (Data Administration Commands – команды администрирования данных)
- TCC (Transaction Control Commands – команды управления транзакциями)

Основные команды DDL:

Оператор | Действия
CREATE TABLE | Создать таблицу
DROP TABLE | Удалить таблицу
ALTER TABLE | Изменить таблицу
CREATE VIEW | Создать представление (создаёт виртуальную таблицу, соответствующую некоторому SQL-запросу)
ALTER VIEW | Изменить представление
DROP VIEW | Удалить представление
CREATE INDEX | Создать индекс (создаёт индекс для некоторой таблицы для обеспечения быстрого доступа по атрибутам, входящим в индекс)
DROP INDEX | Удалить индекс

Основные команды DML:

Оператор | Действие
DELETE | Удалить строку
INSERT | Вставить строку
UPDATE | Обновить строку (обновляет значение одного или нескольких столбцов в одной или нескольких строках, соответствующих условиям фильтрации)

DQL: SELECT – выбрать строки

DCL: Команды управления данными в SQL позволяют осуществлять контроль над возможностью доступа к данным внутри базы данных. Команды DCL обычно используются для создания объектов, относящихся к управлению доступом пользователей к базе данных, а также для назначения пользователям подходящих уровней привилегий доступа. Некоторые коды управления данными:

- ALTER PASSWORD
- GRANT – Дать привилегию
- REVOKE – Отменить привилегию
- CREATE SYNONYM

Команды администрирования данных:

- START AUDIT
- STOP AUDIT Эти команды дают пользователю возможность выполнять аудит и анализ операций внутри базы данных.

Команды управления транзакциями:

- COMMIT (используется, чтобы сохранить транзакцию)
- ROLLBACK (используется, чтобы отменить транзакцию)
- SAVEPOINT (создаёт точки внутри групп транзакций, к которым отсылает команда ROLLBACK)
- SET TRANSACTION (позволяет назначит транзакции имя. Используется для инициализации транзакции)

Команды управления транзакциями используется только с командами DML INSERT, UPDATE и DELETE. Например, оператор COMMIT не используется для подтверждения создания таблицы. При создании таблицы операция её создания подтверждается автоматически. Точно так же нельзя с помощью команды ROLLBACK вернуть таблицу, только что удалённую из базы данных.

## 5.2 Типы связывания.

Самые общие типы связывания:

- Связывание по равенству (EQUI JOINS)
- Естественное связывание (NATURAL JOINS)
- Связывание по неравенству (NON-EQUI JOINS)
- Внешнее связывание (OUTER JOINS)
- Рекурсивное связывание (SELF JOINS)

Связывание по равенству используется чаще всего и является самым простым типом связывания. Связывание по равенству называется также внутренним (INNER JOIN). При связывании по равенству таблицы связываются по общему столбцу, который в каждой из таблиц обычно является ключевым. Естественное связывание почти эквивалентно связыванию по равенству, но при естественном связывании таблиц повторения эквивалентных столбцов исключаются. Условие связывания оказывается таким же. При связывании по неравенству две или несколько таблиц объединяются по условию неравенства значения столбца таблицы значению из столбца другой таблицы. Внешнее связывание (OUTER JOIN) используется, когда вывод должен содержать все записи одной таблицы, даже если некоторые из её записей не имеют соответствующих записей в другой таблице. Во многих реализациях языка внешнее связывание разбито на левое внешнее связывание (LEFT OUTER JOIN), правое внешнее связывание (RIGHT OUTER JOIN) и полное внешнее связывание (FULL OUTER JOIN). Рекурсивное связывание (SELF JOIN) предполагает связывание таблицы с ней же самой, как будто бы это были две таблицы, применяя временное переименование таблицы в операторе SQL. Если нужно связать таблицы, не имеющие общих столбцов, необходимо использовать третью таблицу, имеющую общие столбцы как с первой, так и со второй таблицей. Такая таблица называется связующей таблицей. Связующую таблицу можно использовать для связывания как таблиц с общими столбцами, так и таблиц, не имеющих общих столбцов.

## 5.3 Команды языка запросов SQL.

Аббревиатура QBE – Query by Example – означает запрос по образцу. SQL – это принятая фирмой IBM аббревиатура слов Structured Query Language. Запрос по образцу (QBE) разработан на основе созданной фирмой IBM системы средств управления запросами. Запросы по образцу в dBASE IV позволяют дополнительно сформировать в специальном окне логическое условие, которое присоединяется к запросу. Запросы позволяют обновлять данные в БД, используя для этого данные из других БД. Запросы по образцу выполняют во многом те же функции, что и в СУБД Paradox, включая отбор записей и полей для вывода на экран и связывания с БД. Язык SQL разработан в соответствии со стандартом СУБД DB2 фирмы IBM. Это реляционная СУБД предназначена для больших ЭВМ. При работе в режиме языка SQL около 100 команд языка dBASE не используются. Ряд команд языка dBASE, аналогов которых нет в SQL, например, создание отчетов, можно применять вместе с языком SQL. Язык SQL используется в интерактивном режиме, а также в программах. Переключение из режима команд SQL в режим команд dBASE и обратно осуществляется командой SET SQL. На языке SQL осуществляется доступ ко всем файлам БД dBASE, включая файлы с расширением DBF,NDX и т.д.. Включение SQL в пакет FoxPro вызвано желанием придать формальную полноту средствам СУБД. Команды SQL могут непосредственно включаться в программы наряду с собственными командами FoxPro.

Создание Базы Данных:

CREATE DBF (<имя поля> <тип> [(<размер> [, <дробных разрядов>]) [, <имя поля> ... ]]) /FROM ARRAY <массив>

Команда создает новую базу данных с указанным именем. Для каждого поля задаются его имя, тип (одной из букв C, N, D, M, F, L), длина и число десятичных разрядов. Длина и точность не задаются для типов дата (D), логический (L), и примечаний (M), а точность - для символьного типа (С). Все требования к описанию полей базы данных - стандартные. Созданная база данных сразу открывается. Описание полей может быть задано и из <массива> при использовании опции FROM ARRAY. Такой двумерный массив из четырех столбцов и строк в количестве, совпадающем с количеством полей, должен иметь указанное выше наполнение. Например, функция AFIELDS() как раз генерирует такой массив из открытой базы данных.

Дополнение базы:

INSERT INTO <файл БД> [(<поле1> [, <поле2> [, ... ]])] VALUES (<выр1> [, <выр2> [, ... ]])

Команда добавляет записи в конец существующего <файла базы данных>, используя <выражения>, перечисленные после слова VALUES. Если опущены имена полей, <выражения> будут записываться в последовательные поля <базы данных> в соответствии с ее структурой.

Другая форма этой команды:

INSERT INTO <имя БД> FROM ARRAY <массив> FROM MEMVAR

переносит данные, содержащиеся в указанном <массиве> (опция ARRAY), или данные из временных переменных (опция MEMVAR). Такие переменные должны существовать и иметь те же самые имена, что и поля базы данных (но с префиксом М). Такие переменные, например, вырабатываются по команде SCATTER MEMVAR. Поля, для которых нет переменных с подходящими именами, останутся пустыми. Т.о. команда INSERT соответствует паре команд APPEND BLANK и REPLACE. В следующей команде база STUD.DBF дополняется новой записью с данными для полей FAM,KURS.

INSERT INTO stud (fam, kurs) VALUES (/Иванов А.И./, 4)

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

### Формирование запросов из базы данных.

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

SELECT [DISTINCT] [<псевдоним>.] <выражение> [AS <колонка>] [, [<псевдоним>.] <выражение> [AS<колонка>]...] FROM <БД> [, <БД>...] [[IN TO <получатель>]/ [TO FILE <файл> [ADDITIVE]/TO PRINTER]] [NOCONSOLE] [PLAIN] [NOWAIT] [WHERE <условие связи> [AND <условие связи>...] [AND/OR <условие отбора> [AND/OR <условие отбора>...]]] [GROUP BY <колонка> [, <колонка>...]] [HAVING <условие отбора>] [ORDER BY <колонка> [ ASC/DESC] [, <колонка> [ASC/DESC] ...]]

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

Указание результатов выборки и источников данных.

SELECT [DISTINCT] [<псевдоним>.] <выражение> [AS <колонка>] FROM <БД> [<псевдоним>] [, <БД> [<псевдоним>]...]

Здесь указывается, что и откуда берется в выборку. Перед словом FROM перечисляются отбираемые <выражения>, а после - имена баз, из которых берутся данные. <Выражение> может быть полем записи из БД, константой (выводимой в каждой строке выборки), функцией от переменных, полей и т.п.. Если <выражение> является именем поля, то оно может быть составным (с включением имени базы данных или псевдонима), в особенности если выборка делается из нескольких баз, где имена полей совпадают. Псевдонимом может быть не только «официальный» псевдоним (ALIAS) базы, но и любое другое имя, которое вы ей присвоите в команде SELECT. Это задаваемое временное имя указывается в опции <псевдоним> после слова FROM. Никаких последствий за пределами команды SELECT такое назначение не имеет. Если необходимо построить выборку из всех полей базы, вместо их перечня можно указать символ «*». В результате выполненной выборки получается совокупность колонок, заголовками которых могут быть имена полей. Если имена совпадают, то такие колонки получают совпадающие имена, к которым присоединяется одна из букв (по алфавиту), например ТАВ_А, ТАВ_В и т.д.. Аналогичным образом даются имена колонкам, полученным в результате вычисления выражений. Их имена состоят из слова EXP и последовательных чисел EXP_1, EXP_2 и т.д.. Исключение составляют выражения, использующие собственные функции SQL, например, функции MIN(), MAX() и др.. Имена колонок в этом случае будут включать имена функций. Если не устраивают имена, формируемые по умолчанию, можно назначить свои, указав их после слова AS в виде:

<выражение> AS <новое имя колонки>

Такое переименование имеет смысл, если выборка помещается во вновь создаваемую базу данных. Имя дается по правилам, принятым в FoxPro, и должно быть задано латинскими буквами. В <выражении> могут быть использованы любые функции FoxPro. Кроме того, здесь есть еще собственные специальные арифметические функции — это функции вычисления среднего, минимального и максимального значений, суммирования, а также количества записей:

AVG (<выр>), MIN (<выр>), MAX (<выр>), SUM (<выр>), COUNT (<выр>).

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

Указание объекта, куда пересылается выборка. Следующие опции задают «получатель» данных выборки. Им может быть база данных, массив, текстовый файл, экран и принтер. Кроме того информация может быть переслана в так называемый Курсор. Курсор - это временный набор данных, который может быть областью памяти или временным файлом FoxPro и имеет режим «только чтение». Данные курсора могут быть предъявлены в команде BROWSE, напечатаны, из них может быть образовано меню и т.д.. Курсор может быть обработан другой командой SELECT. К колонкам курсора обращаются по имени этих колонок.

Итак: INTO <получатель> <получатель> может быть одного из следующих типов: ARRAY <массив> – задается вновь создаваемый двумерный <массив>, CURSOR <курсор> – задается имя курсора, DBF/TABLE <БД> – новая база данных с указанным именем. Слова DBF и TABLE здесь являются синонимами.

Кроме того данные можно переслать в файл или на принтер. TO FILE <файл> [ADDITIVE]/TO PRINTER – выборка посылается в текстовый <файл> или на принтер. Если используется слово ADDITIVE, то выборка будет добавлена в конец существующего файла без его перезаписи. Следующие опции имеют смысл только при выдаче на экран (команда исполняется без слова INTO):

NOCONSOLE – выборка не выдается на экран, PLAIN – заголовки колонок не выдаются, NOWAIT – не делаются паузы при заполнении экрана.

Критерий отбора данных.

WHERE <условие связи> [AND <условие связи> ... ] [AND/OR <условие отбора> [AND/OR <условие отбора> ... ]]

Здесь: | <Условие связи> – применяется в случае, если выборка делается в более, чем из одной базы данных, и указывает критерий, которому должны отвечать поля из разных баз. В условии связи указываются поля из разных баз. Здесь разрешается использовать знаки отношения =, #, >, >=, <, <=. Допускается задание нескольких критериев, соединенных знаком AND.
| <Условие отбора> – строится аналогично, но из выражений только для одной базы, и допускается использование логических операторов OR и NOT.

Условия, кроме любых функций FoxPro, могут содержать следующие операторы SQL:

- LIKE – позволяет построить условие сравнения по шаблону, где символ «_» указывает единичный неопределенный символ в строке, «%» - любое их количество. Эти символы аналогичны символам маски «?» и «*» в MS DOS. Формат оператора: <выражение> LIKE <шаблон>.
- BETWEEN – проверяет, находится ли выражение в заданном диапазоне. Формат оператора: <выражение> BETWEEN <нижнее значение> AND <верхнее значение>.
- IN – проверяет, находится ли выражение стоящее слева от слова IN, среди перечисленных справа от него (аналогично функции INLIST). Формат оператора: <выражение> IN (<выражение>, <выражение>, ...).

Все указанные операторы можно комбинировать с помощью связок OR, AND, NOT и скобок. Операторы LIKE и BETWEEN не следует путать с одноименными функциями FoxPro, которые тоже можно использовать.

Группирование данных. GROUP BY <колонка> [, <колонка>] – задаются колонки, по которым производится группирование выходных данных. Все записи базы, для которых значения колонок совпадают, отображаются в выборке единственной строкой. Группирование удобно для получения некоторых сводных характеристик (сумм, количеств) группы. HAVING <условие отбора> – опция задает критерий отбора данных в каждую сформированную в процессе выборки группу.

Сортировка. ORDER BY <колонка> [ASC/DESC] [,<колонка> [ASC/DESC] ...] – опция задает упорядочение по заданной колонке/колонкам. По умолчанию сортировка выполняется по возрастанию (ASC), но может быть задана и по убыванию (DESC).

### Примеры запросов.

1. Выборка всех полей из базы STUD.DBF. Все колонки выборки будут иметь имена полей базы данных. SELECT * FROM stud

2. Вывод минимального, максимального и среднего значений поля STIPEND. Колонки получают имена MIN_STIPEND, MAX_STIPEND и AVG_STIPEND. SELECT MIN(STIPEND), MAX(STIPEND), AVG(STIPEND) FROM STUD

3. Вывод фамилий студентов, получающих от 80000 до 100000р. SELECT fam FROM stud WHERE stipend BETWEEN 80000 AND 100000.

4. Вывод фамилий всех студентов, кроме учащихся на факультете ФАМ и ЭМФ. SELECT fam FROM stud WHERE fak NOT IN ( /ФАМ/, /ЭМФ/ ).

5. Выборка названий всех факультетов (поле fak) института из базы STUD.DBF. Опция DISTINCT предотвращает повторный вывод одних и тех же названий, если они повторяются. SELECT DISTINCT fak FROM stud

6. Выборка фамилий (fam) всех студентов - семейных из stud.dbf. SELECT fam FROM stud WHERE sempol = /S/.

7. Выборка всех фамилий и номеров курсов из stud.dbf, сцепленных с выборками из базы prepod.dbf для записей, у которых совпадают номера курсов. SELECT s.fam, s.kurs, t.kurs, t.fio; FROM stud s, prepod t WHERE s.kurs = t.kurs Здесь для сокращения записи команды базам STUD.DBF и PREPOD.DBF заданы новые временные имена S и T. Они никак не связаны с рабочими областями. Базы будут открыты в свободных областях системы. Сами колонки выборки получат имена FAM, KURS_A, KURS_B, FIO.

8. Если хотим задать собственные имена колонкам, а не использовать умолчания, нужно воспользоваться опцией AS. Пусть нужно вывести фамилии и номера курса (поля FAM и KURS) по алфавиту и с другими именами колонок FAMILII и NUMKURS. SELECT fam AS familii, kurs AS numkurs FROM stud ORDER BY fam.

9. Выборка фамилий всех родившихся в текущем месяце с указанием дня (числа) рождения, количества лет и материальной помощи по этому поводу - 50% от стипендии. SELECT fam. DAY (dtr) , /число/ , YEAR (DATE()) - YEAR (dtr) , /лет/, ; /матпомощь/, 0,5*stipend FROM stud WHERE MONTH (dtr) = MONTH (DATE()). Колонки получают имена FAM и от EXP_2 по EXP_7.

10. Вывод полей FAM и KURS, отсортированных по полям SEMPOL (главное поле) и FAM (подчиненное поле) в базу FAMKURS.DBF, которая затем открывается в текущей области. SELECT fam, kurs FROM stud ORDER BY sempol, fam INTO TAB2 famkurs. Чтобы увидеть содержимое этой базы можно, например, сразу ввести команду BROWSE.

11. Вывод названий всех факультетов, количества студентов и значений суммарной стипендии (стипендиального фонда). Информация выводится только для факультетов, где количество студентов больше 25. SELECT fak , COUNT (*), SUM (stipend); FROM stud GROUP BY fak HAVING COUNT (*) > 25.