Скачиваний:
17
Добавлен:
01.05.2014
Размер:
81.15 Кб
Скачать

Лабораторная работа №3 Лабораторная работа №3. Элементарные выборки посредством оператора SELECT. Агрегатные функции SQL.     1. Цель:

    Изучение работы оператора SELECT языка SQL. Изучение возможностей обработки данных с помощью агрегатных функций языка SQL.

    2. Введение

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

    3. Методика выполнения лабораторной работы

    1. Изучить рекомендации по выполнению работы и определить вариант задания.

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

    3. Создать запрос, задающий порядок столбцов, отличный от исходного.

    4. Продемонстрировать действие модификатора DISTINCT.

    5. Ограничить вывод запроса, используя WHERE с простым условием.

    6. Ограничить вывод запроса, используя WHERE и составное условие.

    7. Продемонстрировать действие специальных функций IN, BETWEEN, LIKE, и IS NULL в условии.

    8. Продемонстрировать работу специальных функций с условием NOT.

    9. Ознакомиться с принципами работы агрегатных функций COUNT, SUM, AVG, MAX, MIN.

    10. Продемонстрировать использование COUNT(*)

    11. Продемонстрировать выполнение простых вычислений в запросе.

    12. Использовать простое вычисление как параметр агрегатной функции.

    13. Ознакомиться с использованием предложения GROUP BY, продемонстрировать его работу.

    14. Ознакомиться с использованием предложения HAVING, продемонстрировать его работу.

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

    4. Варианты заданий

    Вариант задания (таблица 1) выбирается по формуле (N mod 24)+1, где N - последние две цифры зачетной книжки студента. В варианте задания указаны: номер структуры данных (структуры данных приведены в приложении 1), имя таблицы, условие, которому должны соответствовать обновляемые и удаляемые данные.

Таблица 1 - Варианты заданий № структуры, имя таблицы Поле фильтра Поле группировки Агрегатная функция 1. Публикация  Заглавие  Тип  Последняя дата для данного типа 2. Курс  Название курса  Номер преподавателя  Количество курсов у препод. 3. Операция  Название операции  Номер патента  Количество операций 4. Личность  ФИО  Пол  Самый старший каждого пола 5. Помещение  Адрес  Номер фирмы  Максимальная площадь 6. Служащий  Ф.И.О.  Код профессии  Число служ. по профессиям 7. Деятельность  Номер служ.  Число служ. по профессиям  Кол-во событий каждого типа 8. Студент  Ф.И.О.  Номер группы  Max. Стипендия в каждой группе 9. Экзамен  Наименов. ВУЗа  Код специальности  Средняя оценка 10. Поезд  Маршрут  Станция отправления  Мин. Время прибытия 11. Преподаватель  Ф.И.О.  Должность  Кол-во преподав. в должности 12. Персона  Ф.И.О.  Пол  Среднее кол-во детей 13. Результат соревнований  Название команды  Номер соревнования  Максим. число забитых мячей 14. Концертный зал  Адрес  Количество мест  Число залов 15. Сотрудник  Ф.И.О.  Пол  Количество сотрудников 16. Перевозка  Место назначения  Дата  Средняя цена 17. Гостиница  Адрес  Разряд  Количество гостиниц 18. Курс лечения  Метод лечения  Номер диагноза  Средняя стоимость 19. Комплект.  Наименован.  Номер машины  Макс. Стоимость 20. Газета  Наименован.  Тираж  Мин. Кол-во сотрудников

    5. Содержание отчета

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

    6. Контрольные вопросы

    1. Опишите основные конструкции языка SQL, использованные в лабораторной работе SELECT, DISTINCT, WHERE, IN, BETWEEN, LIKE.

    2. Каким образом можно добавить поле в существующую таблицу, внести значения в существующие записи для этого поля по умолчанию?

    3. Как ввести в запрос на выборку вычисляемое поле?

    4. Для чего используются агрегатные функции. Что является аргументом агрегатной функции. Перечислите агрегатные функции языка SQL.

    5. С какой целью используются предложения GROUP BY и HAVING?     7. Рекомендации по выполнению работы     7.1. Команда SELECT

    SELECT возвращает данные из таблицы, вида или сохраненной процедуры. Различные инструкции SELECT выполняют следующие действия:

    - Возвращают одиночную стоку или часть строки из таблицы. Это операция упоминается, как sigleton выбор.

    - Непосредственно возвращают список строк или список частичных строк из таблицы.

    - Возвращают связанные строки, или частичные строки из join двух или более таблиц.

    - Возвращают все строки, или частичные строки из union двух или более таблиц.

    Любая инструкция SELECT содержит два обязательных параметра (SELECT, FROM) и возможно другие параметры (WHERE, GROUP BY, HAVING, UNION, PLAN, ORDER BY). Параметры SELECT и FROM обязательны и для sigleton, и для multi-row SELECT; все другие параметры перечисленные ниже факультативны. Следующая таблица объясняет назначение каждого параметра:

