Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бд ответы.docx
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
459.25 Кб
Скачать

18.Структура оператора select.

Оператор SELECT

Оператор SELECT применяется для извлечения строк, выбранных из одной или нескольких таблиц. То есть с его помощью мы задаем столбцы или выражения, которые надо извлечь (select_выражения), таблицы (table_references), из которых должна производиться выборка, и, возможно, условие (where_definition), которому должны соответствовать данные в этих столбцах, и порядок, в котором эти данные нужно выдать.

Кроме того, оператор SELECT можно использовать для извлечения строк, вычисленных без ссылки на какую-либо таблицу. Например, чтобы вычислить, чему равно 2*2, нужно просто написать

mysql> SELECT 2*2;

Упрощенно структуру оператора SELECT можно представить следующим образом:

SELECT select_выражение1, select_выражение2, ... [FROM table_references [WHERE where_definition] [ORDER BY {число | имя_столбца | формула} [ASC | DESC], ...]]

Квадратные скобки [ ] означают, что использование находящегося в них оператора необязательно, вертикальная черта | означает перечисление возможных вариантов. После ключевого слова ORDER BY указывают имя столбца, число (целое беззнаковое) или формулу и способ упорядочения (по возрастанию – ASC, или по убыванию – DESC). По умолчанию используется упорядочение по возрастанию.

Когда в select_выражении мы пишем «*», это значит выбрать все столбцы. Кроме «*» в select_выражения могут использоваться функции типа max, min и avg.

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

Предложение HAVING применяется, чтобы задать условия поиска для групп или для агрегатной функции. Предложение HAVING чаще всего используется после предложения GROUP BY в случаях, когда условие поискадолжно проверяться уже после группировки результатов. Если условие поиска можно было бы проверить до группировки, то гораздо эффективней было бы поместить его в предложение WHERE, а не пользоваться предложением HAVING (за счет этого уменьшилось бы количество строк, участвующих в группировке). Если предложение GROUP BY отсутствует, то HAVING может применяться только в отношении агрегатной функции в списке выборки. В этом случае предложение HAVING действует точно так же, как предложение WHERE. Если попытаться использовать HAVING как-нибудь по-другому, то SQL Server выдаст сообщение об ошибке.

Предложение HAVING имеет такой синтаксис:

HAVING <условие_поиска>

Здесь условие_поиска имеет такой же смысл, что и условие поиска. (См. раздел "Предложение WHERE и условие поиска" выше в данной лекции). Единственным различием между предложениями HAVING и WHERE является то, что предложение HAVING может содержать агрегатную функцию в условии поиска, а предложение WHERE – нет.

П римечание. Агрегатные функции можно применять в предложениях SELECT и HAVING, но не в предложенииWHERE.

Ниже приведен пример запроса, использующего предложение HAVING для поиска книг, сгруппированных по типам и по издательствам, средняя цена на которые превышает 15 долларов:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

HAVING AVG(price) > 15.00

GO

В набор результатов попадут 4 строки:

type pub_id Средняя цена

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

psychology 0877 21.59

trad_cook 0877 15.96

business 1389 17.31

popular_comp 1389 21.48

В предложениях HAVING можно употреблять логические операции. Ниже показан несколько измененный последний пример, в нем теперь применяется логическая операция AND:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

HAVING AVG(price) >= 15.00 AND

AVG(price) <= 20.00

GO

В набор результатов попадут 2 строки:

type pub_id Средняя цена

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

trad_cook 0877 15.96

business 1389 17.31

Такой же результат получится, если вместо AND применить предложение BETWEEN, вот так:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

HAVING AVG(price) BETWEEN 15.00 AND 20.00

GO

Чтобы применять HAVING без предложения GROUP BY, нужно иметь агрегатную функцию в списке выборки и в предложении HAVING. Например, чтобы выводить сумму цен на книги типа mod_cook (современная кулинария), только в тех случаях, когда эта сумма будет превышать 20 долларов, можно применять такой запрос:

SELECT SUM(price)

FROM titles

WHERE type = "mod_cook"

HAVING SUM(price) > 20

GO

Если в этом запросе поместить выражение SUM(price) > 20 в предложение WHERE, то SQL Server выдаст сообщение об ошибке, т.к. в предложениях WHEREагрегатные функции применять нельзя.

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

