Выборка данных из таблиц

Основой оператор для выборки данных в SQL - SELECT.

В Visual FoxPro 9 существует два варианта использования команды SELECT.В одном случае параметров команды большее количество, но в полном объемеони работают только при выборке данных из базы данных Visual FoxPro. Вовтором случае применяется минимальный набор параметров, но все они будутработать практически со всеми системами управления базами данных. Надопомнить, что при обращении приложения к базе данных и приложение должно поддерживать формат запроса, чтобы его сформировать и суметь обработать результат, и СУБД, к которой приложение обращается, должна иметь возможность понять запрос и обработать его.

>    DISTINCT - показывает, что в результирующую выборку из несколькиходинаковых записей включается только одна;

>    FROM <Список_таблиц> - позволяет задать таблицу или список таблиц, ккоторым осуществляется запрос;

>    WHERE <Условие1> -- позволяет задать условия для выбора записей. В результирующую выборку будут включены только записи, удовлетворяющие условию. Условие может быть сложным и состоящим из несколькихусловий, разделенных логическими операторами AND или OR;

>    GROUP BY <Список_полей2> -указывается список полей для группировкипо ним. Имеет смысл использовать, если в <Список_полей1> включитьфункции SUM (суммирование), COUNT (количество записей) и т.п.;

>    HAVING <Условие> - условие, которому должны удовлетворять записи.Имеет смысл при использовании GROUP BY, иначе действие аналогичноWHERE;

>    UNION <ЗЕЬЕСТ-выборка>- позволяет объединить результаты несколькихвыборок в одну результирующую таблицу;

>    ORDER BY - упорядочивает результат выборки по указанным полям по возрастанию (ASC) или убыванию (DESC);

>    INTO <Имя_таблицы> - позволяет указать таблицу, в которую следует поместить результирующую выборку.

Простейший пример выборки всех полей всех записей таблицы Persons:

Если ввести эту команду в окне Command, в результате ее выполнения появится окно с результирующей выборкой в окне с заголовком Query. Это временная таблица, и на диск она не записывается. Когда вы закроете таблицуQuery, она просто исчезнет.

При выборке не всех, а только нужных полей требуется указать их череззапятую. Например, требуется выбрать все записи и отобразить поля с фамилиями (Name) и адресами (Address). Для этого можно использовать следующую команду:

Если требуется выбрать не все записи, а по определенному условию, надоприменить параметр WHERE:

SELECT Name, Address FROM Persons WHERE Tabnum > 7000b

В результате применения этой команды в выборку попадут записи, в которых в поле Tabnum стоят значения больше 70005.

В условиях можно применять операторы сравнения: = (равно), < > (не равно), > (больше), < (меньше), >= (больше или равно), <= (меньше или равно).

При указании условия можно использовать логические выражения и получать, таким образом, сложные условия, состоящие из нескольких простых.Какими ключевыми словами обозначаются логические операторы?

>    NOT - логическое «не»;

>    AND - логическое «и»;

>    OR - логическое «или».

Как пользоваться логическими выражениями? Логическое «не» означаетотрицание, то есть если условие, стоящее после NOT, истинно, то в результателогической операции «не» оно станет ложным.

И наоборот:

Логическое «и» говорит о том, что, для того чтобы условие стало истинным,все условия, между которыми стоит оператор AND, должны быть истинными.

Логическое «или» говорит о том, что, для того чтобы условие стало истинным, хотя бы одно из условий, между которыми стоит оператор OR, должнобыть истинным.

Допустим, что требуется выбрать записи со значениями табельного номераот 70003 до 70005 включительно:

В результате применения этой команды в выборку попадут записи, в которых в поле Tabnum стоят значения больше или равные 70003 и меньше илиравные 70005.

Оператор AND имеет приоритет перед OR. Он более «сильный». Например, ввыражении

сначала будет выполнен логический оператор AND, а затем результат будет участвовать в операторе OR. Таким образом, будут выбраны записи с табельнымномерами 70002, 70004, 70005, 70006 и 70007. Если бы OR выполнился раньше,чем AND, в выборку попали бы записи с табельными номерами 70004, 70005,70006 и 70007.

Допускается применение в условиях скобок. При помощи скобок при необходимости можно менять приоритеты выполнения логических операций.

Например:

Эта команда вернет выборку из записей со значениями поля Tabnum с 70003по 70007 и со значениями в поле Id равными 701007? (рис. 2.25).

Если в условие приведенной выше команды добавить скобки

то условие Id = ?01007? будет проверяться только совместно с условиемTabnum >= 70003, а если учесть, что у единственной записи с Id = 7 01007? вполе Tabnum стоит значение 70001, эта запись в результирующую выборкуне попадет (рис. 2-26).

