BD / bd_lab_kn(2008)
.pdfЛАБОРАТОРНАЯ РАБОТА 4 СОЗДАНИЕ ЗАПРОСОВ НА ЯЗЫКЕ SQL
Цель работы: использование языка SQL для создания запросов на выборку.
Для любой БД большинство запросов можно создать, используя графические возможности QBE (запроса по образцу). При запуске QBE –
запроса Access сначала преобразует его в инструкцию языка SQL.
SQL (Structured Query Language – Структурированный язык запросов) является стандартом языка реляционных баз данных. Он позволяет выразить запрос средствами операций реляционной алгебры (специальные операции,
применяемые к отношениям).
В SQL для запроса на выборку используется инструкция SELECT,
обобщенный синтаксис которой имеет вид:
SELECT <список - выбора>
FROM <список - ПМИтаблиц>
[ WHERE <условие – отбора - записей>]
Методические указания к выполнениюДонНТУработы
[ GROUP BY <список – полей – для - группировки>] [ HAVING <условие – отбора - групп>]
[ ORDER BY <условия - сортировки>];
Здесь FROM, WHERE, GROUP BY, HAVING, ORDER BY –
предложения SQL.
определяет список таблиц на основе которых строится запрос
КафедраFROM ,
(обязательное предложение).
WHERE указывает условие, которому должны удовлетворять записи результирующего набора.
GROUP BY определяет, как должны быть сформированы группы для итогового запроса (то есть указывает список полей, по одинаковым значениям
которых будет выполняться группировка записей).
HAVING используется для указания условия отбора тех групп, которые должны быть включены в результат запроса.
ORDER BY указывает условия упорядоченности строк в результирующем наборе.
<список - выбора> определяет, какие поля (столбцы) должен иметь результирующий набор записей (наличие <списка> в SQL – запросе обязательно)
В Access синтаксис SELECT расширен по сравнению со стандартом языка.
При описании синтаксиса SQL приняты следующие соглашения:
60
- прописные буквы используются для ключевых слов языка (в программе их можно писать как прописными, так и строчными буквами);
- русские слова показывают элементы, имена которых должны быть указаны программистом;
указать; текст внутри скобок характеризует элемент, но не описывает синтаксис этого элемента;
- в угловые скобки заключаются элементы синтаксиса, который нужно ДонНТУ
- квадратные скобки определяют необязательные элементы; - вертикальная черта разделяет предоставляемые на выбор элементы;
- фигурные скобки заключают несколько предоставленных на выбор
элементов, разделенных вертикальной чертой;
- многоточие показывает, что некоторый элемент можно повторить
несколько раз.
Внешние объединения
Для создании внешних объединений (симметричное, левое, правое) инструкция SELECT имеет следующий синтаксис:
SELECT [ALL | DISTINCT | DISTINCTROW ]
[TOP |
количество [PERCENT]] список- выбора |
||
FROM {{имя-таблицы [[AS] псевдоним ] | имя-запроса [[AS |
|||
|
псевдоним]} <таблица-объединения>}, … |
||
[WHERE условие – отбора ] |
|||
[ORDER BY {имя–столбца | номер–столбца [ASC | DESC]}, …]; |
|||
Здесь |
|
|
|
псевдоним - |
для каждой таблицы и каждого запроса, участвующих в |
||
|
|
FROM, можно определить альтернативное имя (псевдоним), |
|
|
|
|
ПМИ |
|
|
которое можно использовать вместо имени таблицы (запроса) |
|
|
|
при задании имен полей. Такая необходимость возникает в |
|
|
|
случае, когда имя таблицы длинное; с помощью псевдонима |
|
|
|
его можно сделать короче. Следует помнить, что |
|
|
|
альтернативное имя действует только в рамках SELECT. |
|
список-выбора - |
{*|{имя-поля | выражение [AS имя-столбца-результата] | |
||
* |
|
имя-таблицы.* | имя-запроса.* | псевдоним.* },…} |
|
– означает, что результирующий набор включает в себя все |
|||
|
|
поля всех таблиц, на основе которых строится запрос. |
|
имя-таблицы.* – набор включает все поля данной таблицы . |
|||
имя-поля |
– имя поля таблицы (запроса), указанной в FROM; так как имена |
||
|
полей разных таблиц могут совпадать, то рекомендуется |
||
|
использовать полное имя: |
||
Кафедра |
[имя-таблицы].[имя-поля] |
||
|
|||
выражение |
- |
используется для создания вычисляемого поля (смотри в |
лабораторной работе 4 пункт "Вычисляемые поля"); имя этого
61
поля |
указывается в AS имя (используется это имя только в |
||
момент вывода результатов запроса). |
|
||
<таблица-объединения> - виртуальная таблица, получающаяся в результате |
|||
выполнения операции объединения двух таблиц. |
|
||
Синтаксис <таблицы-объединения>: |
|
||
({имя-таблицы [[AS]псевдоним] | имя-запроса [[AS]псевдоним] | |
|
||
<таблица-объединения> } { INNER | LEFT | RIGHT } JOIN |
|
||
{ имя-таблицы [[AS] псевдоним ] | имя-запроса [[AS]псевдоним] | |
|
||
<таблица-объединения>} ON <условие-объединения>) |
|
||
Операция JOIN используется для задания типа объединения таблиц (смотри |
|||
лабораторную работу 4, пункт “Внешние объединения”): |
|
||
INNER JOIN – |
симметричное объединение (параметр = 1); |
|
|
LEFT JOIN – |
левое объединение (параметр = 2); |
|
|
RIGHT JOIN – |
правое объединение (параметр = 3). |
|
|
<условие-объединения> - это условие, по которому объединяются две |
|||
|
|
ПМИ |
|
таблицы. В основном это условие равенства значений полей связи обеих таблиц |
|||
(объединение по равенству). Но в SQL при объединенииДонНТУмогут использоваться |
|||
и условия неравенства : <, |
>, <=, >=, <>. |
|
|
Предикаты ALL, DISTINCT, DISTINCTROW, TOP количество, |
TOP |
||
количество PERCENT |
служат для ограничения количества |
записей, |
включаемых в выходной набор.
В результате выполнения предложения FROM образуется динамический |
|
набор записей, содержащих все поля таблиц, участвующих в FROM. Среди |
|
Кафедра |
|
этих записей могут быть повторяющиеся (дубликаты). |
Предикат |
DISTINCTROW указывает, что из динамического набора нужно исключить дубликаты. Действие этого предиката соответствует установке свойству
Уникальные записи QBE-запроса значения Да.
Если в FROM используется только одна таблица, то данный предикат не имеет смысла.
Предикат ALL показывает, что в динамический набор включаются все строки, в том числе и дубликаты (действует по умолчанию).
На последних шагах выполнения запроса из множества полей записей динамического набора выбираются только поля, указанные в списке - выбора. Полученный после этого набор может содержать повторяющиеся строки. Предикат DISTINCT требует при выводе результирующего набора данных оставлять только уникальные строки (то есть строки-дубликаты игнорируются). Действие этого предиката соответствует установке свойству Уникальные
значения QBE-запроса значения Да. |
|
|
Предикат TOP количество |
позволяет из набора записей, |
ограниченных |
условием WHERE, отобрать для |
вывода только определенное |
количество |
первых записей. Для указания относительного количества выводимых записей
62
предикат TOP нужно взять в виде TOP количество PERCENT, где количество определяет процент от общего числа записей (это значение должно быть целым числом, не превышающим 100).
Предложение |
ДонНТУ |
|
|
|
WHERE условие-отбора |
указывает условие отбора, которое применяется к каждой записи динамического набора, полученного в результате выполнения FROM. Условие может быть представлено корректным логическим выражением любой сложности (правила составления условий отбора приведены в лабораторной работе 4 в пункте “Условия отбора”). В результирующий набор включаются только те записи, для которых условие - отбора приняло значение Истина (Да).
Так как не рекомендуется указывать в запросе конкретное условие отбора, то нужно включить в запрос параметр (параметры). Синтаксис параметра такой же, как и в QBE-запросах. Для указания типа параметра используется описание PARAMETERS, которое располагается перед инструкцией SQL (SELECT, TRANSFORM и другими). Описание имеет
следующий синтаксис: |
|
PARAMETERS [имя-параметра] |
тип-SQL, ... ; |
Здесь квадратные скобки являются элементом синтаксиса; тип-SQL – это тип |
|
данных SQL, соответствующий типу данных Access. Например, |
|
Тип данных Access: |
Тип данных SQL: |
Байт |
Byte |
Денежный |
Currency |
Кафедра |
DateTime |
Дата/Время |
|
Длинное целое ПМИLong |
|
Целое |
Short |
Текстовый |
Text |
С плавающей точкой(4б) |
IEEESingle |
Предложение ORDER BY задает порядок строк в результирующем наборе:
ORDER BY {имя-столбца | номер-столбца [ ASC | DESC ] }, ...
номер-столбца – можно указать порядковый номер столбца выходного набора, по которому осуществляется сортировка строк;
ASC – сортировка по возрастанию (назначается по умолчанию); DESC – сортировка по убыванию.
Возможна многоуровневая сортировка.
Пример 1. Вывести сведения о поставщиках и их товарах, поставленных в указанный период.
63
PARAMETERS [Начало периода] DateTime, |
|
[Конец периода] DateTime; |
|
SELECT Поставщик, Город, Товар, Дата_поставки, |
|
Цена_единицы, Количество_единиц, |
|
Цена_единицы*Количество_единиц |
|
AS [Стоимость партии] |
ДонНТУ |
|
|
FROM ( Города INNER JOIN Поставщики |
|
ON Города.Код_города = Поставщики.Код города ) |
|
INNER JOIN ( Каталог INNER JOIN Товары |
|
ON Каталог.Код_товара = Товары.Код товара) |
|
ON Поставщики.Код_поставщика = |
Товары.Код_поставщика |
|
|
|
||||
WHERE Дата_поставки |
Between[Начало периода] And |
|
|||||
|
[Конец периода] |
|
|
|
|||
ORDER BY |
Поставщик, Товар, Дата_поставки; |
|
|||||
Пример 2. Определить, какие виды товаров поставил каждый поставщик. |
|||||||
|
|
|
|
ПМИ |
|
|
|
SELECT DISTINCT Поставщики.Поставщик, Каталог.Товар |
|||||||
FROM Поставщики INNER JOIN (Каталог |
|
|
|||||
|
INNER JOIN Товары ON Каталог.Код_товара = |
|
|||||
|
Товары.Код_товара ) ON Поставщики.Код_поставщика = |
||||||
|
Товары.Код_поставщика |
|
|
|
|||
ORDER BY Поставщики.Поставщик,Каталог.Товар; |
|
||||||
Пример 3. Определить 5 партий товаров с наибольшей стоимостью. |
|||||||
Кафедра |
Поставщик, Код_города, |
Товар, |
|||||
SELECT |
|
TOP |
5 |
||||
Дата поставки, |
|
|
|
|
|
||
|
Цена единицы*Количество_единиц |
AS |
[Общая |
||||
|
стоимость] |
|
|
|
|
|
|
FROM |
Поставщики |
INNER JOIN |
(Каталог INNER JOIN Товары |
||||
|
ON |
Каталог.Код_товара = Товары.Код_товара) |
|
||||
|
ON |
|
|
Поставщики.Код_поставщика |
= |
||
|
Товары.Код поставшика |
|
|
|
|||
ORDER |
BY |
Цена единицы*Количество_единиц |
DESC ; |
|
|||
|
|
|
|
Итоговые запросы |
|
|
|
Для создания итоговых запросов в рассмотренную выше инструкцию |
|||||||
SELECT нужно включить предложения GROUP BY и HAVING: |
|
||||||
|
|
|
|
GROUP BY |
имя - поля, ... |
|
|
|
|
|
|
HAVING условие – отбора |
|
64
имя - поля - имя поля любой таблицы, указанной в FROM; по одинаковым значениям этого поля формируются группы записей.
условие - отбора – условие, применяемое к группам строк (условие, заданное в WHERE, применяется к отдельным записям перед объединением
их в группы). |
ДонНТУ |
|
Список - |
выбора инструкции |
SELECT должен содержать в итоговом |
запросе имена |
полей, указанных в GROUP BY, и хотя бы одну итоговую |
|
функцию (Count, Sum,...). |
|
Пример 4. Определить поставщиков, которые поставили товаров на сумму, превышающую заданную. Вывести: наименование поставщика, общую сумму за товары, количество партий товаров, среднюю цену партии.
PARAMETERS [Укажите сумму] IEEESingle;
SELECT Поставщик, |
|
|
|
|
|
Sum(Цена_единицы*Количество_единиц) |
AS |
||||
[Стоимость], |
|
|
|
|
|
Count(Товары.Код_поставщика) |
AS |
[Количество |
|||
партий], |
ПМИ |
|
|
||
|
|
|
|
||
Format(Avg(Цена единицы*Количество единиц), |
|||||
"Standard") AS [Средняя цена партии] |
|
||||
FROM Поставщики INNER |
JOIN Товары |
|
|
||
ON |
|
Поставщики.Код_поставщика |
= |
||
Товары.Код_поставщика |
|
|
|||
GROUP BY Поставщик |
|
|
|
|
|
HAVING |
Sum(Цена единицы*Количество_единиц)>[Укажите |
||||
сумму] |
|
|
|
|
|
ORDER BY Sum(Цена единицы*Количество_единиц) |
DESC; |
||||
Кафедра |
|
|
|
|
|
Пример |
5. Определить, |
сколько различных |
видов |
товара поставил |
каждый поставщик.
Для реализации этого запроса нужно создать запрос на запросе. Сначала создадим запрос, приведенный в примере 2 (имя запроса-SQL_Distinct), а затем на этом запросе построим итоговый запрос:
SELECT SQL Distinct.Поставщик,
Count (SQL Distinct.Товар) AS [Видов товаров]
FROM SQL Distinct
GROUP BY SQL Distinct.Поставщик
ORDER BY SQL Distinct.Поставщик;
Перекрестный запрос
Перекрестный запрос является разновидностью итоговых запросов. Он представляет итоговые данные в компактной форме – в виде перекрестной
65
таблицы, похожей на электронную таблицу. При создании перекрестного запроса нужно указать поле (несколько полей) для заголовков строк, поле - для заголовков столбцов и значение, которое выводится в ячейках перекрестной таблицы.
В SQL перекрестный запрос определяется инструкцией TRANSFORM: |
||
TRANSFORM выражение1 |
ДонНТУ |
|
|
||
< инструкция SELECT> |
|
|
PIVOT |
выражение2 [IN (список – заголовков - |
|
столбцов)]; |
|
|
Заголовки строк указываются в списке - выбора инструкции SELECT.
Заголовки столбцов определяются выражением2.
Значения, которые должны появиться в перекрестной таблице, задаются выражением1; это выражение должно содержать одну из итоговых функций.
В предложении GROUP BY, входящем в инструкцию SELECT, указываются поля для группировки записей. В списке этого предложения должны быть перечислены только поля – заголовки строк.
Условия на записи, а также на строки и столбцы перекрестной таблицы определяются предложением WHERE.
Упорядоченность выводимых данных определяется предложением ORDER BY. В нем нужно указать порядок сортировки строк. Столбцы перекрестной таблицы по умолчанию выводятся в порядке возрастания. Режим вывода столбцов в порядке убывания нужно указать явно (опция DESC). Для задания порядка расположения столбцов, не совпадающего со стандартным,
используется предикат IN. |
ПМИ |
|
Пример |
|
|
6. Определить для каждого поставщика количество |
||
поставленных партий товаров по месяцам задаваемого года и общее количество |
||
партий за год. |
|
|
КафедраPARAMETERS [Укажите год] Short;
TRANSFORM Count(Товары.Код_поставщика) AS [За месяц] SELECT Поставщик,
Count(Товары.Код_поставщика) AS [За год]
FROM Поставщики INNER JOIN Товары ON
Поставщики.Код поставщика = Товары.Код_поставщика
WHERE Year(Дата_поставки) = [Укажите год]
GROUP BY Поставщик
ORDER BY Поставщик
PIVOT Format(Дата_поставки, "mmm")
IN ("янв", "фев", "мар", "апр", "май", "июн", "июл", "авг","сен","окт","ноя","дек");
66
Подчиненные запросы
Логические выражения, представляющие условия отбора в предложениях WHERE и HAVING, могут быть достаточно сложными. Так, например, в предикате Сравнение операндом может быть не только выражение, но и более
сложная структура – подчиненный запрос. |
ДонНТУ |
|
Синтаксис предиката Сравнение: |
||
|
выражение {= | <> | > | < | >= | <=}{выражение | подчиненный- запрос}
Тип данных первого выражения должен быть совместимым с типом данных второго выражения или со значением, возвращаемым при выполнении подчиненного запроса (сравнение строк производится без учета регистра). Если подчиненный запрос не возвращает ни одной записи или возвращает более одной записи, регистрируется ошибка. Если значение одного из операндов равно Null, то результат сравнения считается неопределенным.
Подчиненный запрос используется для выбора из одного столбца значений некоторого множества значений (либо ни одного). Имеет следующий синтаксис:
(SELECT [ALL | DISTINCT ] список – выбора ПМИ
FROM …
[WHERE …] [GROUP BY …] [HAVING …] )
(полный синтаксис предложений FROM, WHERE, GROUP BY и HAVING смотрите в предыдущих пунктах).
В условии отбора предложения WHERE можно ссылаться на поля любой
таблицы, определенной во внешнем запросе.
В предложении GROUP BY можно ссылаться на любое поле из любой |
|
Кафедра |
|
таблицы, указанной в FROM, даже если оно не входит в список выбора. |
|
Пример 7. Определить тех поставщиков, у которых средняя стоимость |
|
партий товаров меньше средней стоимости партий по всем поставщикам. |
|
SELECT Код поставщика, |
|
Avg([Цена единицы]*[Количество_единиц]) |
|
AS [Средняя стоимость партий] |
|
FROM Товары |
|
GROUP BY Код поставщика |
|
HAVING Avg ([Цена_единицы]*[Количество_единиц]) < |
|
(SELECT |
Avg |
([Цена единицы]*[Количество_единиц]) |
|
FROM Товары) |
|
ORDER BY Код поставщика; |
|
Предикат EXISTS проверяет существование в подчиненном запросе по крайней мере одной строки, которая удовлетворяет условиям отбора:
67
EXISTS (подчиненный - запрос)
Результат всегда определен. Если подчиненный запрос возвращает по крайней мере одну строку, результат имеет значение Истина, в противном случае – Ложь.
Предикат IN определяет, равно ли некоторое значение одному из значений, указанных в списке или возвращаемых подчиненным запросом:
выражение [NOT] IN {(подчиненный-запрос)| ({литерал}, …) | выражение}
Типы данных, участвующих в IN, должны быть совместимыми. Если одно из значений равно Null, то результат сравнения не определен.
IN в терминах других предикатов: |
|
||
а) |
выражение IN выражение |
|
|
эквивалентно: выражение = выражение |
|
||
б) |
выражение IN (подчиненный - запрос) |
|
|
эквивалентно: выражение ANY (подчиненный - запрос) |
|||
в) |
выражение IN (a,b,c,…), |
где a,b,c… – литералы, |
|
эквивалентно: (выражение = a) OR (выражение = b) OR (выражение = c) … |
|||
г) выражение NOT IN … |
|
ДонНТУ |
|
эквивалентно: NOT (выражение IN …) |
|
Предикаты SOME, ANY,ПМИALL сравнивают значение выражения с некоторым значением или всеми значениями столбца, возвращаемого подчиненным запросом:
выражение { = | <> | > | < | >= | <= }
[SOME | ANY | ALL] (подчиненный - запрос)
КафедраТип данных выражения должен быть совместимым с типом данных столбца, возвращаемого подчиненным запросом. Сравнение строк
производится без учета регистра.
При использовании ALL предикат принимает значение Истина, если все результаты сравнения со значениями, возвращаемыми подчиненным запросом, истинны. Если выражение или некоторое значение из возвращаемых подчиненным запросом равно Null, результат не определен.
При использовании SOME (или ANY, которое является синонимом SOME) предикат принимает значение Истина, когда результат сравнения хотя бы с одним из возвращаемых подчиненным запросом значений истинен. Если выражение имеет значение Null, результат не определен. Если подчиненный запрос не возвращает никаких значений, предикат принимает значение Ложь.
68
Пример 8. Определить партии товаров, цена которых превышает цену указываемого товара (один и тот же товар может иметь в разных партиях различные цены).
PARAMETERS [Укажите код товара] Long; SELECT Товары.Код_товара, Каталог.Товар,
Цена_единицы, Дата_поставки
FROM Каталог INNER JOIN Товары
ON Каталог.Код_товара = Товары.Код товара WHERE Цена_единицы > ALL
(SELECT Distinct Цена_единицы
FROM Товары
WHERE Код_товара = [Укажите код товара]) ORDER BY Код_товара;
Выполнение приведенного запроса:
1) Подчиненный запрос возвращает в качестве результата столбец
значений, |
представляющих |
разные цены |
заданного товара |
(например, |
|
|
|
ПМИ |
|
|
|
принтера): 210, 230, 280, 300, 330. |
|
|
|||
2) |
Внешний запрос первоначально создает ДонНТУдинамический набор записей, |
||||
в который входят все партии товаров. |
|
|
|||
3) |
Для |
каждой записи |
динамического |
набора выполняется |
сравнение |
значения поля Цена_единицы со значениями столбца, возвращаемого подчиненным запросом.
4) Если результат сравнения Истина (то есть условие отбора удовлетворяется), запись включается в результат запроса. В противном случае запись отбрасывается.
Итак, подчиненный запрос можно использовать для выполнения таких задач:
1)можно находить значения в главном запросе, которые =, > или <, чем значения, возвращаемые подчиненным запросом (используя предикаты Сравнения, IN, SOME, ANY, ALL);
2)с помощью предиката EXISTS или NOT EXISTS можно проводить в подчиненном запросе проверку на существование результата;
3)можно создавать вложенные подчиненные запросы;
4)использовать SQL – инструкции в QBE – запросах:
-в строке ПОЛЕ для определения нового поля;
-в строке Условие отбора для определения условий отбора для
поля.Кафедра
69