Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

УП СУБД ч1

.pdf
Скачиваний:
14
Добавлен:
11.06.2015
Размер:
1.05 Mб
Скачать

CUSTOMER_NAME

самый дорогой

самый дешевый

Mr.Pundleberry

199.99

25

Mr.O’Raily

16.5

12.7

Ms.Magpie

400

12.5

Рис. 9.7. Значение запроса 9.8

Агрегатные функции могут использоваться и в запросах без группировки; запрос 9.9 определяет цены самых дорогих и самых дешевых заказов по всем заказам.

SELECT MAX( price*quantity ) «самый дорогой», MIN( price*quantity ) «самый дешевый»

FROM acceptedorders

(9.9)

 

 

 

 

 

Самый дорогой

самый дешевый

 

 

400

12.5

 

Рис. 9.8. Значение запроса 9.9

В выражениях группировки можно использовать не только имена полей, но и любые корректные выражения, включая неагрегатные функции: в запросе 9.10 группировка осуществляется по первому символу поля name, а в запросе 9.11 – по значению выражения – конкатенации двух числовых полей, преобразованных в строки.

SELECT SUBSTR(name, 1, 1 ), COUNT(*)

 

FROM Students

 

(9.10)

GROUP BY SUBSTR(name, 1, 1 );

 

 

 

 

 

SUBSTR(NAME,1,1)

COUNT(*)

 

 

P

2

 

 

K

1

 

 

I

1

 

 

M

1

 

 

D

1

 

 

J

2

 

 

C

1

 

 

A

1

 

 

T

1

 

 

G

1

 

 

F

1

 

Рис. 9.9. Значение запроса 9.10

91

SELECT TO_CHAR(year) || ‘.’ || TO_CHAR(class) «Группа», COUNT(*) «Количество»

FROM Students

GROUP BY TO_CHAR(year) |‘.’ || TO_CHAR(class); (9.11)

Группа Количество

3.22

3.31

2.12

3.11

1.12

1.22

2.21

2.32

Рис. 9.10. Значение запроса 9.11

Следует обратить внимание, что при использовании группировки значения полей исходных записей не могут присутствовать в значении запроса, если они не используются в выражениях группировки. Например, в последнем запросе (9.11) невозможно вывести имена отдельных студентов.

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

HAVING логическое выражение

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

SELECT year, class, COUNT(*)

FROM Students WHERE year = 1

GROUP BY year, class HAVING COUNT(*)>1; (9.12)

YEAR

CLASS

COUNT(*)

1

2

2

1

1

2

Рис. 9.11. Значение запроса 9.12

92

9.3.Множественные операции

Вязыке SQL существует несколько бинарных операций, которые позволяют оперировать с результирующими множествами нескольких независимых SELECT-запросов. Такие операции, приведенные в таблице 6, называются множественными.

Таблица 6

Множественные операции

UNION Слияние строк обоих результирующих множеств, при этом дубликаты строк удаляются

UNION ALL Слияние строк с сохранением дубликатов

INTERSECT Слияние строк при условии, что каждая строка присутствует в каждом объединяемом результирующем множестве

MINUS В результирующем множестве остаются только строки, которые присутствуют в первой выборке, но отсутствуют во второй; эта операция несимметричная

Рассмотрим несколько формальных примеров использо-

вания множественных операций:

 

SELECT result FROM CourseResult

(9.13)

UNION SELECT result FROM CourseResult

 

 

 

 

 

 

RESULT

 

 

 

4

 

 

 

 

5

 

 

 

 

-

 

 

 

Рис. 9.12. Значение запроса 9.13

 

SELECT result FROM CourseResult

(9.14)

INTERSECT SELECT result FROM CourseResult

 

 

 

 

 

RESULT

 

 

 

 

4

 

 

 

 

5

 

 

 

 

-

 

 

 

Рис. 9.13. Значение запроса 9.14

SELECT result FROM CourseResult

 

UNION ALL

(9.15)

SELECT result FROM CourseResult

93

RESULT

 

5

 

-

 

5

 

4

 

-

 

5

 

-

 

5

 

4

 