Параметр Назначение SELECT Список столбцов, которые возвращаются. FROM Определяет таблицы в которых ищутся значения. WHERE Определенное условие поиска, которое используется, чтобы выбрать необходимые стоки из множества всех строк. Предложение WHERE может содержать инструкцию SELECT, которая упоминается, как подзапрос GROUP BY Группирует возвращенные строки основываясь на общих значениях столбцов. Используется совместно с HAVING. HAVING Restricts rows generated by GROUP BY to a subset of those rows. UNION Комбинирует результаты двух или более инструкций SELECT создавая одиночную динамическую таблицу исключая повторяющиеся строки. ORDER BY Определяет порядок сортировки строк возвращенных SELECT, по умолчанию в возрастающем порядке (ASC), или в убывающем порядке (DESC). PLAN Определяет план запроса, который будет использоваться оптимизатором запроса вместо обычного выбора.

    Синтаксис команды SELECT

    SELECT [ DISTINCT | ALL ] ( * | <val> {, <val> })

    FROM <tableref> { , <tableref> }

      [ WHERE <search_condition> ]

      [ GROUP BY col [ COLLATE collation ] { , col [ COLLATE collation ] }

      [ HAVING <search_condition> ]

      [ UNION <select_expr> ]

      [ PLAN <plan_expr> ]

      [ ORDER BY <order_list> ]

     <val> ::= col [ <array_dim> ] | <constant> | <expr> | <function> | NULL | USER | RDB$DB_KEY

     <array_dim> ::= [x:y { , x:y }]

     <constant> ::= num | " string " | charsetname " string "

     <expr> ::= Допустимое выражение SQL, результат которого одиночное значение.

     <function> ::= COUNT (* | [ALL] <val> | DISTINCT <val> )

                         | SUM ( [ALL] <val> | DISTINCT <val> )

                         | AVG ( [ALL] <val> | DISTINCT <val> )

                         | MAX ( [ALL] <val> | DISTINCT <val> )

                         | MIN ( [ALL] <val> | DISTINCT <val> )

                         | CAST ( <val> AS <datatype> )

                         | UPPER ( <val> )

                         | GEN_ID ( generator , <val> )

     <tableref> = <joined_table> | table | view | procedure [( <val> { , <val> })] [ alias ]

     <joined_table> ::= <tableref> <join_type> JOIN <tableref> ON <search_condition> | ( <joined_table> )

     <join-type> ::= ( [ INNER ] | ( LEFT | RIGHT | FULL ) [ OUTER ] ) JOIN

     <search_condition> ::= <val> <operator> ( <val> | ( <select_one> ))

                                           | <val> [ NOT ] BETWEEN <val> AND <val>

                                           | <val> [ NOT ] LIKE <val> [ ESCAPE <val> ]

                                           | <val> [ NOT ] IN ( <val> { , <val> } | <select_list> )

                                           | <val> IS [ NOT ] NULL

                                           | <val> ( [ NOT ] ( = | < | > ) | >= | <= ) ( ALL | SOME | ANY ) ( <select_list> )

                                           | EXISTS ( <select_expr> )

                                           | SINGULAR ( <select_expr> )

                                           | <val> [ NOT ] CONTAINING <val>

                                           | <val> [ NOT ] STARTING [ WITH ] <val>

                                           | ( <search_condition> )

                                           | NOT <search_condition>

                                           | <search_condition> OR <search_condition>

                                           | <search_condition> AND <search_condition>

     <operator> ::= = | < | > | <= | >= | !< | !> | <> | !=

     <select_one> ::= SELECT on a single column that returns exactly one row.

     <select_list> ::= SELECT on a single column that returns zero or more rows.

     <select_expr> ::= SELECT on a list of values that returns zero or more rows.

     <plan_expr> ::= (JOIN | [SORT] MERGE) ( <plan_item> | <plan_expr> {, ( <plan_item> | <plan_expr> )})

     <plan_item> ::= ( table | alias ) NATURAL | INDEX ( <index> { , <index> }) | ORDER <index>

     <order_list> ::= ( col | int ) [COLLATE collation ] ( ASC[ENDING] | DESC[ENDING] ) { , <order_list> }

Аргумент Описание SELECT [ DISTINCT | ALL ] Определяет данные, для поиска. DISTINCT удаляет повторяющиеся значения из возвращенных данных. ALL, параметр по умолчанию, возвращает все данные. ( * | <val> { , <val> } ) * - возвращает все столбцы из определенной таблицы. <val> [, <val> ...] - возвращает определенный список столбцов и значений. FROM <tableref>  { , <tableref> } Список таблиц, видов и сохраненных процедур, из которых возвращаются данные. Список может включать JOIN, объединения могут быть вложенными. table Имя существующей таблицы в базе данных. view имя существующего вида в базе данных. procedure Имя существующей сохраненной процедуры, которая функционирует, как инструкция SELECT. alias Псевдоним - краткое, альтернативное имя для таблицы или вида. After declaration in tabdef , alias can stand in for subsequent references to a table or view. <joined_table> Ссылка таблицы состоящая из JOIN. <join_type> Тип выполнения объединения. По умолчанию INNER. WHERE <search_cond> Определяет условия, которые ограничивают подмножество возвращаемых строк из всех доступных строк. GROUP BY <col> { , <col> } Разделяет результаты запроса в группы содержащие все строки с одинаковыми значениями, основанными на списке столбцов. COLLATE collation Определяет порядок сопоставления для данных возвращаемых запросом. HAVING <search_cond> Используется совместно с GROUP BY. Определяет условия, которые ограничивают группировку возвращаемых строк. UNION Комбинирует две или более таблиц, которые имеют полностью, либо частично одинаковую структуру. PLAN <plan_expr> Определяет план доступа для оптимизатора InterBase, который используется в течении поиска. <plan_item> Определяет таблицу и индексный метод для плана. ORDER BY <order_list> Определяет порядок в котором строки возвращены.

    Примеры команды SELECT

    1) Следующая инструкция выбирает столбцы из таблицы:

SELECT JOB_GRADE, JOB_CODE, JOB_COUNTRY, MAX_SALARY FROM PROJECT;

    2) Следующая инструкция использует шаблон *, что бы выбрать все столбцы и строки из таблицы:

SELECT * FROM COUNTRIES;

    3) Следующая инструкция использует агрегатную функцию, что бы сосчитать все строки в таблице, которые удовлетворяют условиям поиска определенным в предложении WHERE:

SELECT COUNT (*) FROM COUNTRY WHERE POPULATION > 5000000;

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

SELECT C.CITY FROM CITIES C WHERE C.POPULATION < 1000000;

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

SELECT CITY, STATE FROM CITIES ORDER BY STATE;

    6) Следующая инструкция выполняет левое объединение:

SELECT CITY, STATE_NAME FROM CITIES C LEFT JOIN STATES S ON S.STATE = C.STATE WHERE C.CITY STARTING WITH "San";

    7) Следующая инструкция определяет план оптимизации запроса для упорядоченного поиска, использование индекса для упорядочивания:

SELECT * FROM CITIES ORDER BY CITY PLAN (CITIES ORDER CITIES_1);

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

SELECT * FROM CITIES C, STATES S, MAYORS M WHERE C.CITY = M.CITY AND C.STATE = M.STATE PLAN JOIN (STATE NATURAL, CITIES INDEX DUPE_CITY, MAYORS INDEX MAYORS_1);

    9) Следующая инструкция выбирает столбцы из таблицы:

SELECT JOB_GRADE, JOB_CODE, JOB_COUNTRY, MAX_SALARY FROM PROJECT;

    10) Следующая инструкция использует шаблон *, что бы выбрать все столбцы и строки из таблицы:

