Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретические основы реляционных баз данных. Учебное пособие.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
936 Кб
Скачать

- 35 -

Можно использовать подзапросы внутри предложения HAVING. Эти подзапросы могут использовать свои собственные агрегатные функции, если они не производят нескольких значений, или использовать GROUP BY или HAVING. Примером этого служит следующий запрос, в котором находятся группы, у которых средний балл по группе выше среднего балла по всем студентам.

SELECT s.stgroup,AVG(gpa)

FROM students s

GROUP BY stgroup

HAVING AVG(gpa) >

(SELECT AVG(gpa) FROM students);

stgroup

|

avg

---------+--------------------

345

| 4.8700000000000000

342

| 4.6250000000000000

(2 rows)

2.6.2. Использование операторов ANY, ALL и SOME

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

ANY, ALL и SOME принимют подзапросы как аргументы и используются совместно с реляционными операциями. В этом отношении они напоминают оператор IN, когда тот используется с подзапросами: они берут все значения, выведенные подзапросом, и обрабатывают их как модуль. Однако в отличие от IN они могут использоваться только с подзапросами.

Операторы SOME и ANY взаимозаменяемы везде, и там, где мы используем ANY, SOME будет работать точно так же. Различие в терминологии состоит в том, чтобы позволить людям использовать тот термин, который является однозначным.

В примере ниже мы выбираем только те группы, для которых в таблице students имеется хотя бы один студент. Предположим, что мы добавили в таблицу stgroups запись о группе 311, причем в таблице students нет ни одного студента, который учится в этой группе.

SELECT *

FROM stgroups ;

stgroup

| department

| curator

---------

+------------

+-----------

340

| ЭВМ

| Логинов

 

 

- 36 -

341

| ЭВМ

| Кузьмин

342

| ЭВМ

| Гринченко

344

| САПР

| Бабаев

345

| ВПМ

| Макаров

349

| АСУ

| Маркин

311

| РТФ

| Езерский

(7 rows)

 

 

В результате следующего запроса не будет записи с группой 311, поскольку у нас нет ни одного обучающегося в этой группе.

SELECT * FROM stgroups WHERE stgroup = ANY

(SELECT stgroup FROM students );

stgroup

| department

| curator

---------

+------------

+-----------

342

| ЭВМ

| Гринченко

344

| САПР

| Бабаев

345

| ВПМ

| Макаров

349

| АСУ

| Маркин

(4 rows)

 

 

Еще один часто используемый оператор - это ALL. С помощью ALL предикат будет верным, если каждое значение, выбранное подзапросом, удовлетворяет условию в предикате внешнего запроса. Если мы хотим пересмотреть наш предыдущий пример, чтобы вывести только тех студентов, чьи средние оценки фактически выше, чем у каждого студента в определенной группе (в примере это группа 345, в которой, правда, всего один студент), мы можем сформировать следующий запрос:

SELECT * FROM students WHERE gpa > All

(SELECT gpa FROM students

WHERE stgroup = '345');

 

 

family

| name

|

stgroup |

gpa | sex

---------

+--------

+

---------

+------

+

-----

Балашов

| Андрей |

342

|

5.00 |

м

(1 row)

 

 

 

 

 

 

ALL чаще используется с неравенствами, нежели с равенствами, так как значение может быть "равным для всех" результатом подзапроса, только если все результаты фактически идентичны.

В SQL сказать, что значение больше (или меньше), чем любое (ANY) из набора значений, - то же самое, что сказать, что оно больше (или меньше), чем любое отдельное из этих значений. И наоборот, сказать, что значение не равно всему (ALL) набору значений, это то же, что сказать, что нет такого значения в наборе, которому оно равно.

-37 -

2.6.3.Использование предложения UNION

Ранее мы обсуждали различные способы вложения запросов друг в друга. Имеется другой способ объединения нескольких запросов - формирование их в объединение.

Рассмотрим использование предложения UNION в SQL. UNION отличается от подзапросов тем, что в нём ни один из двух (или более) запросов не управляется другим запросом. Все запросы выполняются независимо друг от друга, а уже вывод их объединяется. В примере мы объединяем результаты двух запросов. В первом выводятся все студенты группы 342, а во втором куратор этой группы.

SELECT family FROM students s WHERE s.stgroup='342'

UNION

SELECT curator FROM stgroups g WHERE g.stgroup='342';

family

--------------

Гринченко

Фахрудинова

Катеринченко

Никулкин

Балашов (5 rows)

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

SELECT family, 'студент' AS member FROM students s WHERE s.stgroup='342'

UNION

SELECT curator, 'куратор' FROM stgroups g WHERE g.stgroup='342';

family

| member

--------------

+---------

Фахрудинова

| студент

Гринченко

| куратор

Балашов

| студент

Катеринченко

| студент

Никулкин

| студент

(5 rows)

 

- 38 -

Обратите внимание, что с помощью оператора AS имя константному полю задано только в первом запросе, а на результат второго запроса оно распространяется автоматически.

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

2.6.4. Ввод, удаление и изменение значения поля

Значения могут быть помещены и удалены из полей тремя командами языка DML (язык манипулирования данными):

