Программирование >>  Разработка пользовательского интерфейса 

1 ... 70 71 72 [ 73 ] 74 75 76 ... 147


И наконец, оператор IS NULL позволяет обнаружить значения типа NULL в указанном поле и соответственно определить, выводить проверенную запись в итоговый курсор или нет. Оператор IS NULL нельзя непосредственно использовать в Visual FoxPro и Microsoft Access. Но в этих языках есть функция ISNULL(). Поэтому можно написать команду следующим образом:

SELECT DISTINCTROW firm.name firm, model.name model, country.country name

FROM model INNER JOIN (firm INNER JOIN country ON firm.key country = country.key country) ON

model.key firm = firm.key firm

WHERE NOT isnull(country.country name)

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

SELECT DISTINCTROW firm.name firm, model.name model, country.country name

FROM model INNER JOIN (firm INNER JOIN country ON firm.key country = country.key country) ON

model.key firm = firm.key firm

WHERE NOT isnull(country.country name)

ORDER BY firm.name firm

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

ORDER BY firm.name firm DESC

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

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

COUNT(*) - возвращает число выбранных записей;

COUNT(ALL Expression) - возвращает количество непустых значений;

COUNT(DISTINCT Expression) - возвращает количество неповторяющихся значений по указанному в Expression выражению;

MAK(Expression) - максимальное значение по указанному выражению;

MIN(Expression) - минимальное значение по указанному выражению;

SUM(ALL/DISTINCT Expression) - сумма по всем или только по неповторяющимся значениям;

AVG(ALL/DISTINCT Expression) - среднее по всем или только по неповторяющимся значениям.

В Microsoft Access и Visual FoxPro, в дополнение к вышеприведенным функциям, вы можете вычислить еще и стандартное отклонение, дисперсию и т. д.

В следующем запросе приводится пример вычисления сумм продаж по конкретным наименованиям автомобилей:

SELECT DISTINCTROW Sum(account.sum) AS Sum sum, model.name model FROM model INNER JOIN (account INNER JOIN [automobile passenger car] ON account.key auto = [automobile passenger car].key auto) ON model.key model = [automobile passenger car].key model GROUP BY model.name model

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

Сумма Наименование

20500 145 1.4

10500 146 1.9

25000 740i 4.0

60000 840Ci 4.0 37000 M3 3.0



Если внимательно посмотреть на текст запроса, то в конце выражения можно увидеть предложение GROUP BY. В стандартном SQL вам просто необходимо группировать запрос по всем выбираемым полям, либо использовать поля как выражения функций агрегирования. Совершенно аналогичные ограничения накладываются на запросы в Microsoft Access. В Visual FoxPro и Microsoft SQL Server таких ограничений нет, и вам не обязательно группировать данные по всем выводимым полям.

При создании запросов перед вами обязательно возникнет необходимость отфильтровать данные по какому-нибудь наименованию. Например, по модели M3 3.0. В принципе, вы можете использовать следующую строку, сформированную с помощью предложения WHERE:

WHERE model.name model = M3 3.0

Но это будет не совсем правильно с точки зрения стандарта SQL. Правильно построенный запрос будет выглядеть следующим образом:

SELECT DISTINCTROW Sum(account.sum) AS Сумм, model.name model

FROM model INNER JOIN (account INNER JOIN [automobile passenger car] ON account.key auto = [automobile passenger car].key auto) ON model.key model = [automobile passenger car].key model GROUP BY model.name model HAVING model.name model = M3 3.0

Результат этого запроса будет выглядеть следующим образом:

Сумма Наименование

37000 M3 3.0

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

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

Подзапросы присоединяются к основному запросу через операторы IN, EXIST, SOME, ANY, ALL.

Рассмотрим пример использования оператора IN. Допустим, у нас есть две таблицы с одинаковой структурой. Необходимо вывести данные из первой таблицы при условии, что по полю kto у выводимых записей нет совпадающих значений.

SELECT kto, skolko FROM first WHERE kto NOT IN ; (SELECT DISTINCT kto FROM second)

Пример использования оператора EXIST. Оператор EXIST - единственный из операторов, не требующий выражения между ключевым словом WHERE и самим собой. Он возвращает истину в зависимости от того, есть ли хоть одна запись в выборке подзапроса. Рассмотрим два решения одной задачи. Нам необходимо выбрать все модели автомобилей, которые стоят больше 25000 и которые мы ухитрились продать хотя бы один раз. Код записан в синтаксисе FoxPro.