-

 

Рис. 9.14. Значение запроса 9.15

 

SELECT result FROM CourseResult

(9.16)

MINUS SELECT result FROM CourseResult

no data found

 

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

SELECT name, ‘an academic staff’ «status», position FROM staff

UNION

SELECT name, ‘a student ‘ «status», TO_CHAR(class) || ‘ year’

FROM student

 

(9.17)

ORDER BY «status», 3

 

 

 

 

NAME

status

POSITION

 

S.Abiteboul

An academic staff

Full Professor

 

Won Kim

An academic staff

Full Professor

 

G.Anderson

An academic staff

Senior Lector

 

Gill

a student

1 year

 

Polie

a student

2 year

 

Bill

a student

3 year

 

Jane

a student

3 year

 

Рис. 9.15. Значение запроса 9.17

94

Поскольку поле class имеет тип INT, перед объединением необходимо преобразовать это значение в тип CHAR для соответствия с типом значений поля position из первого SELECT-запроса.

В этом запросе 9.16 применяется упорядочивание результирующего множества после выполнения операции UNION. Используемая здесь конструкция ORDER BY относится не к последнему SELECT-запросу, а к значению UNION-операции; использование этой конструкции в первом SELECT-запросе запрещено правилами языка. Идентификатор «status» введен в

обеих выборках для того, чтобы это поле в итоговом результирующем множестве получило именно это имя (по умолчанию при множественных операциях это поле получило бы имя поля первой выборки, т.е. «an academic staff», что не очень удачно). Упорядочивание проводится по второму и третьему полям; вместо идентификатора третьего поля используется его порядковый номер, что разрешается в SQL-Oracle.

Следующие два примера иллюстрируют различие группировки выборок до (9.18) и после (9.19) применения множественных операций.

SELECT result, COUNT(*) FROM CourseResult GROUP BY result

UNION ALL

SELECT result, COUNT(*) FROM CourseResult

GROUP BY result

(9.18)

 

 

 

 

 

RESULT

COUNT(*)

 

 

-

2

 

 

5

2

 

 

4

1

 

 

-

2

 

 

5

2

 

 

4

1

 

Рис. 9.16. Значение запроса 9.18

 

SELECT result, COUNT(*) FROM

 

(SELECT result FROM CourseResult

 

UNION ALL

 

SELECT result FROM CourseResult )

(9.19)

GROUP BY result

95

RESULT COUNT(*)

-4

5

4

4

2

Рис. 9.17. Значение запроса 9.19

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

SELECT DISTINCT title «Курс», staff «Преподавателя» FROM Attends RIGHT JOIN Course USING (title)

MINUS

SELECT DISTINCT title «Курс», staff «Преподавателя»

FROM Attends JOIN Course USING (title)

(9.20)

Выводы

к результирующему множеству – значению запроса можно применить операцию группировки записей, записываемых при помощи конструкции GROUP BY список выражений;

при группировке записи результирующего множества объединяются на группы по совпадающим значениям выражений из списка, затем из каждой группы удаляются строки-дубликаты;

группировка может выполняться по одному полю и по группе полей;

при использовании группировки каждое выражение после SELECT обязательно должно присутствовать и в списке выражений после GROUP BY;

в запросах с группировкой можно использовать агрегатные функции – COUNT(), MIN(), MAX() и SUM().

агрегатные функции вычисляются по всем записям каждой группы после группировки строк результирующего множества и до удаления дубликатов из групп;

96

для селекции записей после выполнения группировки используется конструкция HAVING логическое выражение.

множественные операции UNION (объединение), UNION ALL (объединение с сохранением дубликатов), INTERSECT (пересечение) и MINUS (разность) используются для слияния результирующих множеств двух SELECT-запросов.

Вопросы для контроля

1.Опишите правила вычисления SELECT-запросов с группировкой данных.

2.Какая функция позволяет наиболее простым способом определить количество записей в таблице?

3.Можно ли использовать агрегатные функции в запросах без использования операции группировки?

4.Перечислите основные агрегатные функции языка SQL и объясните правила их вычисления.

