Лекция 16. Выборка данных на языке SQL Вопросы лекции: 1

advertisement
Лекция 16. Выборка данных на языке SQL
Вопросы лекции:
1 Синтаксис оператора SELECT
2 Использование условий поиска для отбора строк
3 Применение специальных операторов
4 Получение итоговых данных
Запросы - это наиболее часто используемый момент в SQL ведь этот язык для них и был создан.
Запрос представляет собой некую команду, которая обращается к БД и сообщает ей, чтобы она
отобразила определенную информацию из таблиц в память. Эта информация обычно выводится
непосредственно на экран компьютера, терминал, посылается принтеру, сохраняется в файле или
служит исходными данными для другой команды или запроса.
Запросы реализуются с помощью операторов SQL языка обработки данных (data manipulation language - DML). Основные операторы DML – это операции выборки SELECT и операции обновления INSERT, UPDATE, DELETE. Выборка в SQL состоит из одиночной команды SELECT с
достаточно простой структурой, однако путем ее использования можно выполнить сложную обработку данных. В самой простой форме, команда SELECT просто обращается к БД, чтобы извлечь
информацию из таблицы.
Рассмотрим выборку (или чтение данных) на примере базы данных поставщиков и деталей, содержащей три файла:
 поставщики S
 детали P
 поставки SP:
Например, можно вывести таблицу деталей, сформулировав следующий запрос:
SELECT P#, PNAME, COLOR, WEIGHT, CITY FROM P;
Детально поясним каждую часть этой команды:
SELECT - ключевое слово, которое сообщает БД, что эта команда является запросом, т.е. все запросы начинаются этим словом.
P#, PNAME, COLOR, WEIGHT, CITY - список полей из таблицы, которые выбираются запросом. Поля, не перечисленные здесь, не будут включены в вывод команды, но это, разумеется, не
означает, что они будут удалены или информация в них будет стерта из таблиц. Запрос не воздействует на информацию в таблицах, он только показывает данные.
FROM P - ключевое слово, подобно SELECT, которое должно быть представлено в каждом запросе. Оно сопровождается пробелом и затем именем таблицы используемой в качестве источника
информации.
Точка с запятой (;) используется во всех интерактивных командах SQL для сообщения БД, что команда заполнена и готова выполниться.
Очевидно, запрос такого характера не обязательно будет упорядочивать вывод любым указанным
способом. Та же самая команда, выполненная с теми же самыми данными, но в разное время, не
сможет вывести результат в одинаковом порядке. Обычно строки обнаруживаются в том порядке,
в котором они найдены в таблице, а поскольку он произволен, то совсем не обязательно будет сохраняться тот порядок, в котором данные вводились или сохранялись. Допускается упорядочивать
вывод командами SQL с помощью специального предложения; необходимо иметь в виду, что в
отсутствие явного упорядочения нет никакого определенного порядка в выводе результатов запроса.
Если необходимо получить каждое поле таблицы, имеется необязательное сокращение в виде символа "звездочка" (*). которое можно использовать для вывода полного списка полей следующим
образом:
SELECT * FROM P;
кто приведет к тому же результату, что и предыдущая команда.
Ключевое слово FROM, следующее далее, сопровождается пробелом и именем таблицы, запрос к
которой делается.
1 Синтаксис оператора SELECT
Выборка данных в языке SQL производится с помощью оператора SELECT
Синтаксис оператора SELECT:
DISTINCT – аргумент, обеспечивающий возможность устранения избыточности, т.е. повторяющихся значений, из предложения SELECT. Этот аргумент просматривает значения, которые были
выведены ранее, и не дает им дублироваться в списке.
ALL – аргумент, производящий противоположный эффект: дублирование строк вывода сохранится.
Примеры:
2 Использование условий поиска для отбора строк
SQL дает возможность устанавливать критерии выбора записей.
WHERE <предикат> - предложение команды SELECT, которое позволяет устанавливать
предикаты, условие которых может быть верным или неверным для любой записи таблицы.
Команда извлекает только те записи из таблицы, для которой такое утверждение истинно.
СУБД рассматривает всю таблицу по одной записи, чтобы определить, является ли предикат истинным.
Пример 1.
Выбрать фамилии и местонахождение поставщиков из отношения S, причем интересуют только
такие, рейтинг (статус) которых равен 20.
Изменять порядок столбцов для имен можно только в операторе SELECT, но не в предложении
WHERE.
В предикатах часто требуется не только оценить равенство оператора как истинного или ложного,
но и осуществить другие виды связей. Это реализуется с помощью:
 булевых операторов (AND, OR, NOT) и
 знаков отношений (=, >, <, >=, <=, <>).
