Секция FROM, логическое связывание таблиц

Перечень таблиц, из которых производится выборка данных, указывается
в секции FROM. Выборка возможна как из одной таблицы, так и из нескольких логически взаимосвязанных. Логическая взаимосвязь осуществляется с помощью подсекции JOIN. На каждую логическую связь пишется отдельная подсекция. Внутри подсекции указывается условие связи двух таблиц (обычно по условию равенства первичных и вторичных ключей). Примеры для модели данных Сотрудники-Отделы-Города:

Employees  
TabNum Name Position DeptNum Salary
Иванов Начальник
Петров Инж.
Сидоров Менеджер

 

Departments  
DeptNum City Name
Производственный отдел
Отдел продаж

 

Cities  
City Name
Минск
Москва

 

SELECTEmployees.TabNum, Employees.Name,Departments.Name

FROMEmployees

JOINDepartmentsONEmployees.DeptNum =

Departments.DeptNum

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

Иванов Производственный отдел
Петров Производственный отдел
Сидоров Отдел продаж

SELECTEmployees.TabNum, Employees.Name, Departments.Name, Cities.Name

FROMEmployees

JOINDepartmentsONEmployees.DeptNum = Departments.DeptNum

JOINCitiesONDepartments.City = Cities.City

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

Иванов Производственный отдел Минск
Петров Производственный отдел Минск
Сидоров Отдел продаж Москва

Пример связывания таблиц по нескольким полям:

SELECTTable1.Field1, Table2.Field2

FROM Table1

JOINTable2

ONTable2.ID1 =Table1.ID1

ANDTable2.ID2 =Table1.ID2

AND ….

Существует несколько типов связывания:

Тип Результат
JOIN Внутреннее соединение. В результирующем наборе присутствуют только записи, значения связанных полей в которых совпадают
LEFT JOIN Левое внешнее соединение. В результирующем наборе присутствуют все записи из Table1 и соответствующие им записи из Table2. Если соответствия нет, поля из Table2 будут пустыми
RIGHT JOIN Правое внешнее соединение. В результирующем наборе присутствуют все записи из Table2 и соответствующие им записи из Table1. Если соответствия нет, поля из Table1 будут пустыми
FULL JOIN Полное внешнее соединение. Комбинация двух предыдущих. В результирующем наборе присутствуют все записи из Table1 и соответствующие им записи из Table2. Если соответствия нет – поля из Table2 будут пустыми. Записи из Table2, которым не нашлось пары в Table1, тоже будут присутствовать в результирующем наборе. В этом случае поля из Table1 будут пустыми.
CROSS JOIN Cartesian product. Результирующий набор содержит все варианты комбинации строк из Table1 и Table2. Условие соединения при этом не указывается.

Проиллюстрируем каждый тип примерами. Модель данных:

Table1     Table2  
Key1 Field1   Key2 Field2
A   AAA
В   BBB
C   CCC
      DDD

SELECT Table1.Field1, Table2.Field2

FROM Table1

JOIN Table2 ON Table1.Key1 = Table2.Key2

Результат:

A AAA
B BBB
B CCC

SELECT Table1.Field1, Table2.Field2

FROM Table1

LEFT JOIN Table2 ON Table1.Key1 = Table2.Key2

Результат:

A AAA
B BBB
B CCC
C  

SELECT Table1.Field1, Table2.Field2

FROM Table1

RIGHT JOIN Table2 ON Table1.Key1 = Table2.Key2

Результат:

A AAA
B BBB
B CCC
  DDD

SELECT Table1.Field1, Table2.Field2

FROM Table1

FULL JOIN Table2 ON Table1.Key1 = Table2.Key2

Результат:

A AAA
B BBB
B CCC
  DDD
C  

SELECT Table1.Field1, Table2.Field2

FROM Table1

CROSS JOIN Table2

Результат:

A AAA
A BBB
A CCC
A DDD
B AAA
B BBB
B CCC
B DDD
C AAA
C BBB
C CCC
C DDD

Секция WHERE

Для фильтрации результатов выполнения запроса можно использовать условия выборки в секции WHERE. В общем виде синтаксис WHERE выглядит следующим образом:

WHERE[NOT] <условие1>[AND |OR<условие2>]

Условие представляет собой конструкцию вида:

<столбец таблицы, константа или выражение>

<оператор сравнения> <столбец таблицы, константа или выражение>

или

IS [NOT] NULL

или

[NOT] LIKE <шаблон>

или

[NOT] IN (<список значений>)

или

[NOT] BETWEEN <нижняя граница> AND <верхняя граница>

Операторы сравнения:

< Меньше
<= Меньше либо равно
<> Не равно
> Больше
>= Больше либо равно
= Равно

Примеры запросов с операторами сравнения:

SELECT * FROM Table WHERE Field > 100

SELECT * FROM Table WHERE Field1 <= (Field2 + 25)

Выражение IS [NOT] NULL проверяет данные на [не]пустые значения:

SELECT * FROM Table WHERE Field IS NOT NULL

SELECT * FROM Table WHERE Field IS NULL

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

Выражение [NOT] LIKE используется при проверке текстовых данных на [не]соответствие заданному шаблону. Символ ‘%’ (процент) в шаблоне заменяет собой любую последовательность символов, а символ ‘_’ (подчеркивание) – один любой символ.

SELECT * FROM Employees WHERE Name LIKE ‘Иван%’

Попадающие под заданное условие фамилии: Иванов

SELECT * FROM Employees WHERE Name LIKE ‘__д%’

Попадающие под заданное условие фамилии: Сидоров

Выражение [NOT] IN проверяет значения на [не]вхождение в определенный список:

SELECT * FROM Employees WHERE Position IN (‘Начальник’, ‘Менеджер’)

Выражение [NOT] BETWEEN проверяет значения на [не]попадание в некоторый диапазон:

SELECT * FROM Employees WHERE Salary BETWEEN 200 AND 500

Этот запрос вернет список работников, зарплата которых больше либо равна 200 у.е. и меньше либо равна 500 у.е.

Несколько условий поиска могут комбинироваться посредством логических операторов AND, OR или NOT:

SELECT *

FROM Employees

WHERE Position IN (‘Начальник’, ‘Менеджер’)

AND Salary BETWEEN 200 AND 500

SELECT *

FROM Employees

WHERE (Position = ‘Начальник’ OR Position =

‘Менеджер’)

AND Salary BETWEEN 200 AND 500

SELECT *

FROM Employees

WHERE NOT (Position = ‘Начальник’ OR Position =

‘Менеджер’)

Секция ORDER BY

Необязательная секция ORDER BY в команде SELECT предназначена для сортировки строк результирующего набора данных. Формат этой секции в общем виде выглядит так:

ORDER BY Field1 [ASC | DESC] [, Field2 [ASC | DESC] ] [, …]

Ключевое слово ASC предписывает производить сортировку по возрастанию, а DESC – по убыванию. Если ASC и DESC отсутствуют, по умолчанию подразумевается ASC. Например, выберем записи о начальниках и отсортируем результат
в порядке убывания размера зарплат:

SELECT *

FROM Employees

WHERE Position = ‘Начальник’

ORDER BY Salary DESC

Следующий запрос отсортирует сотрудников по отделам (в порядке возрастания номера отдела) и по размеру зарплат внутри каждого отдела (в порядке убывания зарплаты):

SELECT *

FROM Employees

ORDER BY DeptNum ASC, Salary DESC

Ключевое слово ASC можно опустить, ибо оно действует по умолчанию:

SELECT *

FROM Employees

ORDER BY DeptNum, Salary DESC

Групповые функции

Если нас не интересуют строки таблицы как таковые, а интересуют некоторые итоги, мы можем использовать в процессе выборки колонок таблиц групповые функции. Основные групповые функции представлены ниже:

Функция Описание
SUM(Field) Вычисляет сумму по указанной колонке
MIN(Field) Вычисляет минимальное значение по указанной колонке
MAX(Field) Вычисляет максимальное значение по указанной колонке
AVG(Field) Вычисляет среднее значение по указанной колонке
COUNT(*) Вычисляет количество строк в результирующей выборке
COUNT(Field) Вычисляет количество не пустых значений в колонке

Например, чтобы узнать максимальную зарплату, получаемую сотрудниками в организации, можно выполнить запрос вида:

SELECT MAX(SALARY)

FROM Employees

Общее количество записей в таблице вернет запрос вида:

SELECT COUNT(*)

FROM Employees

Секция GROUP BY

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

GROUP BY Field1 [, Field2] [, …]

Например, подсчитаем максимальную зарплату по отделам организации:

SELECT DeptNum, MAX(SALARY)

FROM Employees

GROUP BY DeptNum

В этом случае функция MAX будет считаться отдельно для всех записей с одинаковым значением поля DeptNum.

Секция HAVING

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

SELECT DeptNum, MAX(SALARY)

FROM Employees

GROUP BY DeptNum

HAVING MAX(SALARY) > 1000

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

Изменение данных

Под изменением данных понимаются следующие операции:

  • вставка новых строк в таблицу;
  • изменение существующих строк;
  • удаление существующих строк.

Команда INSERT

Добавление новых записей в таблицу осуществляется посредством команды INSERT. Она имеет следующий синтаксис:

INSERT INTO <имя таблицы> [(<список имен колонок>)]

VALUES(<список констант>)

Например, для внесения сведений о новом работнике необходимо выполнить следующую команду:

INSERT INTO Employees(TabNum, Name, Position, DeptNum,

Salary)

VALUES(45, ‘Сергеев’, ‘Старший менеджер’, 15, 850)

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

Employees  
TabNum Name Position DeptNum Salary
Иванов Начальник
Петров Инженер
Сидоров Менеджер
Сергеев Старший менеджер

Если какая-либо колонка в списке будет опущена при вставке, в соответствую­щее поле записи автоматически будет занесено пустое значение (NULL):

INSERT INTO Employees(TabNum, Name, DeptNum, Salary)

VALUES(45, ‘Сергеев’, 15, 850)

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

Employees  
TabNum Name Position DeptNum Salary
Иванов Начальник
Петров Инженер
Сидоров Менеджер
Сергеев  

Количество констант в секции VALUES всегда должно соответствовать количеству колонок. Список колонок в команде INSERT может быть опущен целиком. В этом случае список констант в секции VALUES должен точно соответствовать описанию колонок таблицы в словаре данных СУБД, иначе команда будет отвергнута ядром БД. Пример правильной команды:

INSERT INTO Employees VALUES(45, ‘Сергеев’,

‘Старший менеджер’, 15, 850)

Команда вида:

INSERT INTO Employees VALUES(45, ‘Сергеев’, 15, 850)

завершится ошибкой, так как количество констант не соответствует реальному количеству колонок в таблице.

В колонку можно в явном виде внести пустое значение посредством ключево­го слова NULL. Последний запрос можно переписать следующим образом:

INSERT INTO Employees VALUES(45, ‘Сергеев’, NULL, 15, 850)

В этом случае команда вставки отработает корректно, и в поле Position будет внесено пустое значение. Очевидно, что к аналогичному результату приведет
и команда:

INSERT INTO Employees(TabNum, Name, Position, DeptNum,

Salary)

VALUES(45, ‘Сергеев’, NULL, 15, 850)

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

INSERT INTO <имя таблицы> [(<список имен колонок>)]

<команда SELECT>

Например:

INSERT INTO Table1(Field1, Field2)

SELECT Field3, (Field4 + 5) FROM Table2

Команда DELETE

Чтобы удалить ненужные записи из таблицы, следует использовать команду DELETE:

DELETE FROM <имя таблицы> [WHERE <условия поиска>]

Если опустить секцию условий поиска WHERE, из таблицы будут удалены все записи. Иначе – только записи, удовлетворяющие критериям поиска. Форматы секций WHERE команд SELECT и DELETE аналогичны.

Примеры команды DELETE:

DELETE FROM Employees

DELETE FROM Employees WHERE TabNum = 45

Команда UPDATE

Изменить ранее внесенные командой INSERT данные можно с помощью команды UPDATE:

UPDATE < имя таблицы>

SET <имя колонки> = <новое значение> , <имя колонки> =

<новое значение>, …

WHERE <условия поиска>]

Как и в случае команды DELETE, при отсутствии секции WHERE обновлены будут все строки таблицы. Иначе – только подходящие под заданные условия. Примеры:

UPDATE Employees SET Salary = Salary + 100

UPDATE Employees

SET Position = ‘Старший менеджер’, Salary = 1000

WHERE TabNum = 45 AND Position IS NULL