Лабораторная работа № 5. Написание запросов на языке SQL (ч. 2)

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

Результат, возвращаемый запросом, может содержать вычисляемые поля или константы. Название такого поля можно указать в списке выводимых столбцов после соответствующего значения через ключевое слово AS (стандарт SQL допускает указание и через пробел, без AS, но Access в подобных случаях выдает ошибку). Если название такому столбцу явно не задать, Access автоматически сгенерирует название, но для пользователя такой вариант менее удобен. Аналогичным образом альтернативное имя (псевдоним) можно задать и обычному столбцу.

Например, следующий запрос выводит без повторений список авторов, переименовав столбец в "Авторы", и сегодняшнюю дату в столбце TODAY (функция Date() возвращает текущую дату):

SELECT DISTINCT Author AS [Авторы],

Date () AS TODAY

FROM Book;

Обратите внимание, что псевдоним, как и название столбца или таблицы, в Access надо писать в одно слово или же заключить в квадратные скобки (название без пробелов тоже можно брать в квадратные скобки).

Задание. Напишите запрос, выводящий два столбца: первый должен называться "Подпись" и содержать во всех строках слово "Книга", второй столбец называется "Название книги" и содержит названия книг, взятых без повторения из таблицы Book.

Задание. Измените предыдущий запрос таким образом, чтобы он выводил единственный столбец, в котором была бы подпись "Книга", а за ней в двойных кавычках шло название книги, например: "Книга “Экспертные системы”". Для сцепления строк используйте операцию "+".

Обратите внимание, что при попытке выполнить приведенный ниже запрос Access выдаст сообщение о несовместимости типов. Связано это

с тем, что поле BookYear имеет числовой тип, а сложение числа со строкой невозможно:

SELECT DISTINCT 'Книга ' + BookYear

FROM Book;

В подобных случаях, используется явная конвертация типов, для чего Access предоставляет ряд функций: для конвертации в логический тип – СВоо1( ), в строковый – CStr(-), в тип "Целое" – Clnt(-) и т.д.

Задание. Измените представленный выше запрос так, чтобы он корректно сцеплял подпись и год издания.

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

SELECT DISTINCT В.*

FROM Book as В, BooklnLib as BL

WHERE В.BookID=BL.BookID;

Задание. По аналогии с рассмотренным примером напишите свой запрос, использующий псевдонимы таблиц. Проверьте его работу.

Другой характерный пример использования псевдонимов таблиц – так называемое "самосоединение" (self-join). Ниже приведен пример, выводящий все сочетания разных статусов книг. Чтобы отличать один экземпляр таблицы BookStatus от другого, потребовалось ввести псевдонимы:

SELECT Т.StatusName, T1. StatusName

FROM BookStatus AS T, BookStatus AS T1

WHERE T.StatusIDOTl .StatusID;

Задание. По анаюгии с рассмотренным примером напишите свой запрос, выводящий без повторения все сочетания разных издательств.

Следующая тема – использование агрегатных функций и группировки. Агрегатные функции обрабатывают набор записей и возвращают одно значение. К ним относятся функция подсчета количества записей или элементов – COUNT(), а также функции нахождения среднего, минимума, максимума, суммы (AVG, MIN, MAX, SUM соответственно). В большинстве случаев в качестве аргумента агрегатной функции выступает название столбца или выражение. У функции Count() есть также вариант Count(*), подсчитывающий количество записей.

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

SELECT Min(BookYear) as (Год первой книги]

FROM Book;

Задание. Напишите запрос, подсчитывающий количество статусов книг в таблице BookStatus.

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

SELECT Book.Publisher,

Count(Book.BookID) AS [К-во книг]

FROM Book

GROUP BY Book.Publisher;

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

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

Если необходимо выполнить группировку по нескольким столбцам, то в секции GROUP BY они перечисляются через запятую.

Задание. Для книг, экземпляры которых присутствуют в библиотекелюбым статусом), выведите идентификатор издания, название, автора и число экземпляров книги.

На группу можно наложить условие, которое записывается в секции HAVING. Если секции GROUP BY в запросе не было, вся таблица рассматривается как единая группа. Например, снова выведем издательство и количество изданных им книг, но только для издательств, где было выпущено две или более книг:

SELECT Book.Publisher,

Count(Book.BookID) AS [К-во книг]

FROM Book

GROUP BY Book.Publisher

HAVING COUNT(Book.BookID)>=2;

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

При написании запросов, в которых есть секции WHERE и HAVING, нужно учитывать что:

  • • условие отбора, применяемое к отдельной записи, прописывается в секции WHERE, применяемое к группе – в HAVING;
  • • в соответствии с порядком выполнения оператора SELECT секция WHERE выполняется до группировки и секции HAVING.

Рассмотрим пример, где выведем издательство и количество изданных им книг, для издательств, где было выпущено две или более книг, не считая книг, в названии которых присутствует сочетание "баз":

SELECT Book.Publisher,

Count(Book.BookID) AS [К-во книг]

FROM Book

WHERE Title NOT LIKE ' *баз*'

GROUP BY Book.Publisher

HAVING COUNT(Book.BookID)>=2;

Задание. Модифицируйте запрос из предыдущего задания, учитывая при подсчете только книги, изданные после 1998 г.

 
< Пред   СОДЕРЖАНИЕ     След >