- •Практическое занятие №6 построение запросов к субд
- •Команда select
- •Некоторые другие команды sql
- •Insert into таблица [(поля)] values (значения)
- •Insert into regions values (77,'Москва')
- •Компонент запроса Query
- •Особенности работы с запросами
- •Контрольные вопросы:
- •Отчет должен содержать:
- •Цель работы.
Команда select
Наиболее важной командой языка манипулирования данными является команда SELECT (выбрать). За кажущейся простотой ее синтаксиса скрывается огромное число возможностей. В простейшем случае с ее помощью можно просто отобразить все содержимое таблицы. В других случаях при помощи одной команды SELECT можно одновременно производить такие операции, как фильтрация, сортировка по одной лил нескольким таблицам сразу. В самой обобщенной форме синтаксис этой команды можно представить следующим образом:
SELECT выражения_для_выборки FROM таблицы [параметры выборки]
В качестве выражения для выборки обычно перечисляют поля таблиц. Если требуется вывести все поля, то используют символ "*":
SELECT BILL_ID, BILL_SUMM FROM BILL SELECT * FROM BILL
В первом случае будут выведены поля BILL_ID и BILL_SUMM из таблицы BILL, а во втором - все поля из этой же таблицы. В этом нетрудно убедиться, воспользовавшись утилитой SQL Explorer для написания запроса. Для этого запустите SQL Explorer, откройте нужную БД, например, DATA1 (или предварительно создайте новый алиас для более полной версии БД, созданной для примера DBApp), и в правой части окна щелкните по закладке Enter SQL, после чего введите нужный код и нажмите на кнопку Execute Query. Результат выполнения запроса незамедлительно будет выведен в таблицу внизу (рис. 21.1).
Рис.
21.1. Приложение SQL Explorer
СОВЕТ
Если у вас установлена версия Delphi, не имеющая этого инструмента, то для экспериментов с командой SELECT вы можете использовать приложение SQLELE, которое можно найти в каталоге Tools\SQLE_LE.
При выборе можно сразу же произвести упорядочивание записей, причем SQL позволяет делать эту операцию по любому полю таблицы, а не только по индексированному. Например, чтобы вывести все счета в порядке возрастания суммы, достаточно написать следующее выражение:
SELECT * FROM bill ORDER BY BILL_SUMM
Если бы требовалось выполнить сортировку не по возрастанию, а по убыванию, то в конце выражения следовало бы добавить ключевое слово DESC:
SELECT * FROM bill ORDER BY BILL_SUMM DESC
Выборка записей из таблицы производится при помощи условия, определяемого после ключевого слова WHERE. Например, если надо выбрать только те счета, которые были после 15 декабря, следует написать следующий SQL-запрос (формат написания даты в данном случае зависит от системных установок):
SELECT * FROM bill WHERE BILL_DATE>'15.12.2005'
Если при этом так же требуется еще и выполнить сортировку, то в конец выражения добавляют определение ORDER BY:
SELECT * FROM bill WHERE BILL_DATE>'15.12.2005' ORDER BY BILL_SUMM
В случае, когда условий больше одного, то их объединяют при помощи логических AND или OR:
SELECT * FROM bill WHERE BILL_DATE>'15.12.2005' AND BILL_SUMM>100 SELECT * FROM bill WHERE BILL_DATE>'15.12.2005' OR BILL_SUMM>300
Все эти примеры иллюстрируют общую форму команды SELECT в языке SQL (для одной таблицы): SELECT (выбрать) указанные поля FROM (из) указанной таблицы WHERE (где) заданные условия истинны.
Немного более сложным вариантом является выборка данных из 2 и более таблиц сразу. Например, для наглядности не помешало бы вывести в виде таблице список счетов, содержащий не внутренние номера клиентов, а их имена. В этом случае придется задействовать 2 таблицы - bill и customer, причем связующим полем будет номер клиента, т.е. поле BILL_CUST в таблице счетов и поле CUST_ID в таблице клиентов. В результате, мы получаем следующее выражение:
SELECT CUST_NAME, BILL_SUMM FROM bill, customer WHERE CUST_ID = BILL_CUST
Опять-таки, к данному условию, связывающему поля таблиц, можно добавить дополнительные, скажем, ограничивающие даты или суммы, равно как и определить упорядочивание вывода. Например, можно добавить условие, что сумма счета должна быть свыше 250, а так же задать упорядочивание по имени клиента (рис. 21.2).
Рис.
21.2. Результат выполнения SQL-запроса по
2 таблицам
Следует учитывать, что подобное связывание таблиц - путем указания условия в конструкции WHERE, является устаревшим и применяется лишь тогда, когда требуется добиться совместимости с SQL89. Более новый стандарт, SQL92, рекомендует использовать для связывания таблиц ключевое слово JOIN. Таким образом, предыдущий пример можно переписать следующим образом:
SELECT CUST_NAME, BILL_SUMM FROM customer JOIN bill ON CUST_ID = BILL_CUST
Важно отметить, что условия объединения помещают после ключевого слова ON, в то время, как остальные условия можно указать после WHERE. Таким образом, если бы нам надо бы добавить ограничения на сумму, то можно было бы написать 2 равнозначных варианта:
SELECT CUST_NAME, BILL_SUMM FROM customer JOIN bill ON CUST_ID = BILL_CUST AND BILL_SUMM>250; SELECT CUST_NAME, BILL_SUMM FROM customer JOIN bill ON CUST_ID = BILL_CUST WHERE BILL_SUMM>250;
Для удобства можно задавать локальные "имена" как для полей, так и для таблиц. Это бывает полезным в тех случаях, когда в большом и сложном запросе используется множество условий с длинными именами полей и таблиц:
SELECT EXTRA_USER_DATA_INFO AS a, EXTRA_USER_DATA_NAME as b FROM USER_TABLE WHERE a > 10 AND a < 100 AND b != 'Super' ORDER BY b
Следует отметить, что при выводе полей таблиц с помощью SQL можно производить некоторые вычисления. В этих случаях использование локальных имен бывает просто необходимым. Допустим, в счетах у нас хранятся суммы без НДС. В таком случае мы можем ввести сразу 2 столбца с суммами - с той, что хранится таблице и в виде вычисленного значения.
SELECT BILL_DATE, BILL_SUMM, BILL_SUMM * 1.18 as WITH_TAX FROM BILL ORDER BY WITH_TAX
В таком случае названием столбца с вычисленным значением будет "WITH_TAX" (см. рис. 21.3).
Рис.
21.3. SQL-запрос с вычислениями
При подобном переименовании столбцов следует быть внимательным, поскольку использование идентификаторов, совпадающих с ключевыми словами SQL, приведет к ошибке. Кроме того, следует избегать использования символов кириллицы, поскольку они не поддерживаются многими СУБД в данном контексте.
Если написание арифметического выражения приведет к изменению выводимых данных в записях столбца, то использование агрегирующих (агрегатных) функций поможет выполнить действия над всеми записями, удовлетворяющими указанным в запросе условиям. Пожалуй, чаще всего используется функция COUNT, позволяющая узнать количество записей. Например, чтобы узнать, сколько записей хранится в таблице счетов, достаточно написать следующий запрос:
SELECT COUNT(*) FROM bill
Результатом выполнения этого запроса будет число записей в таблице счетов. Если бы мы хотели узнать число записей, сделанных, скажем, до 1января, то могли бы написать такое выражение:
SELECT COUNT(*) FROM bill WHERE BILL_DATE < '01.01.2006'
Помимо COUNT, в стандартном SQL предусмотрено еще 4 агрегирующих функции - для вычисления суммы (SUM), максимального (SUM) и минимального (MIN) значений столбцов, а так же среднего арифметического (AVG). Результатом выполнения запроса по всем этим функциям для таблицы счетов будет таблица, состоящая из 4 столбцов, в каждом из которых будет находиться результат вычислений (рис. 21.4).
Рис.
21.4. Результат выполнения запроса с
агрегирующими функциями
Что касается заданий ограничений на обрабатываемые данные, ровно, как и на выводимые при помощи "обычного" запроса строки, то помимо реляционных операторов сравнения - больше (>), меньше (<), равно (=), не равно (!= или <>), больше или равно (>=), меньше или равно (<=), - можно использовать следующие операторы:
BETWEEN - задает диапазон значений, для которого выражение принимает истину;
IN - проверяет, входит ли заданное значение, предшествующее ключевому слову "IN" (например, значение столбца) в указанный в скобках список;
LIKE - проверяет, соответствует ли данное символьное значение строке с указанной маской (только для символьных данных);
В качестве примеров можно привести следующие варианты SQL-запросов:
SELECT BILL_SUMM FROM bill WHERE BILL_SUMM BETWEEN 100 and 200; /* Вывести счета с суммами от 100 до 200 */ SELECT BILL_SUMM, BILL_CUST FROM bill WHERE BILL_SUMM IN (100,150,200) /* Вывести счета с суммами, равными 100, 150 и 200 */ SELECT CUST_NAME FROM customer WHERE CUST_NAME LIKE 'OOO "Gamma%' /* Вывести клиентов, имя которых начнается с "ООО "Gamma" */ SELECT CUST_NAME FROM customer WHERE CUST_NAME LIKE 'OOO "_____"' /* Вывести клиентов, имя которых начнается с "ООО "" и имеет 5 символов в кавычках */ SELECT CUST_NAME FROM customer WHERE CUST_NAME LIKE '_%' /* Вывести клиентов, имя которых состоит хотя бы из 1 символа */
Что касается порядка вывода результатов, то помимо сортировки, еще одним способом повлиять на вывод результатов запроса является использование GROUP BY. Эта конструкция определяет порядок группировки полей при выводе. При этом следует учитывать, что должны быть указаны все поля, перечисленные в запросе:
SELECT BILL_SUMM, BILL_DATE FROM bill GROUP BY BILL_DATE, BILL_SUMM
В данном случае данные будут сгруппированы по датам. Впрочем, это не самый удачный пример, поскольку такого же результата можно было бы добиться простой сортировкой по полю BILL_DATE. Поэтому рассмотрим более сложный запрос, который будет выводить общие суммы всех счетов для каждого из клиентов. Для этого нам понадобится агрегирующая функция SUM:
SELECT BILL_CUST, SUM(BILL_SUMM) FROM BILL GROUP BY BILL_CUST
Наконец, усложним запрос, сделав результаты его работы более наглядными. Для этого нам потребуется связать таблицу счетов с таблицей клиентов, а заодно произвести сортировку по итоговому результату. Таким образом, мы получим следующий запрос:
SELECT CUST_NAME, SUM(BILL_SUMM) as TOTAL FROM BILL JOIN CUSTOMER ON CUST_ID=BILL_CUST GROUP BY BILL_CUST, CUST_NAME ORDER BY TOTAL DESC
Результатом его выполнения будет таблица, содержащая в первом столбце имена клиентов, а во втором - суммы всех их счетов, по которой и была произведена сортировка (рис. 21.5).
Рис.
21.5. Запрос с группировкой, агрегацией
и упорядочиванием по вычисляемому полю
Все, что было на данный момент рассказано про команду SELECT, на самом деле, является лишь верхушкой айсберга ее возможностей. В то же время, даже такое беглое знакомство дает понять, что без знания SQL написать достаточно объемное приложение для БД крайне затруднительно. В то же время, каждая СУБД, как уже было отмечено, имеет свои тонкости в реализации языка, и команда SELECT, по причине своих огромных возможностей, является одним из наиболее частых претендентов на "модернизацию". По этой причине для дальнейшего изучения как команды SELECT, так и прочих возможностей SQL, следует использовать документацию к используемой СУБД.
