Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БД.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
71 Кб
Скачать

Внутреннее соединение

Декартово произведение в его «чистом» виде используется относительно редко. Гораздо более широкое применение имеет внутреннее соединение: между именами отношений задается INNER JOIN, а затем, после слова ON, формулируется требуемое условие соединения. Например,

SELECT Группы.Наименование, Студенты.ФИО

FROM Группы INNER JOIN Студенты ON Студенты.Группа = Группы.КодГруппы;

LEFT JOIN и RIGHT JOIN работают аналогично INNER JOIN, единственной разницей является то, что при использовании объединения слева подразумевается объединения всех записей из таблицы, указанной слева от оператора LEFT JOIN и только тех записей таблицы, стоящей справа, в которых связанные поля совпадают. Аналогично – для RIGHT JOIN.

Простые запросы и порядок их выполнения (условно отделенный пункт)

В Access если имена полей или таблиц содержат пробелы, то их заключают в квадратные скобки.

Отличие запроса от фильтра – фильтр (в Access) накладывает ограничения на отображаемые данные, в то время, как сама просматриваемая таблица остается неизменной, запрос же представляет модифицированную таблицу, в соответствии с требованиями пользователя. Также разница заключается в том, что пользователь (опять же, в Access) вряд ли может изменять сам запрос, написанный программистом, но может отфильтровать результат выполнения запроса.

Предикаты. Предикат ALL – выбрать все записи (можно не указывать, ибо это подразумевается по умолчанию), DISTINCT – удаление дубликатов из результата запроса, DISTINCTROW сначала удаляет дубликаты из исходных таблиц, а потом уже собирает все в запрос (простой DISTINCT сначала собирает, а потом уже из результата удаляет).

TOP N – выбрать первые N записей (сначала запрос выполняется, как если бы этого не было, а потом от результата берутся только первые N строк).

TOP N PERCENT – выбрать первые N процентов записей.

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

Примеры:

SELECT [Дисциплины в учебном плане].[Полное наименование дисциплины] AS Дис

SELECT ((Белки+Углев)*4.1+Жиры*9.3) AS ККал

При работе с конструктором запросов псевдоним для поля или выражения указывается в начале и отделяется двоеточием.

Дис: Полное наименование дисциплины

ККал: (Белки+Углев)*4.1+Жиры*9.3

Условия поиска. Как пользоваться IN. Наиболее мощный вариант – это поиск значения в подзапросе, например:

WHERE Номенклатура.[Код продукта]

In ( select [Связь с продуктом]

FROM Поставки

WHERE Month([Дата поставки])=Month(Now()))

Смысл: надо отобрать только те номенклатурные позиции, по которым были поставки в текущем месяце.

По стандарту можно проверять вхождение в фиксированный список значений:

WHERE Цвет IN ("Красный" "Желтый");

EXISTS. Выражение истинно, если подзапрос возвратил хотя бы одну запись, например:

WHERE EXISTS (SELECT [Код поставки] FROM Поставки WHERE Поставщик="Вася Пупкин");

Запрос что-нибудь покажет только в том случае, если были поставки от Васи. Очевидно, NOT EXISTS – это когда подзапрос ничего не возвращает.

Сравнение [ANY | ALL | SOME]. Предикаты ANY или SOME, являющиеся синонимами, используются для отбора записей в главном запросе, которые удовлетворяют сравнению с любыми записями, отобранными в подчиненном запросе. В следующем примере отбираются все товары, цена которых больше, чем цена любого товара, проданного со скидкой в 25 процентов или более:

SELECT * FROM Товары

WHERE Цена > ANY (SELECT Цена FROM Заказано WHERE Скидка >= .25);

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

Параметры запроса (только Access)

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

Также можно организовать ввод параметров через собственное диалоговое окно. Для этого имя параметра должно представлять собой полную ссылку на элемент формы (например, Forms![Параметры отчета]![txtMinValue]). Однако данный случай справедлив только для ситуаций, когда пользователь работает с формой, содержащей это поле.

SELECT Сотрудники.ФИО, Сотрудники.Зарплата

FROM Сотрудники

WHERE Сотрудники.Зарплата>=[Введите минимальную зарплату];

В данном случае Access предложит пользователю форму ввода с одним текстовым полем и подписью "Введите минимальную зарплату".

Ключевое слово PARAMETERS позволяет определить типы параметров. Размещается в самом начале запроса. Для нашего примера с зарплатой, параметр минимальной зарплаты должен иметь денежный тип. Поэтому окончательный вариант запроса будет таким:

PARAMETERS [Введите минимальную зарплату] Currency;

SELECT Сотрудники.ФИО, Сотрудники.Зарплата

FROM Сотрудники

WHERE Сотрудники.Зарплата>=[Введите минимальную зарплату];

То есть сначала имя параметра, потом через пробел его тип (по-английски). Если несколько параметров, эти пары перечисляются через запятую.

Для строк все то же самое, только тип обычно выглядит как Text(255). В скобках – длина.

При создании запросов в конструкторе предложению PARAMETERS соответствует диалоговое окно Запрос->Параметры (не путать с Сервис->Параметры). Там же выбираются типы.

Порядок выполнения запроса, вообще говоря, определяется оптимизатором запросов. Смысл в том, что один и тот же запрос можно выполнить по-разному. Оптимизатор выбирает среди всех возможных вариантов самый быстрый. Например, при объединении (INNER JOIN) студентов и групп можно сначала загрузить группы, а потом "подцеплять" студентов, либо наоборот. Или осуществлять ли сначала проекцию (выбор из таблицы определенных полей) для каждой таблицы, а потом собирать, или сначала все собрать, а потом "выкинуть" лишнее. На каком этапе производить отбор?

На примере одной таблицы, что может быть. "В лоб": СУБД просматривает все таблицы, указанной во FROM, записи по очереди и для каждой проверяет логическое выражение из WHERE. Если удовлетворяет, "складывает" эту запись в какую-нибудь временную область памяти. При этом вычисляются выражения в SELECT и отбираются нужные поля. После прохода всей таблицы при наличии DISTINCT отбрасываются дубликаты (а при DISTINCTROW, стало быть, надо было сначала пройтись по таблице и отбросить дубликаты), затем осуществляется сортировка. Если есть TOP, то берем столько записей (или процентов записей), сколько указано. В конце концов, результат выдается на экран. Но, конечно, такой сценарий практически не применяется, особенно если есть индексы. Если все поля в условии отбора проиндексированы, тогда осуществляется выборка полей на основе сведений в индексах. Заодно выполняется сортировка.

5