INSERT (ВСТАВИТЬ),

UPDATE (МОДИФИЦИРОВАТЬ), DELETE (УДАЛИТЬ).

Все значения в SQL вводятся с использованием команды модификации INSERT. В самой простой форме INSERT использует следующий синтаксис:

INSERT INTO VALUES (<value>, . . .);

Так, для ввода данных об еще одном студенте следует использовать следующую команду:

INSERT INTO students

VALUES ('Дубоделов','Андрей','345',4.87,'м');

Если вам нужно ввести пустое значение (NULL), вы вводите его точно так же, как и обычное значение. Предположим, что ещё нет значения среднего балла для студентки Макаркиной. Вы можете вставить в строку значение=NULL в это поле следующим образом:

INSERT INTO students

VALUES ('Макаркина','Надежда','344',NULL,'ж');

INSERT 0

1

 

 

 

 

SELECT *

FROM students ;

 

 

 

family

 

| name

| stgroup | gpa

| sex

--------------

 

+---------

+---------

+------

+-----

Балашов

 

| Андрей

| 342

| 5.00

| м

Катеринченко

| Андрей

| 342

| 4.59

| м

Колычева

 

| Лия

| 349

| 4.38

| ж

Малин

 

| Сергей

| 345

| 4.87

| м

Никулкин

 

| Сергей

| 342

| 4.79

| м

Фахрудинова

| Тамара

| 342

| 4.12

| ж

Чертков

 

| Максим

| 344

| 4.31

| м

Дубоделов

| Андрей

| 345

| 4.87

| м

Макаркина

| Надежда | 344

|

| ж

(9 rows)

 

 

 

 

 

- 39 -

Так как значение NULL - это специальный маркёр, а не просто символьное значение, оно не заключается в одинарные кавычки.

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

INSERT INTO boys

SELECT family,name FROM students WHERE sex='м'; INSERT 0 6

SELECT * FROM boys ;

family

| name

--------------

+--------

Балашов

| Андрей

Катеринченко

| Андрей

Малин

| Сергей

Никулкин

| Сергей

Чертков

| Максим

Дубоделов

| Андрей

(6 rows)

 

Здесь мы в созданную ранее пустую таблицу boys вставляем из таблицы students записи обо всех студентах мужского пола.

Вы можете удалять строки из таблицы командой модификации DELETE. Она может удалять только строки, а не индивидуальные значения полей, так что параметр поля является необязательным или недоступным. Чтобы удалить всё содержание таблицы, вы можете ввести следующую команду:

DELETE FROM boys ; DELETE 6

SELECT * FROM boys ; family | name

--------+------

(0 rows)

Теперь, когда таблица пуста, её можно окончательно удалить командой DROP TABLE . Обычно вам нужно удалить только некоторые определённые строки из таблицы. Чтобы определить, какие строки будут удалены, вы используете предикат так же, как вы это делали для запросов. Например, чтобы удалить студентов с именем Андрей из таблицы, вы можете ввести:

DELETE FROM boys WHERE name='Андрей'; DELETE 3

SELECT * FROM boys ;

- 40 -

family

| name

----------

+--------

Малин

| Сергей

Никулкин

| Сергей

Чертков

| Максим

(3 rows)

 

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

UPDATE students SET stgroup = '340';

 

UPDATE 9

 

 

 

 

SELECT * FROM students ;

 

 

 

family

| name

| stgroup | gpa

| sex

--------------

+---------

+---------

+------

+-----

Балашов

| Андрей

| 340

| 5.00

| м

Катеринченко

| Андрей

| 340

| 4.59

| м

Колычева

| Лия

| 340

| 4.38

| ж

Малин

| Сергей

| 340

| 4.87

| м

Никулкин

| Сергей

| 340

| 4.79

| м

Фахрудинова

| Тамара

| 340

| 4.12

| ж

Чертков

| Максим

| 340

| 4.31

| м

Дубоделов

| Андрей

| 340

| 4.87

| м

Макаркина

| Надежда | 340

|

| ж

(9 rows)

 

 

 

 

На практике такое глобальное изменение значений в таблицах

используется крайне редко. Чаще всего модифицируются только определенные строки. В примере мы переведем студентку Макаркину в группу 340 и заодно наконец установим для нее средний балл:

UPDATE students

 

 

 

SET stgroup = '340', gpa = 4.55

 

WHERE family = 'Макаркина';

 

 

UPDATE 1

 

 

 

 

SELECT * FROM students ;

 

 

 

family

| name

| stgroup | gpa

| sex

--------------

+---------

+---------

+------

+-----

Балашов

| Андрей

| 342

| 5.00

| м

Катеринченко

| Андрей

| 342

| 4.59

| м

Колычева

| Лия

| 349

| 4.38

| ж

Малин

| Сергей

| 345

| 4.87

| м

Никулкин

| Сергей

| 342

| 4.79

| м

Фахрудинова

| Тамара

| 342

| 4.12

| ж

Чертков

| Максим

| 344

| 4.31

| м

Дубоделов

| Андрей

| 345

| 4.87

| м

Макаркина

| Надежда | 340

| 4.55

| ж

(9 rows)

 

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]