SELECT * FROM COUNTRIES;

    11) Следующая инструкция использует агрегатную функцию, что бы сосчитать все строки в таблице, которые удовлетворяют условиям поиска определенным в предложении WHERE:

SELECT COUNT (*) FROM COUNTRY WHERE POPULATION > 5000000;

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

SELECT C.CITY FROM CITIES C WHERE C.POPULATION < 1000000;

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

SELECT CITY, STATE FROM CITIES ORDER BY STATE;

    14) Следующая инструкция выполняет левое объединение:

SELECT CITY, STATE_NAME FROM CITIES C LEFT JOIN STATES S ON S.STATE = C.STATE WHERE C.CITY STARTING WITH "San";

    15) Следующая инструкция определяет план оптимизации запроса для упорядоченного поиска, использование индекса для упорядочивания:

SELECT * FROM CITIES ORDER BY CITY PLAN (CITIES ORDER CITIES_1);

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

SELECT * FROM CITIES C, STATES S, MAYORS M WHERE C.CITY = M.CITY AND C.STATE = M.STATE PLAN JOIN (STATE NATURAL, CITIES INDEX DUPE_CITY, MAYORS INDEX MAYORS_1);

    7.2. Агрегатные функции SQL

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

Дата продажи № товара Группа товара Цена покупки 11.12.89 1 1 10 11.12.89 2 1 20 11.12.89 3 2 15 12.12.89 1 1 100 12.12.89 2 1 50

    Группировать поля таблицы можно многими способами. Например, можно сгруппировать продажи по дням, тогда сумма поля «Цена покупки» даст общую выручку по дням. Группируя по номеру товара, и суммируя по тому же полю получим сумму продаж товара с таким-то номером за все дни. Группируя таблицу по группам товара, получим сумму покупок всех товаров данной группы за все дни. В нашем примере мы вычисляем сумму от некоторой группы, сумма в данном случае - агрегатная функция. Группировать можно не только по одному полю, но и по нескольким.

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

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

    Существуют следующие агрегатные функции:

    - COUNT считает количество строк, которые вернул запрос;

    - SUM суммирует значения данного поля;

    - AVG находит среднее значение поля;

    - MAX находит максимальное значение поля;

    - MIN находит минимальное значение поля.

    Тестовая база данных. Рассмотрим работу агрегатных функций на примере базы данных, состоящий из трех таблиц - «Торговый агент», «Покупатели», «Заказы».

    Таблица «Торговый агент» (Salespeople) содержит следующие столбцы:

    - SNUM - номер агента;

    - SNAME - имя агента;

    - CITY - город, где работает агента;

    - COMM - комиссионные торгового агента.

Торговый агент (Salespeople) SNUM SNAME CITY COMM 1001 Peel London 0.12 1002 Serres San Jose 0.13 1004 Motika London 0.11 1007 Rifkin Barcelona 0.15 1003 Axelrod New York 0.10

    Таблица «Покупатель» (Customers) содержит следующие столбцы:

    - СNUM - номер покупателя;

    - СNAME - имя покупателя;

    - CITY - город проживания покупателя;

    - RATING - некоторый рейтинг, присвоенный покупателю;

    - SNUM - номер торгового агенты, за которым закреплен покупатель;

Покупатели (Customers) CNUM CNAME CITY RATING SNUM 2001 Hoffman London 100 1001 2002 Giovanni Rome 200 1003 2003 Liu SunJose 200 1002 2004 Grass Berlin 300 1002 2006 Clemens London 100 1001 2007 Pireira Rome 100 1004 2008 Cisneros SunJose 300 1007

    Таблица «Заказы» (Orders) содержит следующие столбцы:

    - ONUM - номер заказа;

    - AMT - сумма заказа;

    - ODATE - дата заказа;

    - CNUM - номер покупателя;

    - SNUM - номер торгового агента.