SELECT DISTINCT Model.name model,; Automobile passenger car.cost; FROM auto store!model ,;

auto store!automobile passenger car ; Automobile passenger car ; WHERE Model.key model = ; Automobile passenger car.key model AND ; Automobile passenger car.cost >>=25000 AND Exist ; (SELECT * FROM account,;

auto store!automobile passenger car Automobile passenger car ; WHERE account.key auto = ; Automobile passenger car.key auto) SELECT DISTINCT Model.name model, ; Automobile passenger car.cost ;

FROM auto store!model ,;

auto store!automobile passenger car ; Automobile passenger car; WHERE Model.key model = Automobile passenger car.key model AND ; Automobile passenger car.cost >>=25000 ; And Automobile passenger car.key auto NOT IN;

(SELECT DISTINCT account.key auto FROM account)



Возможно, вы найдете еще более короткое решение данной задачи, не корите нас, так как мы думаем еще и об учебных целях приводимых примеров. В первом решении с помощью оператора EXIST мы просто проверяем таблицу Account на наличие записей во внутреннем подзапросе. Во втором решении нас интересует просто список значений, которые у нас имеются, после выполнения внутреннего запроса по полю key auto.

Второе решение дает правильный ответ, а первое неправильный. Почему? Обратимся к теории. Внутренний запрос выполняется только один раз, и внешний запрос при своей работе обращается только к его итогу, раз за разом проходя по всем записям. Естественно, что оператор EXIST здесь оказывается совершенно бесполезным. Есть ли выход из положения? Безусловно. Согласно теории, если мы свяжем внешний и внутренний запрос, получив при этом связанный подзапрос, то вынудим внешний запрос обращаться к внутреннему каждый раз во время обработки записей при решении, выводить ли выбранные поля в итоговый курсор. Поэтому мы выводим во внешнем запросе еще одно поле Automobile passenger car.key auto и связываем внешний и внутренний запрос по этому полю. Теперь правильный запрос с использованием оператора EXIST выглядит так:

SELECT Model.name model, ; Automobile passenger car.cost, ; Automobile passenger car.key auto;

FROM auto store!model ,; auto store!automobile passenger car Automobile passenger car; WHERE Model.key model = Automobile passenger car.key model AND ;

Automobile passenger car.cost >>=25000 And Exist ;

(SELECT * FROM account WHERE ;

Automobile passenger car. key auto=account.key auto)

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

Пример использования операторов ANY и SOME. Использование операторов ANY и SOME приводит к совершенно одинаковым результатам. В качестве примера решим предыдущую задачу:

SELECT Model.name model, Automobile passenger car.cost;

FROM auto store!model ,;

auto store!automobile passenger car Automobile passenger car; WHERE Model.key model = Automobile passenger car.key model AND ; Automobile passenger car.cost >>=25000 And Automobile passenger car.key auto= ; ANY (SELECT DISTINCT account.key auto FROM account);

Пример использования операторов ALL. Оператор ALL используется с операторами сравнения >> и << и подзапросом. Оператор ALL с оператором >> перед ним означает, что сравниваемое значение должно быть больше любого значения в списке значений, полученных в подзапросе. В противоположном случае - соответственно меньше любого значения в списке.

SELECT Model.name model, Automobile passenger car.cost;

FROM auto store!model ,;

auto store!automobile passenger car Automobile passenger car ; WHERE Model.key model = Automobile passenger car.key model and ; Automobile passenger car.cost >>=ALL ; (SELECT DISTINCT summa FROM account ;

WHERE summa>>=30000) Запросы добавления

Не стоит особо пропагандировать необходимость добавления записей в таблицы в системах обработки данных. Они ведь и становятся настоящими таблицами, когда в них появляются записи. За этот процесс в языке SQL отвечает команда INSERT. Она имеет два варианта использования. В первом случае вы добавляете одну запись с конкретными данными в конкретные поля. Во втором случае вы можете добавить одну и более записей, набор которых формируется запросом. Необходимо отметить, что второй вариант синтаксиса не реализован в версии Visual FoxPro 3.0. Тем не менее его легко реализовать в два шага. Рассмотрим конкретные примеры.

В таблицу Account добавим одну запись:



1 ... 70 71 72 [ 73 ] 74 75 76 ... 147

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика