- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Контрольні питання
- •Контрольні питання
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.2: основні конструкції мови.
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.2: основні конструкції мови.
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.2: основні конструкції мови.
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.2: основні конструкції мови
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.2: основні конструкції мови
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.3: галуження і цикли
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.3: галуження і цикли
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.3: галуження і цикли
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.3: галуження і цикли
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.3: галуження і цикли
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.4: елементи інтерфейсу
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.5: основи створення прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.5: основи створення прикладних застосувань
- •План заняття
- •Контрольні питання
- •Контрольні питання:
- •Необхідні теоретичні відомості для практичної роботи:
- •Контрольні питання:
- •Змістовий модуль 1: основні поняття та означення. Елементи мови. Керування процесом обчислень
- •Тема 1.5: основи створення прикладних застосувань
- •План заняття
- •Проект Delphi
- •Модулей в проект.
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.1: основи мови object pascal
- •План заняття
- •Контрольні питання
- •Контрольні питання
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.1: основи мови object pascal
- •План заняття
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.1: основи мови object pascal
- •План заняття
- •Контрольні питання
- •Контрольні питання
- •Функции преобразования в числовой формат и обратно
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.1: основи мови object pascal
- •План заняття
- •7.1. Простые типы
- •Контрольні питання
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.2: графіка, мультимедія та друк
- •План заняття
- •Контрольні питання
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.2: графіка, мультимедія та друк
- •План заняття
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.2: графіка, мультимедія та друк
- •План заняття
- •Контрольні питання
- •Контрольні питання
- •Змістовий модуль 2: процедурно-орієнтоване програмування. Програмування графіки
- •Тема 2.2: графіка, мультимедія та друк
- •План заняття
- •Контрольні питання
- •Печать с помощью объекта Printer
- •Подготовка и печать отчетов с помощью QuickReport — компоненты QuickRep, qrSubDetail, qrLabel, qrExpr, qrSysData, qrMemo, qrRichText, qrShape, qrImage
- •Контрольні питання
- •Змістовий модуль 3: масиви. Записи та множини
- •Тема 3.1: масиви
- •План заняття
- •Листинг 1. Инициализация и вывод массива
- •Ввод массива
- •Использование компонента StringGrid
- •Листинг 2. Ввод и обработка массива целых чисел
- •Листинг 3. Процедура обработки события OnKeyPress
- •Листинг 4. Ввод и обработка массива дробных чисел
- •Контрольні питання
- •Объявление записи
- •Инструкция with
- •Ввод и вывод записей в файл
- •Вывод записи в файл
- •Листинг 25. Добавление записей в файл
- •Чтение записи из файла
- •Листинг 26. Чтение записей из файла
- •Контрольні питання
- •Змістовий модуль 3: масиви. Записи та множини
- •Тема 3.3: множини
- •План заняття
- •Контрольні питання
- •Необхідні теоретичні відомості для практичної роботи:
- •Контрольні питання:
- •Змістовий модуль 3: масиви. Записи та множини
- •Тема 3.4: множини обовязкова контрольна робота №28
- •Змістовий модуль 4: файлові структури даних. Динамічні структури даних
- •Тема 4.1: робота з файлами
- •План заняття
- •Объявление файла
- •Назначение файла
- •Вывод в файл
- •Открытие файла для вывода
- •Листинг 20. Создание нового или замещение существующего файла
- •Листинг 21. Добавление в существующий файл
- •Ошибки открытия файла
- •Закрытие файла
- •Пример программы
- •Листинг 22. Простая база данных (запись в файл)
- •Ввод из файла
- •Открытие файла
- •Листинг 23. Обработка ошибки открытия файла (фрагмент программы)
- •Чтение данных из файла
- •Чтение чисел
- •Чтение строк
- •Конец файла
- •Листинг 24.. Чтение из файла
- •Контрольні питання
- •Змістовий модуль 4: файлові структури даних. Динамічні структури даних
- •Тема 4.1: файлові структури даних. Динамічні структури даних
- •План заняття
- •Контрольні питання
- •Указатели
- •Динамические переменные
- •Листинг 27. Создание, использование и уничтожение динамических переменных
- •Листинг 28. Добавление элемента в начало динамического списка
- •Упорядоченный список
- •Добавление элемента в список
- •Листинг 29. Добавление элементов в упорядоченный список
- •Удаление элемента из списка
- •Листинг 30. Удаление узла из списка
- •Контрольні питання
- •Необхідні теоретичні відомості для практичної роботи:
- •Контрольні питання:
- •Необхідні теоретичні відомості для практичної роботи:
- •Контрольні питання:
- •Змістовий модуль 4: файлові структури даних. Динамічні структури даних
- •Тема 4.2: динамічні структури
- •План заняття
- •Вариантные переменные
- •Контрольні питання
- •Const-параметры
- •Контрольні питання
- •Змістовий модуль 4: файлові структури даних. Динамічні структури даних
- •Тема 4.2: динамічні структури
- •План заняття
- •Способы вызова подпрограмм
- •Контрольні питання
- •Этапы разработки программы
- •Спецификация
- •Создание установочного диска
- •Алгоритм и программа
- •Контрольні питання
- •Этапы разработки программы
- •Спецификация
- •Создание установочного диска
- •Алгоритм и программа
- •Контрольні питання
- •Контрольні питання
- •Необхідні теоретичні відомості для практичної роботи:
- •Контрольні питання:
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.2: Візуальні компоненти
- •План заняття
- •Контрольні питання
- •Распознавание источника события, нажатых кнопок и клавиш, координат курсора
- •События клавиатуры
- •Распознавание нажатых клавиш
- •Контрольні питання
- •Создание нового IntraWeb приложения
- •Редактирование главной формы
- •Написание обработчика события для кнопки
- •Запуск созданного приложения
- •Контрольні питання
- •Управляющие кнопки Button и BitBtn
- •Кнопка с фиксацией SpeedButton
- •Группы радиокнопок — компоненты RadioGroup, RadioButton и GroupBox
- •Контрольні питання
- •Листинг 28. Добавление элемента в начало динамического списка
- •Упорядоченный список
- •Добавление элемента в список
- •Листинг 29. Добавление элементов в упорядоченный список
- •Удаление элемента из списка
- •Листинг 30. Удаление узла из списка
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Упражнения. Совершенствование проекта
- •Контрольні питання:
- •Контрольні питання
- •Упражнения
- •Контрольні питання:
- •Змістовий модуль 6: програмування з графами. Вызуальны компоненти. Бази даних.
- •Тема 6.2: візуальні компоненти
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.3: форми та меню
- •План заняття
- •Контрольні питання
- •Контекстное всплывающее меню — компонент PopupMenu
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.4: обробка виключних ситуацій
- •План заняття
- •Конрольні питання
- •Упражнения. Совершенствование проекта.
- •Контрольні питання:
- •Змістовий модуль 6: програмування з графами
- •Тема 6.4: обробка виключних ситуацій
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питанна
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.5: організація прикладних застосувань
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.6: основи баз даних
- •План заняття
- •Классификация баз данных
- •Локальная база данных
- •Удаленная база данных
- •Структура базы данных
- •Контрольні питання
- •Контрольні питання
- •Упражнения
- •Контрольні питання:
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.6: основи баз даних
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Insert into Имя таблицы
- •Insert into Имя_таблицы
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
- •Рисование круга
- •Контрольні питання
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи обов’язкова контрольна робота №63
- •Змістовий модуль 6: програмування з графами. Візуальні компоненти. Бази даних
- •Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
- •План заняття
Контрольні питання
Навести характеристику SQL запитів
Надати поняття принципам роботи оператора CREATE TABLE
Надати поняття принципам роботи оператора DROP TABLE
САМОСТІЙНА РОБОТА СТУДЕНТА
Змістовий модуль 6: програмування з графами
Тема 6.7: навігація по набору даних. Мова sql. Створення довідкової системи
Самостійне заняття №44 – Організація відбору даних
План заняття
Характеристика роботи оператора Select
Характеристика формату команди Select
Отбор данных из таблиц БД осуществляется с помощью оператора SELECT. Результат такого отбора данных называется выборкой.
Оператор SELECT - наиболее часто используемый и самый важный оператор языка SQL. Он позволяет получать выборки данных из одной или нескольких таблиц БД и преобразовывать результаты к нужному виду. С помощью этого оператора можно реализовать довольно сложные условия выбора данных. В общем виде этот оператор имеет такой формат:
SELECT [DISTINCT] {*поле![,поле2...]} FROM таблиця,а1
[, таблица2 . . . ] [WHERE условия_отбора]
[GROUP BY список_группируемых_полей]
[HAVING условие_группироваяля]
[ORDER BY список_полей_для_сортировки]
[UNION onepaтop SELECT)
Описание оператора SELECT требует обязательного указания списка полей, а также операнда FROM, после которого приводится список таблиц, используемых для отбора данных. Все остальные операнды могут не указываться. В самом простом случае данный оператор может иметь, например, такой вид:
SELECT Tovar, Price FROM shop
В результате выполнения данного оператора будет сформирован набор данных, содержащий значения полей Tovar и Price из таблицы shop.
Список полей приводится непосредственно после ключевого слова SELECT, при этом имена полей отделяются одно от другого запятыми. При указании дополнительного описателя DISTINCT после ключевого слова SELECT обеспечивается исключение из выборки одинаковых записей, для которых совпадают значения всех полей, указанных в операторе SELECT.
Если в набор данных необходимо включить все поля заданной таблицы (таблиц), то вместо перечисления имен полей можно указать символ «*». Допустим, таблица firm. db содержит поля: Tab_nom, Fio, Otdel, Dolgn и Salary. Тогда следующие два оператора абсолютно идентичны:
SELECT Tab_nom, Fio, Otdel, Dolgn, Salary FROM firm
или
SELECT * FROM firm
При отображении содержимого набора данных по результатам выполнения SQL-запроса в компоненте DBGrid по умолчанию в качестве заголовков столбцов будут использоваться соответствующие имена полей. Однако существует возможность переопределить эти заголовки, для чего используется описатель AS, который ставится после имени поля, а за ним указывается отображаемый заголовок столбца. Это делается таким образом:
SELECT Nom_stud AS Номер, Fio AS Фамилия,
Grup AS Группа FROM students
Использование условий отбора записей. В секции WHERE оператора SELECT можно задать необходимое условие отбора, что позволит включать в выборку не все записи, а только те, которые соответствуют заданному условию. При использовании данного операнда в набор данных будут включаться только те записи, которые удовлетворяют установленным условиям поиска (отбора).
При сравнении значения столбца с константой условие поиска имеет такое общее описание:
WHERE ямя_поля операция константа
В качестве операции может выступать одна из операций отношения: = (равно), > (больше), < (меньше), >= (больше или равно), <= (меньше или равно), ! < (не меньше), ! > (не больше), <> (не равно), != (не равно). Кроме того, условие может быть составным, для объединения частей которого применяются круглые скобки и логические функции NOT, AND, OR. Ниже показан пример оператора SELECT с использованием условия отбора.
SELECT Nom_r, Time_dep
FROM reys
WHERE Punkt_dep='Берлин' AND
Punkt_arr='Лондон'AND Time_dep>=l5:00
Результатом выполнения приведенного запроса будет набор данных, в который будут включены два поля Nom_r и Time_dep, показывающие, соответственно, номера рейсов и время отправления самолетов. При этом накладывается ряд ограничений. В частности, будут отобраны только те записи, для которых пункт отправления (Punkt_dep) - Берлин, пункт прибытия (Punkt_arr) - Лондон и время отправления (Time_dep) - в 15:00 или позже.
Существует еще несколько операций, которые могут быть использованы при формировании условия поиска:
BETWEEN - обеспечивает проверку вхождения значения поля в заданный диапазон;
IN - служит для проверки вхождения значения поля в заданный набор значений;
LIKE - позволяет производить сравнение по заданной маске. В маске могут быть использованы следующие специальные символы: '%' - для обозначения произвольной строки любой длины, '_' - для обозначения произвольного единичного
символа. Если данные символы должны использоваться в шаблоне как таковые, без учета их специального значения, то операция дополняется описателем ESCAPE символ, позволяющим задать символ, появление которого в шаблоне отменяет специальные функции следующего за ним символа;
■ IS NULL - используется для проверки неопределенного значения поля.
Практические примеры использования перечисленных операций при создании запросов приведены ниже.
SELECT Fam, Rost, Ves FROM grup
WHERE (Ves BETWEEN 45 AND 65)
AND (Rost in (160, 165, 170))
Результатом выполнения этого запроса будет набор данных, содержащий поля: Фамилия (Fam), Рост (Rost) и Вес (Ves). Набор данных формируется на основе записей из таблицы grup, у которых значение поля Ves находится в диапазоне от 45 до 65 и значение поля Rost точно равно одному из трех чисел: 160,165 или 170.
SELECT Fam, Name
FROM spisok
WHERE Fam LIKE '_ва%'
В результате выполнения данного оператора выводятся значения полей Fam и Name всех записей таблицы, у которых значение поля Fam начинается с любого символа, затем следуют буквы «ва», а после них может стоять любая строка, в том числе и пустая. Так, например, указанному условию удовлетворяют такие значения: «Ива», «Иванов», «Уваров», «4ва64про@&>56» и т.д.
SELECT *
FROM people
WHERE Name IS NOT NULL
Данный запрос позволяет вывести все записи таблицы people, для которых определено значение поля Name. Записи, у которых значение этого поля не определено, не включаются в результирующий набор данных.
Дополнительные функции SOL.
В языке SQL существует ряд дополнительных функций, которые могут быть использованы при составлении запросов. Среди них можно выделить такие функции:
UPPER {строка) - преобразует все символы строки в символы верхнего регистра;
LOWER (строка) - преобразует все символы строки в нижний регистр;
■ TRIM (строка) - удаляет символы пробела в начале и в конце строки;
■ SUBSTRING (строка FROM nl ТО п2) - выделяет из строки подстроку, начиная с позиции nl и заканчивая позицией п2;
CAST (выражение AS тип_данных) - преобразует выражение к заданному типу данных;
Строка_1 | строка_2 - осуществляет конкатенацию (соединение) двух строк;
EXTRACT (элемент FROM выражение) -извлекает значение, соответствующее указанному элементу, из выражения, содержащего значение даты или времени. В качестве параметра элемент могут быть заданы такие значения: YEAR, MONTH, DAY, HOUR, MINUTE или SECOND (год, месяц, день, час, минута и секунда соответственно).
Примеры использования описанных функций приводятся ниже.
SELECT UPPER(Fam)
FROM spisok
WHERE LOWER(Name)='Владимир'
В результате выполнения данного оператора будут большими буквами выведены значения поля Fam всех записей, для которых значение поля Name, преобразованное к символам нижнего регистра, равно «Владимир».
SELECT *
FROM people
WHERE EXTRACT(MONTH FROM Birth)=10
Представленный запрос обеспечивает отбор из таблицы people всех записей, у которых значение месяца в поле Birth равно 10 (то есть октябрь).
Сортировка записей.
Сортировка или упорядочение записей по возрастанию или по убыванию значений полей осуществляется с помощью операнда ORDER BY. После него приводится список полей, по которым должна производиться сортировка. Записи будут упорядочены в зависимости от порядка указания полей. Вначале осуществляется сортировка по первому указанному полю; затем для записей, имеющих одинаковое значение первого поля, происходит упорядочение по второму полю и т.д.
Сортировка может выполняться как для индексированных, так и для неиндексированных полей. Поля в списке обозначаются именами или номерами, соответствующими порядку расположения полей в списке после ключевого слова SELECT.
По умолчанию производится сортировка в порядке возрастания значений поля. Описатель DESC, который указывается после имени (или номера) соответствующего поля, позволяет упорядочить записи по убыванию значений данного поля.
SELECT Number, Address, Floor, Room, Square,
Price FROM flat ORDER BY Room, Price DESC, 5
При выполнении данного запроса выводятся записи таблицы flat.db, в которой содержатся сведения о предлагаемых на продажу квартирах. Записи сортируются следующим образом. Вначале происходит сортировка в зависимости от количества комнат, то есть по возрастанию значений поля Room. Затем записи, у которых совпадает количество комнат, сортируются по убыванию стоимости квартиры (значения поля Price). И, наконец, записи, у которых одинакова комбинация значений полей Room и Price, упорядочиваются по возрастанию пятого поля из списка полей в разделе SELECT. Пятым полем в списке является поле Square, которое содержит данные о площади квартиры. Результат может выглядеть примерно так, как это показано на рис. 15.2.
Агрегатные функции. В SQL-запросах предусмотрено использование так называемых агрегатных функций, которые позволяют получать некоторую общую величину, которая рассчитывается на основе всех значений набора данных или определенной группы записей. В SQL существуют следующие агрегатные функции:
COUNT (выражение) - подсчитывает число вхождений заданного выражения во все записи результирующего набора данных;
SUM (выражение) - определяет общую сумму значений, определяемых параметром выражение;
AVG (выражение) -вычисляет среднее значение;
МАХ (выражение) - находит максимальное значение;
MIN (выражение) - определяет минимальное значение
Ниже приводятся примеры создания запросов с использованием агрегатных функций.
SELECT COUNT(DISTINCT Name)
FROM firm
WHERE Dolgn = 'Водитель'
В результате выполнения этого запроса выводится количество неповторяющихся и непустых значений поля Name для всех записей таблицы firm, у которых значение поля Dolgn равно «Водитель». Другими словами, подсчитывается количество водителей, работающих в данной фирме.
SELECT SUM(Price*Kolvo)
FROM shop
WHERE Date=ll.08.99
Результатом выполнения данного оператора является общая сумма денег, вырученная магазином за день. Она рассчитывается путем суммирования произведений значения поля Цена (Price) на значение поля Количество (Kolvo) для всех записей таблицы shop, у которых значение поля Date равно 11.08.99.
SELECT MAX(Salary) FROM firm
Вышеприведенный запрос выводит максимальное значение поля Salary среди всех записей таблицы firm (т.е. определяется размер максимальной заработной платы среди всех сотрудников фирмы).
Группирование записей. Группирование данных используется, главным образом, в ситуациях, когда необходимо получить агрегированные значения (минимум, максимум, среднее, сумма, количество) не по всему набору данных, а по каждой из входящих в него групп записей, характеризующихся одинаковым значением какого-либо поля. Например, следующий запрос позволяет получить общее количество сотрудников по каждому отделу фирмы.
SELECT Otdel, COUNT(Tab_nom) FROM firm GROUP BY Otdel
В ряде случаев необходимо установить некоторые ограничения на группируемые значения. Для этого применяется операнд HAVING. К примеру, если в предыдущем примере требуется вывести только те отделы, в которых количество сотрудников более 10, то это можно осуществить с помощью запроса такого вида:
SELECT Otdel, COUNT(Tab_nom)
FROM firm
GROUP BY Otdel
HAVING COUNT(Tab_nom)>10
Отбор данных из нескольких таблиц.
С помощью SQL-запроса можно легко сформировать выборку на основе использования данных из нескольких таблиц. В случае, когда требуется выбрать поля из набора таблиц, для указания принадлежности поля к определенной таблице используется составное имя, включающее имя таблицы, разделительную точку и имя поля:
Имя_таблицы. нмя_поля
Если связь между двумя таблицами не установлена, то в результирующий набор данных войдут все возможные комбинации записей указанных таблиц, то есть каждой записи одной таблицы будет поставлена в соответствие каждая запись другой таблицы. На практике редко возникает необходимость формирования подобного рода наборов данных. Гораздо чаще между таблицами устанавливается связь по определенному полю или группе полей. Такую связь можно установить, используя описатель INNER JOIN в секции FROM, либо задавая соответствующее условие в секции WHERE.
Например, в БД имеется две таблицы, в одной из которых хранятся данные обо всех преподавателях института, а в другой содержится расписание занятий различных групп. Первая таблица inst.db имеет такие поля: Фамилия преподавателя (Fam), Должность (Dolgn), Кафедра (Kaf). Вторая таблица rasp.db содержит поля: Дисциплина (Discipl), Группа (Grup), День недели (Day), Время (Vrem), Аудитория (Audit), Преподаватель (Prep). Допустим, из второй таблицы необходимо выбрать все записи, относящиеся к парам, которые проводят преподаватели кафедры иностранного языка. Как видно из описания таблиц, в расписании не указано, на какой кафедре работает тот или иной преподаватель. Поэтому, чтобы выбрать необходимые сведения, нужно воспользоваться информацией из первой таблицы. Решить поставленную задачу можно следующим образом. Между таблицами устанавливается связь по фамилии преподавателя и формируется промежуточный набор данных, содержащий записи обеих таблиц, у которых совпадают значения соответствующих полей. Затем из этого набора данных исключаются все записи, которые не удовлетворяют заданному условию, то есть в результирующий набор данных войдут только записи таблицы rasp, содержащие информацию о парах, которые проводят преподаватели кафедры иностранных языков. Реализуется это с помощью запроса следующего вида:
SELECT rasp.*
FROM inst INNER JOIN rasp ON
inst.Fam=rasp.Prep WHERE (inst.Kaf='Иностранный язык')
Однако более просто такого же результата можно добиться при выполнении следующего запроса (такой способ намного проще и на практике используется гораздо чаще):
SELECT rasp.* FROM inst, rasp
WHERE (inst.Kaf='Иностранный язык')
AND (inst.Fam=rasp.Prep)
Этот способ также обладает тем преимуществом, что он позволяет устанавливать связь сразу между несколькими таблицами, а не только между двумя. Следует также отметить, что в условии
связи кроме знака равенства допустимо использовать и любые другие операторы сравнения.
Как видно из приведенных запросов, перед именами полей указаны имена соответствующих таблиц. Вообще говоря, если имена полей в разных таблицах не совпадают, указывать имена этих таблиц не обязательно, однако все же лучше задавать, к какой таблице относится каждое поле (когда поля таблиц имеют одинаковые имена, то имя таблицы перед именем поля приводится обязательно). Если таблица имеет длинное имя, то вместо него рекомендуется использовать псевдоним, указываемый для каждой таблицы в секции FROM. Делается это следующим образом:
SELECT DISTINCT a.Fam, b.Grup FROM inst a, rasp WHERE a.Fam=b.Prep
В результирующий набор данных войдут неповторяющиеся записи, отражающие информацию о том, в каких группах проводит занятия каждый преподаватель. В приведенном запросе вместо имен таблицы применены псевдонимы: а — для таблицы inst и b - для таблицы rasp.
Описанный тип связи между двумя таблицами называется внутренней связью. Он характеризуется тем, что задается условие связи между соответствующими столбцами и выводятся только удовлетворяющие данному условию записи.
Кроме этого существует еще так называемая внешняя связь. Такая связь реализуется с помощью описателя JOIN и характеризуется тем, что одна из таблиц является ведущей, а другая — ведомой, и в результирующий набор данных кроме записей, удовлетворяющих условию связи, включаются и все остальные записи ведущей таблицы, которым в соответствие ставятся пустые записи.
Какая из таблиц будет ведущей, определяет вид соединения:
LEFT - левое внешнее соединение, при котором ведущей является таблица, расположенная в описании слева от описателя вида соединения;
RIGHT - правое внешнее соединение, при котором ведущей является таблица, расположенная в описании справа от описателя вида соединения;
FULL - полное внешнее соединение, при котором ведущими являются обе таблицы. В результирующий набор данных включаются записи обеих таблиц по следующему алгоритму. Прежде всего, в набор данных включаются все записи, удовлетворяющие условию соединения. Параллельно с этим добавляются записи первой таблицы, не удовлетворяющие условию соединения. Им в соответствие ставятся пустые записи. Аналогичным образом включаются в набор данных все не удовлетворяющие условию соединения записи второй таблицы, которые также объединяются с пустыми записями.
Рассмотрим пример левого внешнего соединения, построенного на основе таблиц, содержащих список преподавателей института и расписание занятий, которые были описаны выше.
SELECT a.Fam, a.Dolgn, b.Discipl, b.Grup
FROM inst a LEFT JOIN rasp b
ON a.Fam = b.Prep
Результат выполнения данного запроса будет выглядеть примерно так, как показано на рис. 15.3.
Как видно из приведенного рисунка, в сформированном наии-ре данных информации о преподавателях из общего списка, хранящегося в таблице inst.db, ставятся в соответствие записи из расписания (таблица rasp. db), содержащие имя того же преподавателя. Если такая запись в расписании не найдена, то данным из общего списка преподавателей в соответствие ставится пустая запись. В этом примере использование такого соединения позволяет получить более полную картину и увидеть не только тех преподавателей, для которых назначено проведение занятий по соответствующим дисциплинам в различных группах, но также и тех, которые свободны от проведения занятий. В подобной ситуации использование внешнего соединения может быть очень удобным.
Вложенные запросы.
В некоторых случаях невозможно решить задачу путем использования единственного запроса (например, в тех ситуациях, когда заранее не определено условие отбора данных). Поэтому иногда возникает необходимость использовать подзапросы (вложенные запросы). В общем виде подзапрос выглядит следующим образом:
SELECT ... FROM ...
WHERE сравниваемое_поле оператор (SELECT ...)
Синтаксис вложенного запроса ничем не отличается от формата основного запроса. Подзапрос должен быть заключен в круглые скобки.
Например, следующий запрос позволяет полностью вывести записи, у которых поле Price имеет минимальное значение:
SELECT *
FROM flat
WHERE Price = (SELECT MIN(Price) FROM flat)
Такие запросы могут формироваться и на основе данных из нескольких таблиц. Например, приведенный ниже запрос выводит список имен и адресов всех покупателей, которые купили в магазине самый дорогой товар.
SELECT b.Name, b.Address
FROM shop a, clients b
WHERE (a.Tovar = b.Tovar) AND
Price = (SELECT MAX(Price) FROM shop)
Информация о товарах хранится в таблице БД shop.db, a сведения о покупателях - в таблице client.db. С помощью подзапроса из таблицы shop. db выбирается запись, содержащая максимальное значение в поле Price (Цена товара). Затем в таблицеclient.db отбираются все записи, для которых значение поля Tovar совпадает с названием выбранного с помощью подзапроса товара, и из этих записей выделяется требуемая информация о покупателях.
Весьма распространенной ошибкой начинающих программистов является использование вложенного запроса, который может вместо единичного значения возвращать список значений:
SELECT *
FROM flat
WHERE Number = (SELECT Number
FROM flat
WHERE Room = 3)
В данном случае результатом вложенного запроса является множество значений. Попытка сравнить единичное значение поля с таким множеством приведет к инициированию исключительной ситуации. Поэтому подобное использование подзапросов недопустимо. Правильным решением в данном случае может быть указание в условии поиска вместо знака равенства оператора IN, обеспечивающего возможность выбора одного из нескольких значений:
SELECT *
FROM flat
WHERE Number IN (SELECT Number
FROM flat
WHERE Room = 3)
Любой подзапрос может также иметь вложенный запрос, который, в свою очередь, может содержать подзапрос, и т.д. Данная возможность достаточно широко используется на практике.
Предположим, что имеется таблица dom. bd, содержащая список всех жильцов дома. Следующий запрос позволяет вывести список жителей квартиры, в которой живет самый старый жилец дома.
SELECT a.* FROM dom a WHERE a.Nom_kv IN
(SELECT b.Nom_kv FROM dom b WHERE b.Vozrast =
(SELECT MAX(c.Vozrast) FROM dom c))
Поясним логику формирования данного запроса. Вначале, в подзапросе с самой большой глубиной вложения, выбирается максимальное значение в поле Vozrast (Возраст жильца). Затем в подзапросе, расположенном на уровень выше предыдущего, определяется номер квартиры (поле Nom_kv), где проживает жилец, возраст которого равен отобранному максимальному значению. И, наконец, основной запрос отбирает все записи, относящиеся к жильцам данной квартиры, то есть записи, у которых значение поля Nom_kv совпадает с отобранным значением. Если существует несколько старейших жильцов, у которых возраст одинаков, то также будет выведен список проживающих с ними в одних квартирах.
Следует обратить внимание на использование псевдонимов в данном запросе. Как видно из текста запроса, одна и та же таблица используется и в основном, и во вложенном запросе. В подоб-. ной ситуации обязательно применяются псевдонимы, поскольку в противном случае при сравнении полей будет неясно, когда происходит обращение к полю, относящемуся к основному запросу, а когда - к вложенному. Использование имен таблиц в данном случае также не поможет, так как данные берутся из одной и той же таблицы, а поэтому во избежание ошибки следует указать соответствующие псевдонимы.
Бывают случаи, когда возникает необходимость отбирать записи, для которых вложенный запрос возвращает одно или несколько значений, но при этом решающим является факт существования некоторого значения, а не само это значение (например, имеет значение только сам факт покупки, независимо от того, что именно было куплено, на какую сумму и т.п.). В таком случае может быть использован оператор EXISTS.
SELECT DISTINCT a.Name, a.Address
FROM clients a
WHERE EXISTS (SELECT b.Customer
FROM shop b
WHERE a.Name = b.Customer)
Вышеприведенный запрос позволяет получить список имен и адресов всех покупателей, которые сделали хотя бы одну покупку в данной фирме.
При использовании подзапросов, возвращающих множество значений, могут применяться специальные операторы ALL, SOME или ANY.
Оператор ALL указывает на то, что условие поиска будет истинным, если сравниваемое значение находится в определенном отношении со всеми значениями, возвращаемыми подзапросом. Поясним сказанное на небольшом примере.
Допустим, имеется таблица liga. db, в которой хранится информация обо всех игроках футбольной лиги. Запрос, представленный ниже, позволяет вывести сведения об игроках, возраст которых меньше любого из значений среднего возраста игроков, определяемого для каждой команды в отдельности.
SELECT *
FROM liga a
WHERE a.Vozrast < ALL
(SELECT AVG(b.Vozrast) FROM liga b GROUP BY b.Komanda)
Действия операторов SOME и ANY абсолютно одинаковы. Они показывают, что условие истинно, когда сравниваемое значение находится в нужном отношении хотя бы с одним значением, возвращаемым подзапросом.
Если немного изменить предьщущий запрос, подставив операнд ANY вместо операнда ALL, то запрос принимает следующий вид:
SELECT *
FROM liga a
WHERE a.Vozrast < ANY
(SELECT AVG(b.Vozrast) FROM liga b GROUP BY b.Komanda)
Результатом выполнения такого запроса будет список всех игроков, у которых возраст меньше хотя бы одного из средних значений возрастов, определяемых по каждой отдельной команде.
Рассмотрим простейшую ситуацию, когда в таблице содержатся данные об игроках только двух команд, и средний возраст игроков первой команды - 23 года, а второй команды - 25 лет. В случае использования первого из приведенных запросов (с операндом ALL) в результирующий список попадут только игроки, имеющие возраст меньше 23 лет (меньше любого из средних значений - как первого, так и второго). В случае же применения второго запроса (с операндом ANY) в результирующем списке окажутся все игроки, имеющие возраст менее 25 лет (меньше хотя бы одного из средних значений).
Объединение запросов.
В некоторых случаях требуется объединить результаты выполнения нескольких операторов SELECT. Такое объединение производится с помощью оператора UNION. При этом результирующие наборы данных должны иметь одинаковый формат, то есть одинаковый состав возвращаемых полей и полное совпадение типов данных соответствующих полей. Если в результирующих наборах данных, сформированных после выполнения различных запросов, имеется одна и та же запись, то она не дублируется в сводном наборе данных.'
Ниже показано, как можно объединить результаты выполнения трех запросов. В рассматриваемом примере осуществляется отбор данных из таблицы anim. db, содержащей информацию о различных животных. Таблица включает такие поля: название животного (Animal), длина тела животного (Dlina), вес животного (Ves).
Первый запрос выводит записи, у которых поле Animal имеет значение «Бурозубка». Второй запрос выбирает из таблицы записи, для которых значение поля Dlina равно 12. Третий запрос отбирает записи, значение поля Ves которых превосходит 300.
SELECT *
FROM anim
WHERE Animal = ЛБурозубка'
UNION
SELECT *
FROM anim
WHERE Dlina = 12 UNION SELECT * FROM anim WHERE Ves > 300
На рис. 15.4 представлен пример выполнения вышеприведенного объединения запросов.
В рассмотренном примере объединяются данные, отбираемые с помощью различных запросов из одной и той же таблицы. В общем случае это не обязательно, т.е. могут быть объединены и данные из различных таблиц. Однако в таком случае нужно более внимательно следить за совпадением типов данных полей и порядком их вывода в объединяемых за просах.