Заказы (Orders) ONUM AMT ODATE CNUM SNUM 3001 18.69 10/03/1990 2008 1007 3003 767.19 10/03/1990 2001 1001 3002 1900.10 10/03/1990 2007 1004 3005 5160.45 10/03/1990 2003 1002 3006 1098.16 10/03/1990 2008 1007 3009 1713.23 10/04/1990 2002 1003 3007 75.75 10/04/1990 2004 1002 3008 4723.00 10/05/1990 2006 1001 3010 1309.95 10/06/1990 2004 1002 3011 9891.88 10/06/1990 2006 1001

    Примеры

    Чтобы найти сумму всех покупок в таблице «Заказы», мы можем ввести следующий запрос:

    SELECT SUM ((amt)) FROM Orders;

    Результат его выполнения – число 26658.4

    Чтобы найти среднее значение сумм заказов в таблице «Заказы», мы можем ввести следующий запрос:

    SELECT AVG (amt) FROM Orders;

    Результат его выполнения – число 2665.84.

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

    SELECT COUNT ( DISTINCT snum ) FROM Orders;

    Результат его выполнения – число 5.

    Иногда возникает необходимость решить обратную задачу – подсчитать количество значений поля вместе с повторениями. Для этого существует описатель ALL (он подразумевается по умолчанию). Например, запрос:

    SELECT COUNT ( ALL rating ) FROM Customers;

    подсчитает количествозначений поля rating с повторениями.

    Чтобы подсчитать общее число строк в таблице, используйте функцию COUNT со звездочкой вместо имени поля, как, например, в следующем примере.

    SELECT COUNT (*) FROM Customers;

    Результат его выполнения – число 7.

    Внимание! Только COUNT (*) может подсчитывать значения NULL. Все остальные функции игнорируют неопределенные значения.

    Простые вычисления

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

    SELECT snum, sname, city, comm*100 FROM Salespeople FROM Salespeople;

    Можно дополнить наш запрос знаком процента, выводимым после поля comm*100:

    SELECT snum, sname, city, comm*100, ' % ' FROM Salespeople;

    Знак процента в данном случае – константное выражение. При выполнении вычислений в запросе допустимы арифметические действия – сложение, вычитание, умножение, деление.

    Вычисления в агрегатных функциях

    Допустим, мы хотим вывести 10% от стоимости самой дорогой сделки. Тогда можно записать такой запрос:

    SELECT MAX (amt*0.1) FROM Orders;

    Таким образом можно выполнять вычисления с использованием других полей и арифметических действий. Вложение агрегатов не допускается.

    Использование GROUP BY

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

    Предположим, что мы хотим найти сделку с максимальной стоимостью для каждого торгового агента. Можно сделать персональный запрос для каждого из них, выбрав MAX(amt) из таблицы сделок. Можно записать следующий запрос:

    SELECT snum, MAX (amt) FROM Orders GROUP BY snum;

    Результат выполнения запроса: SNUM --- 1001 767.19 1002 1713.23 1003 75.75 1014 1309.95 1007 1098.16

    В данном случае таблица группируется относительно номера торгового агента, поэтому поле SNUM присутствует в списке вывода запроса и в предложении GROUP BY.

    Использование HAVING

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

    SELECT snum, odate, MAX(amt) FROM Orders GROUP BY snum, odate HAVING MAX(amt)>3000.00;

    Результат выполнения запроса: SNUM ODATE --- 1001 10/05/1990 4723.00 1001 10/06/1990 9891.88 1002 10/03/1990 5160.45

    Внимание! В предложении HAVING нельзя проверять имена полей на какое-либо условие – для этого существует WHERE. То, что вы проверяете в HAVING должно иметь только одно значение для группы.

    7.3. Использование условий выборки и агрегатных функций SQL в клиентском приложении

    Для того, чтобы проиллюстрировать работу оператора SELECT, модифицируем структуру таблицы PHONE. Добавим дополнительное поле тип телефона (PHONETYPE) и модифицируем данные таблицы. Эту операцию можно выполнить посредством оболочки IB Expert (рисунок 1) или с помощью операторов SQL:

    ALTER TABLE PHONE ADD PHONETYPE VARCHAR(15) CHARACTER SET WIN1251 COLLATE WIN1251;

    UPDATE PHONE SET PHONETYPE = 'Домашний';

Рисунок 1 – Добавление нового поля в таблицу Phone посредством оболочки IB Expert

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