5.Какие типичные ошибки возникают при построении запросов с группировкой?

6.Объясните смысл множественных операций.

97

Раздел 10. Язык Oracle SQL. Соединения

ипустые значения

Втекущем разделе описано использование запросов с использованием нескольких таблиц (запросов с соединением)

ипустые значения.

10.1.Пустые значения

Вполях записей может храниться специальное значение, называемое пустым значением, которое записывается при помощи служебного слова NULL. Пустые значения могут использоваться, например, когда настоящее значение некоторого поля неизвестно. Следует различать пустую строку « » и пустое значение.

Манипулирование с полями, в которых могут находиться пустые значения, имеет некоторые особенности. Рассмотрим таблицу CourseResult, в которой находятся сведения об оценках студентов, полученные за соответствующие учебные курсы:

CREATE TABLE CourseResult

(student CHAR(20), course CHAR(20), result int );

STUDENT

COURSE

RESULT

Bill

C Programming

5

Polie

Graphics

-

Jane

OS

5

Jane

DBMS

4

Bill

DBMS

-

Рис. 10.1. Таблица CourseResult

В настоящее время оценки за курс Graphics студентки Polie и курс DBMS студента Bill отсутствуют (например, еще не выставлены), что в базе данных представлено значением NULL в соответствующих строках.

98

При упорядочивании значение NULL считается максимальным:

SELECT * FROM CourseResult

(10.1)

ORDER BY result DESC;

 

 

 

 

 

 

STUDENT

COURSE

RESULT

 

 

Bill

DBMS

-

 

 

Polie

Graphics

-

 

 

Bill

C Programming

5

 

 

Jane

OS

5

 

 

Jane

DBMS

4

 

Рис. 10.2. Значение запроса 10.1

Значение операций сравнения пустых значений в логических выражениях имеет результат, условно обозначаемый при помощи слова UNKNOWN, он приравнивается к логическому значению FALSE (существует одно исключение). Обратите внимание, что слово UNKNOWN не является ни служебным словом языка SQL, в отличие от слова NULL, ни литеральной константой; это слово нельзя использовать в выражениях SQL. Например, значениями двух следующих запросов будут пустые множества:

SELECT * FROM CourseResult WHERE result = NULL;

(10.2)

SELECT * FROM CourseResult WHERE result != NULL;

(10.3)

Для корректного сравнения с пустым значением существует специальные предикаты IS NULL и IS NOT NULL, которые используются следующим образом:

SELECT * FROM CourseResult

 

 

WHERE result IS NULL;

 

(10.4)

 

 

 

 

 

 

STUDENT

COURSE

RESULT

 

 

Polie

Graphics

-

 

 

Bill

DBMS

-

 

 

Рис. 10.3. Значение запроса 10.4

SELECT * FROM CourseResult

(10.5)

WHERE result IS NOT NULL;

99

STUDENT

COURSE

RESULT

Bill

C Programming

5

Jane

OS

5

Jane

DBMS

4

Рис. 10.4. Значение запроса 10.5

В логической операции AND значение UNKNOWN интерпретируется как FALSE, а в операции OR – игнорируется, например:

SELECT * FROM CourseResult

 

 

WHERE student = ‘Bill’ AND result != NULL;

(10.6)

no data found

 

 

 

SELECT * FROM CourseResult

 

(10.7)

WHERE student = ‘Bill’ OR result != NULL;

 

 

 

 

 

 

STUDENT

COURSE

RESULT

 

 

Bill

C Programming

5

 

 

Bill

DBMS

-

 

Рис. 10.5. Значение запроса 10.7

Значениями арифметических операций и неагрегатных функций с пустыми значениями также будут пустые значения (кроме некоторых специфических функций):

SELECT result, result + 0.0 FROM CourseResult;

(10.8)

RESULT RESULT+0.0

5 5

--

5 5

4 4

--

Рис. 10.6. Значение запроса 10.8

Однако при вычислении агрегатных функций пустые значения игнорируются, если в качестве параметра используется имя поля, а не символ «*»:

SELECT COUNT(*), COUNT(result)

(10.9)

FROM CourseResult;

100