Предикат может содержать неограниченное число условий.
Реляционный оператор – математический символ, указывающий на определенный тип сравнения
между значениями:
Реляционный оператор Значение
=
равно
>
больше чем
<
меньше чем
>=
больше чем или равно
<=
меньше чем или равно
<>
не равно
Пример 2. Вывести список фамилий поставщиков, рейтинг которых STATUS больше 20.
SELECT SNAME FROM S WHERE STATUS > 20 AND CITY=London;
Пример 3. Вывести список фамилий поставщиков, рейтинг которых STATUS
больше или равен 20.
SELECT SNAME FROM S WHERE STATUS >= 20 OR CITY=London;
Результат:
Стандартные булевские операторы, используемые в SQL:
Булевский оператор Значение
верны ли оба операнда А, В
А AND В
верен ли хотя бы один из операндов А, В
А OR В
изменяет значение операнда А на противоположное
NOT A
Пример 4. Выполним запрос:
SELECT SNAME FROM S WHERE STATUS >= 20 AND CITY=London;
Результат – отношение:
Пример 5. Изменим AND в запросе на OR:
SELECT SNAME FROM S WHERE STATUS >= 20 OR CITY=London;
Результат изменится:
Пример 6. SELECT SNAME FROM S WHERE NOT (CITY=Athens); Результат:
3 Применение специальных операторов
Для отбора строк можно использовать сочетание реляционных, булевских операций
со специальными операторами:
IN, BETWEEN, LIKE, IS NULL
1 Оператор IN
Оператор IN определяет набор значений, в который данное значение должно быть включено.
Пример
Результат запроса с помощью оператора выборки
SELECT SNAME FROM S WHERE STATUS =10 OR STATUS =30;
дает следующий результат:
.
Ту же информацию можно получить с использованием в запросе на выборку оператора IN:
SELECT SNAME FROM S WHERE STATUS IN (10,30);
2 Оператор BETWEEN
Оператор BETWEEN похож на IN, но, в отличие от определения из набора, BETWEEN определяет набор значений, в который должны умещаться искомые значения, что и делает предикат верным. Структура оператора BETWEEN следующая: вводится начальное значение, ключевое слово
AND и конечное значение. В отличие от IN, BETWEEN различает порядок значений, и, следовательно, первое из них в предложении должно быть первым по алфавитному или числовому порядку.
Запрос:
SELECT SNAME FROM S WHERE STATUS BETWEEN 5 AND 15;
дает результат
,а
запрос
SELECT SNAME FROM S WHERE STATUS BETWEEN 10 AND 20; -
. Чтобы исключить границы, нужно модифицировать запрос следующим образом:
SELECT SNAME FROM S WHERE (STATUS BETWEEN 10 AND 20) AND
NOT STATUS IN (10, 20);
Получим результат:
3 Оператор LIKE
Оператор LIKE применим только к полям типа CHAR или VARCHAR (символы), в которых он
ищет подстроки, т.е. ищет символы и проверяет, совпадают ли они с условием.
В качестве условия оператор использует групповые символы – специальные символы, которые
соответствуют чему-либо. Существует два типа групповых символов, используемых с LIKE:
 символ «_» замещает любой одиночный символ, например,
‘м_л’ соответствует словам ‘мол’, ‘мел’, но не соответствует слову ‘металл’.
 знак «%» замещает последовательность любого числа символов, в том числе нулевой длины, например,
‘%М%Л’ соответствует словам ‘МЕЛ’ или ‘ПОМОЛ’, но
не соответствует слову ‘МОЛОКО’.
Пример. Найдем всех поставщиков, чье местоположение начинается с буквы L.
SELECT SNAME FROM S WHERE SITY LIKE ‘L%’;
Результатом запроса будет выборка:
Оператор LIKE может быть полезен, например, при поиске атрибута, если точное его значение
неизвестно, например, если происходит поиск по фамилии, о которой известно только, что она
похожа на Казанко, Козанко или Казанков, то поиск можно организовать с помощью операторов:
‘К_занко%’
4 Оператор IS NULL – является нулем. Если информация неизвестна, соответствующее поле заполняется маркером NULL. С помощью оператора IS NULL можно найти такие значения полей.
Пример. Найдем все записи таблицы с информацией о поставщиках со значением NULL в поле
CITY:
SELECT * FROM S WHERE CITY IS NULL;
Если необходимо устранить NULL из вывода информации, можно воспользоваться запросом, содержащим NOT в предикате:
SELECT * FROM S WHERE CITY NOT NULL; - результат – отношение S, если в нем отсутствуют значения NULL.
4 Получение итоговых данных
Запросы могут производить обобщенную групповую обработку значений полей, что реализуется с
помощью агрегатных функций. Агрегатные функции производят одиночное значение для всей
группы таблицы. В SQL допускаются следующие агрегатные функции:
Агрегатные Результат
функции
COUNT
Производит подсчет количества строк или не-NULL значений полей, которые выбрал запрос
SUM
Рассчитывает арифметическую сумму всех выбранных значений данного поля
AVG
Производит усреднение всех выбранных значений данного поля
MAX
Находит и возвращает наибольшее из всех выбранных значений данного поля
MIN
Находит и возвращает наименьшее из всех выбранных значений данного поля
Агрегатные функции используются подобно именам полей в предложении SELECT запроса, но с
учетом того, что они берут имена поля в качестве аргументов. Стоит иметь в виду, что
 с SUM и AVG используются только числовые поля, а
 с COUNT, МАХ, и MIN могут использоваться числовые или символьные поля.
Когда функции записываются с символьными полями, МАХ и MIN используют их эквивалент
ASCII, в соответствии с которым выбирается максимальное или минимальное значение.
Применение агрегатных функций рассмотрим на примере двух таблиц:
 таблицы STUDENTS с полями: SNUM – номер студенческого билета; SFAM – фамилия
студента; STIP – размер стипендии
 таблицы USP (Успеваемость) с полями: UNUM – код факта сдачи учебной дисциплины, OCENKA – оценка, полученная студентом по учебному предмету, UDATE – дата сдачи, SNUM – номер студенческого билета, PNUM – код учебного предмета.