В парамет ре WHERE можно использовать результаты выборок из других таблиц.Например, мы хотим получить список сотрудников, получающих больше 15000:

Если при этом есть желание, чтобы фамилии располагались в алфавитномпорядке, надо использовать команду в таком виде (рис. 2.27):

Довольно часто даже опытные программисты упускают из вид)' возможнос тьзамены оператором IN группы предикатов, объединенных логическими операторами OR. Например:

Такой запрос можно выполнить и по-другому:

В списке полей допускается использование агрегатных функций. Например,для подсчета записей используют функцию COUNT (*), для суммирования значений - функцию зим(<имя_поля>). Правда, использование этих функций оправдано прежде всего при использовании группировки результирующей выборкипо каким-либо значениям (GROUP BY). Записи объединяются в группы так, чтовсе записи, входящие в одну группу, имеют одинаковые значения поля, по которому происходит группировка. По каждой группе в результирующей таблице будет только одна запись. Для чего это может потребоваться? Например,если нужно подсчитать в списке сотрудников количество сотрудников, занимающих одинаковые должности.

Результат такой операции представлен на рис. 2.28.

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

Наличие параметра HAVING имеет смысл только при использовании его совместно с GROUP BY. В чем же отличие WHERE от GROUP BY? Проверка WHERE выполняется раньше; затем записи, прошедшие проверку, группируются GROUP BY,а затем они подлежат проверке по HAVING. Например:

В отличие от предыдущего запроса, результатом этого запроса будут толькозаписи по группам, в которые входит больше одной записи исходной таблицы.

Мы уже упоминали агрегатные функции, которые можно использовать взапросах. Перечислим их:

>    COUNT () - возвращает количество записей в группе. Обычно используют

COUNT(*);

>    SUM (<поле>) - возвращает числовую сумму значений указанного поля длягруппы записей;

>    AVG(<поле>) - возвращает среднее значение чисел указанного поля длягруппы записей;

>    МАХ(<поле>) - возвращает максимальное значение указанного поля длягруппы записей;

>    MIN(<поле>) - возвращает минимальное значение указанною поля длягруппы записей.

Подсчитаем общую сумму окладов сотрудников из нашей таблицы:

Результат представлен на рис. 2.29. В этом примере использованы данныеиз двух таблиц и, соответственно, имена таблиц перечислены через запятуюпосле ключевого слова FROM.

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

Полям в результирующей таблице можно присваивать произвольные имена. Для этого в списке полей после имени исходного поля надо поставить AS

<новое_имя>. В случае, если для предыдущего запроса нам хочется назвать полев результирующей таблице Empty, запрос будет выглядеть так:

В приведенном выше запросе хорошо видно использование префиксов. Вы,наверное, уже заметили в примерах, что перед названием поля часто ставитсяимя таблицы и между именем таблицы и именем поля ставится точка. Имя таблицы и есть префикс. Основной смысл использования префиксов в том, чтобычетко определить, какие поля какой таблице принадлежат. В приведенном вышепримере в подзапросе в условии WHERE использованы префиксы, иначе было быне понятно, поле какой таблицы сравнивать с полем какой, поскольку оба поляносят имя Id.

Иногда имена полей слишком длинные, и неудобно их использовать в качестве префиксов. Получается очень длинная строка запроса. В таких случаяхиспользуют конструкцию AS <короткое_имя>. Например,

Результат такого запроса приведен на рис. 2.30.

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

До этого момента мы рассматривали команду SELECT без указания, в какуютаблицу поместить результирующую выборку. А в Visual FoxPro предусмотренатакая возможность. Можно в качестве хранилища результатов запроса использовать массив, таблицу или курсор (временная таблица, которая по окончаниисеанса работы в Visual FoxPro пропадает). Например, требуется поместитьрезультирующую выборку в таблицу MyReslt. Следует поступить следующимобразом:

В результате выполнения указанной команды выборка поместится в таблицу MyReslt. При этом, если таблица не была создана заранее, она создастся, аесли уже существует такая таблица, она будет перезаписана.

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

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

Довольно удобно для оценки результатов выборки использовать системнуюпеременную Visual FoxPro 9 с именем _TALLY. Если запрос успешно отработан, вэту переменную попадает количество записей в результирующей выборке. Довольно часто после выполнения запроса делают проверку переменной _TALLYчтобы узнать, вернул ли запрос хоть одну запись или, наоборот, записей, удовлетворяющих условию, нет, и по этой причине не имеет смысла как-либо обрабатывать результирующую выборку.