Предложение ORDER BY

Предложение ORDER BY применяется, чтобы задать порядок, в котором должны сортироваться строки набора результатов. Пользуясь ключевыми словамиASC и DESC, вы можете задать как возрастающий (ascending, от меньших значений к большим), так и убывающий (descending, от больших значений к меньшим) порядок сортировки. Если порядок сортировки не указать, то по умолчанию будет применяться возрастающий порядок сортировки. В предложении ORDER BY можно задать более одной колонки. Результаты будут сортироваться по первой из заданных колонок, но если в первой колонке встретятся строки с одинаковыми значениями, то они будут сортироваться в порядке возрастания значения из второй колонки, и т.д. Как вы увидите из материала данного раздела, такая сортировка особенно полезна при использовании вместе с предложением GROUP BY. Давайте сначала рассмотрим пример, в котором предложение ORDER BY работает с одной колонкой и сортирует список авторов по фамилии , в возрастающем порядке:

SELECT au_lname, au_fname

FROM authors

ORDER BY au_lname ASC

GO

Набор результатов будет отсортирован в алфавитном порядке по фамилиям авторов. Не забудьте, что чувствительность сортировки к регистру букв, заданная вами при инсталляции SQL Server, повлияет на обработку фамилий вроде "del Castillo".

Если вы хотите отсортировать результаты для более чем одной колонки, то просто добавьте в предложение ORDER BY имена колонок, разделяя их запятыми. Ниже приведен пример запроса, выдающего идентификаторы должностей, фамилии и имена сотрудников, сортирующего вывод сначала по идентификатору должности, затем по фамилии, а затем по имени:

SELECT job_id, lname, fname

FROM employee

ORDER BY job_id, lname, fname

GO

Набор результатов (43 строки) будет выглядеть так:

job_id lname fname

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

2 Cramer Philip

3 Devon Ann

4 Chang Francisco

5 Henriot Paul

5 Hernadez Carlos

5 Labrune Janine

5 Lebihan Laurence

5 Muller Rita

5 Ottlieb Sven

5 Pontes Maria

6 Ashworth Victoria

6 Karttunen Matti

6 Roel Diego

6 Roulet Annette

7 Brown Lesley

7 Ibsen Palle

7 Larsson Maria

7 Nagy Helvetius

. . .

. . .

. . .

13 Accorti Paolo

13 O’Rourke Timothy

13 Schmitt Carine

14 Afonso Pedro

14 Josephs Karin

14 Lincoln Elizabeth

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

А теперь давайте рассмотрим предложение ORDER BY, работающее совместно с предложением GROUP BY и агрегатной функцией:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

ORDER BY Средняя цена

GO

Набор результатов (8 строк) будет выглядеть так:

type pub_id Средняя цена

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

UNDECIDED 0877 NULL

business 0736 2.99

business 1389 17.31

mod_cook 0877 11.49

popular_comp 1389 21.48

psychology 0736 11.48

psychology 0877 21.59

trad_cook 0877 15.96

Результаты отсортированы в алфавитном порядке (возрастающем) по типу книг. Также обратите внимание, что в этом запросе в предложении GROUP BYдолжны присутствовать и type, и pub_id, потому что они не являются частью агрегатной функции. Если вы не зададите колонку pub_id в предложенииGROUP BY, то SQL Server выдаст сообщение об ошибке (рис. 14.4).

В предложении ORDER BY нельзя применять агрегатные функции и подзапросы. Однако если вы зададите алиас агрегатной функции в предложении SELECT, то его применить можно в предложении ORDER BY, вот так:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

ORDER BY type

GO

Предложение GROUP BY

Предложение GROUP BY применяется после предложения WHERE и означает, что строки набора результатов должны быть сгруппированы в соответствии с данными в колонке группировки. Если в предложении SELECT используетсяагрегатная функция, то для каждой группы вычисляется и отображается в выводе итоговое агрегатное значение.Агрегатная функция выполняет вычисления и возвращает значение. (Про агрегатные функции см. раздел "Агрегатные функции" далее.)

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

Предложение GROUP BY особенно полезно, когда в предложении SELECT имеется агрегатная функция. Давайте рассмотрим пример оператора SELECT, применяющего предложение GROUP BY для получения сведений об общем количестве проданных книг для каждого из названий книг:

SELECT title_id, SUM(qty)

FROM sales

GROUP BY title_id

GO

Будет выдан набор результатов, содержащий 16 строк:

title_id

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

BU1032 15

BU1111 25

BU2075 35

BU7832 15

MC2222 10

MC3021 40

PC1035 30

PC8888 50

PS1372 20

PS2091 108

PS2106 25

PS3333 15

PS7777 25

TC3218 40

TC4203 20

TC7777 20

Этот запрос не содержит предложения WHERE – оно не нужно. Набор результатов состоит из колонки title_id (идентификатор названия книги) и итоговой колонки, не имеющей заголовка. Для каждого отдельного названия книги будет подсчитано общее количество экземпляров этой книги, это число будет показано в итоговой колонке. Например, пусть значение BU1032 колонки title_id встретится в таблице sales (продажи) два раза, первый раз оно будет обозначать продажу 5 экземпляров книги (колонка qty будет иметь значение 5), а во второй раз будет обозначать продажу книг по другому заказу, на этот раз будет продано 10 экземпляров книги. Агрегатная функция SUM произведет суммирование этих двух продаж, отсюда и получится, что общее количество проданных экземпляров равно 15, что и будет показано в итоговой колонке. Если вы хотите, чтобы итоговая колонка имела заголовок, воспользуйтесь ключевым словом AS, вот так:

SELECT title_id, SUM(qty) AS "Колич прод"

FROM sales

GROUP BY title_id

GO

Теперь набор результатов станет показывать заголовок для итоговой колонки (в наборе результатов содержится 16 строк):

itle_id Колич прод

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

BU1032 15

BU1111 25

BU2075 35

BU7832 15

MC2222 10

MC3021 40

PC1035 30

PC8888 50

PS1372 20

PS2091 108

PS2106 25

PS3333 15

PS7777 25

TC3218 40

TC4203 20

TC7777 20

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

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

GROUP BY type, pub_id

GO

В набор результатов попадут 8 строк:

type pub_id Средняя цена

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

business 0736 2.99

psychology 0736 11.48

UNDECIDED 0877 NULL

mod_cook 0877 11.49

psychology 0877 21.59

trad_cook 0877 15.96

business 1389 17.31

popular_comp 1389 21.48

Обратите внимание, что книги, имеющие тип psychology и business, попали в набор результатов более одного раза, потому что они сгруппированы для разных идентификаторов издательств. Значение NULL, показанное в качестве средней цены книг типа UNDECIDED (нераспределенные), отражает тот факт, что для книг этого типа в таблицу не были введены их цены, поэтому невозможно вычислить среднюю цену.

Предложение GROUP BY можно применять с необязательным ключевым словом ALL, означающим, что в набор результатов должны быть включены все группы, даже не соответствующие условию поиска. Группы, не имеющие строк, соответствующих условию поиска, будут содержать в итоговой колонке значение NULL, поэтому их будет сразу видно. Например, чтобы узнать среднюю цену для книг, имеющих авторские отчисления 12%, а также показать в наборе результатов строки для книг, имеющих авторские отчисления не 12% (у них в итоговой колонке будет значение NULL), группируя книги сначала по типам, а затем по идентификатору издательства, выполните такой запрос:

SELECT type, pub_id, AVG(price) AS "Средняя цена"

FROM titles

WHERE royalty = 12

GROUP BY ALL type, pub_id

GO

В набор результатов попадут 8 строк:

type pub_id Средняя цена

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

business 0736 NULL

psychology 0736 10.95

UNDECIDED 0877 NULL

mod_cook 0877 19.99

psychology 0877 NULL

trad_cook 0877 NULL

business 1389 NULL

popular_comp 1389 NULL

Будут выведены строки для всех типов книг, но для типов книг, у которых не имеется книг с 12-процентными авторскими отчислениями, появится NULL.

Если мы уберем ключевое слово ALL, то набор результатов будет содержать информацию только для тех типов книг, у которых имеются книги с 12-процентными авторскими отчислениями. Набор результатов будет содержать 2 строки и будет таким:

type pub_id Средняя цена

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

psychology 0736 10.95

mod_cook 0877 19.99

Предложение GROUP BY часто применяется в сочетании с предложением HAVING, про которое мы сейчас вам расскажем.

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