Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информационное обеспечение систем управления. Построение запросов пр.pdf
Скачиваний:
4
Добавлен:
15.11.2022
Размер:
3.76 Mб
Скачать

1

1

1

1

1

1 I 1 1 1 1 1 1 1 1 1 1 1 1 1 1

COUNT PRJ4AME2 Виктория Галина Гульнара Евгения Кирил Константин Лиана Лилия Марианна Назгуль Николай Нина Павел Петр Руслан Тарас Эльвира Эмма Юлиана Юлий Явар

4.3. Предложение HAVING

Предположим, что в предыдущем примере вы хотели бы уви­ деть только те имена, которые повторяются более двух раз. Вы не сможете использовать агрегатную функцию в предложении WHERE, потому что агрегатные функции находятся после того, как предложение WHERE уже отработано.

Предложение HAVING определяет критерии, используемые чтобы удалять определенные группы из вывода, точно так же как предложение WHERE делает это для индивидуальных строк. Для

GROUP BY ключевое слово HAVING играет ту же роль, что и WHERE для ORDER BY. Другими словами, WHERE задает усло­ вия для значений из выбранных столбцов, a HAVING задает усло­ вия для групп, создаваемых с помощью GROUP BY.

Ключевое слово HAVING в операторе SELECT должно следо­ вать за выражением ключевого слова GROUP BY и тоже предшест­ вовать ключевому слову ORDER BY, если последнее используется. Синтаксис:

[GROUP BY <список столбцов> [HAVING <условия поис-

ка>]]

Основным требованием к составу предложения HAVING явля­ ется то, что имена столбцов в этом предложении обязательно долж­ ны присутствовать в списке GROUP BY или быть параметрами аг­ регатной функции.

При выполнении такого оператора SELECT делается все то же самое, что и при обычном SELECT: выбираются указанные столбцы строк, соответствующие условию в предложении WHERE, вычис­ ляются значения агрегатных функций. После этого выполняется группировка по столбцам, перечисленным в предложении GROUP BY Затем осуществляется дополнительная «фильтрация» строк на основании условия в предложении HAVING.

Найдем, сколько каких имен содержится в нашем списке, пока­ зывая только те имена, которые повторяются более двух раз:30

SELECT COUNT С) AS "Количество", PR__NAME2

FROM PERSON GROUP BY PR_NAME2

HAVING COUNT(*) >2

ORDER BY 1 DESC, PR_NAME2

Листинг 15

Количество каждого имени

в списке людей при условии,

что это количество превышает 2

Количество

PRNAME2

23

Елена

20

Наталья

I6

Татьяна

Количество

PRJNAME2

15

Светлана

12

Марина

11

Ирина

11

Оксана

11

Ольга

10

Екатерина

9

Юлия

7

Сергей

6

Александр

6

Анна

5

Алексей

5

Дмитрий

5

Надежда

5

Олег

4

Вера

4

Людмила

4

Мария

3

Владимир

3

Ксения

3

Лариса

3

Максим

Мы получили все те данные, которые нам были нужны.

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

1.Отбираются те строки, которые соответствуют условию по­ иска в предложении WHERE, если таковое имеется. В нашем при­ мере это предложение отсутствует.

2.Выбранные строки объединяются в группы на основании значения имени (PRJNAME2).

3.Для каждой группы рассчитываются значения агрегатных функций. При этом для каждой группы создается одна результи­ рующая строка.

4. Полученные в результате строки упорядочиваются в соот ветствии с предложением ORDER BY (в нашем случае — по коли­ честву строк в группе).

5. СОЕДИНЕНИЕ ТАБЛИЦ

Вы помните, что в процессе нормализации таблиц вам часто приходилось разделять таблицы на несколько взаимосвязанных таблиц, чтобы устранить избыточность данных. Напомню, что таб­ лицы снова можно будет объединить с помощью операции соеди­ нения.

Соединение таблиц в операторе SELECT является одним из наиболее мощных и элегантных средств реляционных баз данных.

Существует небольшое количество вариантов соединений, JOIN. Соединения задаются в списке имен таблиц:

FROM <ссылка на таблицу> [, <ссылка на таблицу>]...

Здесь не очень удачно названная мною конструкция <ссылка на таблицу> имеет приблизительно такой синтаксис:

<ссылка на таблицу> ::= { соединяемая таблица> | <имя таблицы> | <имя представления> |

<имя процедурна [(<значение> [<значение>]...)]} [<псевдоним>]

Мы в этом предложении пока только использовали вариант указания имени одной-единственной таблицы. Рассмотрим соеди­ няемые таблицы:

соединяемая таблица> ::= ссы лка на таблицу> <тип соединения>

ссылка на таблицу> ON <условия поиска> | (ссылка

на таблицу>)

<тип соединения> ::= [INNER] JOIN

| {LEFT | RIGHT | FULL} OUTER JOIN

Есть внешние (OUTER) левые, правые и полные соединения, а есть внутренние (INNER) соединения. Если вид соединения не ука­ зывается, то по умолчанию предполагается внутреннее соединение.

Рассмотрим на примерах использование всех видов соеди­ нений.

5 .t. Внутренние соединения (связывание по равенству)

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

В случае полного внешнего соединения выбираются все соот­ ветствующие условию в предложении WHERE строки как левой, так и правой таблиц. Затем между ними устанавливается соответст­ вие, заданное в предложении ON.

Свяжем две таблицы, покажем все аэропорты с указанием го­ рода, где аэропорт расположен:31

SELECT * FROM AIRPORT

INNER JOIN CITY ON AIRPORT.AP CT CODE = CITY.CT CODE

Листинг 16

Результат внутреннего объединения таблиц AIROPORT и CITY - список аэропортов с указанием города расположения

APCODE

APJNAME

AP_CT_CODE

CT_CODE

CTJNAME

1

Домодедово

1

1

Москва

2

Внуково

1

1

Москва

3

Шереметьево

1

1

Москва

4

Быково

1

1

Москва

5

Пулково

2

2

С.-Петербург

6

Савино

3

3

Пермь

7

Кольцово

4

4

Екатеренбург

Данные извлекаются из таблиц AIRPORT и CITY, поскольку требуемые данные размещаются частично в одной, частично в дру­ гой таблице. Условие соединения задается после ключевого слова