Чтобы найти сумму всей выплаченной стипендии в таблице с данными о студентах, можно использовать следующий запрос:
SELECT SUM (STIP) FROM STUDENTS;
вывод которого состоит из единственного числа 1100.
Действие агрегатных функций, как видно, отличается от выбора поля, при котором возвращается,
например, одиночное значение. По этой причине агрегатные функции и поля не могут совместно
использоваться без предложения GROUP BY, о котором речь пойдет ниже.
Функция COUNT несколько отличается от остальных - она считает количество значений в данном
столбце, или число строк в таблице. В частности, для подсчета количества значений в столбце, она
используется с DISTINCT . Например, можно подсчитать количество студентов, сдававших учебные предметы по таблице успеваемости с помощью следующего запроса:
SELECT COUNT (DISTINCT SNUM) FROM USP;
В качестве результата этого запроса будет получено значение 4. Обратите внимание на обязательное требование того, чтобы DISTINCT был помещен в круглые скобки в отличие от предыдущих
примеров. Кроме того, допускается возможность использования DISTINCT с любыми агрегатными функциями, но наиболее часто он используется с COUNT.
Для того чтобы подсчитать общее число строк в таблице, используют функцию COUNT со звездочкой вместо имени поля, например как в следующем примере:
SELECT COUNT (*) FROM STUDENTS
что в качестве результата даст значение 5.
COUNT со звездочкой включает записи с NULL значениями, а также дубликаты, по этой причине
DISTINCT в данном случае не может быть использован.
Агрегатные функции в большинстве реализаций допускают использование аргумента ALL, который помещается перед именем поля аналогично DISTINCT, однако означает противоположное
действие - включать дубликаты. Необходимо пояснить различия между ALL и * , когда они используются с COUNT - ALL использует имя поля как аргумент и не может подсчитать значения
NULL. При этом стоит помнить, что функции, отличные от COUNT, игнорируют значения NULL
в любом случае. Следующий пример подсчитает количество не-NULL значений в поле SNUM,
включая повторения:
SELECT COUNT (ALL SNUM) FROM USP;
В качестве результата этого запроса будет получено значение 5.
В SQL допускается использовать агрегатные функции с аргументами, которые состоят из выражений, включающих одно или более полей, при этом команда DISTINCT не разрешается. Предположим, что необходимо найти максимальную величину проиндексированной (в примере, увеличенной вдвое) стипендии. Для каждой строки таблицы такой запрос должен умножать STIP на 2 и
выбирать самое большое значение, которое будет найдено. Для этого можно воспользоваться следующим:
SELECT MAX (STIP*2) FROM STUDENTS;
В качестве результата здесь будет получено число 800. Команда GROUP BY позволяет определять
подмножество значений в поле в терминах другого поля, и применять функцию агрегата к такому
подмножеству. Это дает возможность объединить поля и агрегатные функции в едином предложении SELECT. Например, если возникает необходимость в определении наименьшей оценки, полученной каждым студентом, то можно сделать с использованием GROUP BY следующий запрос:
SELECT SNUM, MIN (OCENKA) FROM USP GROUP BY SNUM;
Вывод для этого запроса показан ниже:
SNUM
3412 4
3413 4
3414 3
3416 5
Команда GROUP BY может применяться с агрегатными функциями независимо от серий групп,
которые определяются с помощью значения поля в целом. В этом случае каждая группа состоит из
всех строк с тем же самым значением поля SNUM, и MIN функция применяется отдельно для
каждой такой группы. Значение поля, к которому применяется GROUP BY, имеет только одно
значение на группу вывода, так же как это делает агрегатная функция. Поэтому в результате и появляется совместимость, которая позволяет агрегатным функциям и полям объединиться.
В принципе, допускается использование GROUP BY одновременно с несколькими полями. Для
примера модифицируем предыдущий случай таким образом, чтобы выводилось наименьшее значение оценки за каждый день. При этом запрос будет следующий:
SELECT SNUM, UDATE, MIN (OCENKA)
FROM USP
GROUP BY SNUM, UDATE;
Вывод для этого запроса будет следующий:
SNUM
3412
3412
3413
3414
UDATE
10/06/2003 5
12/06/2003 4
10/06/2003 4
11/06/2003 3
3416
12/06/2003
5
Теперь предположим, что в предыдущем примере, необходимо увидеть только минимальную
оценку, меньшую 5. Напрямую использовать агрегатную функцию в предложении WHERE в этом
случае нельзя, потому что предикаты оцениваются в терминах одиночной строки, а агрегатные
функции - групп строк. По этому необходимо воспользоваться предложением HAVING, определяющим критерии, используемые для удаления определенных групп из вывода, подобно тому, как
это делает предложение WHERE для индивидуальных строк. При этом запрос будет следующий:
SELECT SNUM, UDATE, MIN (OCENKA) FROM USP
GROUP BY SNUM, UDATE HAVING MIN (OCENKA)<5;
Вывод для этого запроса приведен ниже:
SNUM
UDATE
3412
3413
3414
12/06/2003
10/06/2003
11/06/2003
4
4
3
Аргументы в предложении HAVING подчиняются тем же самым правилам, что и в предложении
SELECT, состоящем из команд, использующих GROUP BY: они должны иметь одно значение на
группу вывода. Например, следующая команда будет запрещена:
SELECT SNUM, MIN (OCENKA) FROM USP GROUP BY SNUM,
HAVING UDATE = 10/06/2003;
Поле UDATE не может быть вызвано предложением HAVING, потому что оно может иметь
больше чем одно значение на группу вывода, следовательно, для избежания такой ситуации, предложение HAVING должно ссылаться только на агрегатные функции и поля, выбранные в GROUP
BY. Правильный способ сделать рассмотренный запрос следующий:
SELECT SNUM, MIN (OCENKA) FROM USP
WHERE UDATE = 10/06/2003
GROUP BY SNUM;
Результат такого запроса следующий:
SNUM
3412 5
3413 4
Поскольку поле UDATE отсутствует в выводе, то для повышения удобочитаемости в результаты
стоит включить поясняющий текст о том, что это за данные.
Как говорилось выше, HAVING может использовать только аргументы, которые имеют одно значение на группу вывода. Практически же ссылки на поля, выбранные с помощью GROUP BY.
также допустимы. Например, для вывода наименьших оценок для студентов с номерами 3412 и
3413 можно воспользоваться следующим:
SELECT SNUM, MIN (OCENKA) FROM USP GROUP BY SNUM HAVING SNUM IN (3412,
3413);
Вывод для этого запроса следующий:
SNUM
3412
3413
4
4
В заключение заметим, что следует быть внимательным при использовании таких функций: нельзя
использовать агрегатную функцию от агрегатной функции.
Итак, можно использовать запросы для получения определенных значений и формировать вывод
данных в соответствии с требованиями текущей задачи пользователя.
Download