Рисунок 2 – Модифицированная таблица «Телефонный справочник»     Необходимо отметить, что полученное отношение не является нормализованным и, как следствие, имеют место аномалии добавления, удаления и обновления. Действительно, если необходимо добавить рабочий телефон Сергея Паршина нам придется дублировать содержимое полей Ф.И.О. и дата рождения. В базе данных не может содержаться информация о человеке, у которого нет телефона. При изменении паспортных данных нам человека необходимо будет поменять информацию в нескольких строках таблицы. Для исключения аномалий выполняется операция декомпозиции отношения, которая будет рассмотрена в следующей лабораторной работе.

    Модифицируем приложение-клиент, разработанное в ходе лабораторной работы №2. Прежде всего добавим поле редакции типа телефона CBType:TComboBox. Заполним поле Items возможными вариантами: «рабочий», «домашний», «мобильный» и модифицируем тексты процедур обработчиков событий BtAddClick, ВtUpdateClick, BtDeleteClick и DBGridCellClick для адекватной работы программной системы.

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

Рисунок 3 – Главная форма проекта с возможностью ввода/коррекции типа телефона     Для сортировки записей таблицы по содержимому полей добавим в проект обработчик события onTitleClick компонента DBGrid.

    procedure TForm1.DBGridTitleClick(Column: TColumn);

      var cn : string;

      begin

        cn:=Column.FieldName;

        DataModule2.IBQuery.Transaction.Commit;

        DataModule2.IBQuery.SQL.Clear;

        DataModule2.IBQuery.SQL.Add('SELECT * FROM PHONE ORDER BY '+cn);

        DataModule2.IBQuery.Active:=true;

      end;

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

    Поиск информации в таблице станет удобней, если в ней будут выведены не все записи, а только те, которые удовлетворяют условию поиска (например, первым буквам Ф.И.О.). Добавим в проект компонент ChBFiltr:TCheckBox и строку ввода условия отбора EdFilter: TEdit. Обработоем событие onClick компонента ChBFilter.

    procedure TForm1.ChBFiltrClick(Sender: TObject);

      var fn : string;

      begin //определение имени поля, по которому следует сортировать

        fn:=DBGrid.SelectedField.FieldName;

        DataModule2.IBQuery.Transaction.Commit; DataModule2.IBQuery.SQL.Clear;

        //Выбираем данные из таблицы

        DataModule2.IBQuery.SQL.Add('SELECT * FROM PHONE');

        if (chbFiltr.Checked) and (EdFilter.Text'') then //Если свойство checked установлено и есть образец для поиска

          DataModule2.IBQuery.SQL.Add('WHERE FIO LIKE "'+EdFilter.Text+'%" ');

          //задаем порядок сортировки значениий

          DataModule2.IBQuery.SQL.Add(' ORDER BY '+fn);

          DataModule2.IBQuery.Active:=true;

        end;

    Заметим, что этот же обработчик целесообразно использовать для обработки события onChange компонента EdFilter. Результат работы модифицированного приложения показан на рисунке 4.

Рисунок 4 – Работа приложения с фильтром записей     Разработаем интерфейс для исследования работы оператора SELECT. Поместим на новую форму компоненты DBGrid1: TDBGrid, BtDistinct: TButton, BtCount: TButton, BTHaving: TButton. Добавим на форму DataModule2 два компонента для работы с данными: SelectQuery: TIBQuery, DataSourceSel: TDataSource. Установим свойство DataSourceSel.DataSet в значение SelectQuery.

    Обработчик события BtDistinct реализует запрос «Вывести всех абонентов телефонной книги без повторения имен».

    procedure TSelectForm.BtDistinctClick(Sender: TObject);

    begin

      DataModule2.SelectQuery.Active:=false;

      DataModule2.SelectQuery.SQL.Clear;

      DataModule2.SelectQuery.SQL.Add('SELECT DISTINCT FIO FROM PHONE ORDER BY FIO');

      DataModule2.SelectQuery.Active:=true;

    end;

    Аналогичным образом создаем обработчики событий для реализации запросов типа «Вывести количество номеров каждого абонента (SELECT FIO, Count(*) FROM PHONE GROUP BY FIO ORDER BY FIO), вывести имена и количество телефонов абонентов, имеющих 2 и более номеров (SELECT FIO, Count(*) FROM PHONE GROUP BY FIO HAVING (Count(*)>=2) ORDER BY FIO). Результат работы приложения показан на рисунке 5.

Рисунок 5 – Результат запроса «вывести имена и количество телефонов абонентов, имеющих 2 и более номеров».

Соседние файлы в папке теория