Тема: «Язык запросов SQL»
План
1. Общий вид оператора выбора данных
2. Параметры команды выбора данных
3. Список полей в команде выбора данных
4. Задание условий в запросах
5. Вычисления в запросах
6. Итоговые функции в запросах
7. Группировка в запросах
8. Сортировка данных
9. Отбор данных из двух таблиц
10. Выбор данных из нескольких таблиц
11. Способы связывания таблиц
12. Объединение запросов UNION
1. Общий вид оператора Select
По большому счету вставка данных в таблицу является лишь подготовительным этапом к их использованию. В основном же работа с данными заключается в их изменении и выборке по различным критериям. Быстрая выборка данных по различным критериям является важнейшей задачей, стоящей перед любой системой управления базами данных. Если система не обеспечивает мощных и простых механизмов доступа к данным, то все остальные достоинства системы будут сведены на нет. В принципе, данные можно хранить и в текстовом файле, но поиск нужной информации, и ее обработка потребуют очень больших усилий.
Язык SQL предоставляет пользователям гибкие средства доступа к данным. В одном запросе пользователи могут сразу обращаться к множеству разнообразных источников данных, возможно расположенных на разных серверах сети.
Для выборки данных существует команда Select, которая позволяет как делать простую выборку всех данных из одной таблицы текущей базы данных, так и выполнять сложные запросы одновременно к множеству таблиц различных баз данных.
Полный синтаксис команды Select следующий:
Select [параметры] список_полей
From имя_таблицы
[Where условия]
[Group by список_полей]
[Having условия]
[Order by список_полей [ASC/DESC]]
Как видно, синтаксис команды Select может быть очень сложный. Пожалуй, команда Select является самой сложной и многофункциональной командой. Разработчиками были приложены большие усилия, чтобы сделать команду Select максимально наглядной и простой в использовании. В итоге перед пользователями предстала хорошо структурированная команда, разбитая на отдельные разделы. Каждый из разделов выполняет узкоспециализированную функцию и является практически независимым от других разделов. Пользователи могут указывать только те разделы, которые им действительно необходимы, и не вникать в логику работы остальных разделов.
Умение создавать правильные и эффективные запросы является важнейшим требованием к профессиональному разработчику.
2. Параметры команды выбора данных
С помощью параметров в команде Select можно управлять количеством и качеством строк, входящих в результат выборки. Параметры записываются сразу после ключевого слова Select через пробел и могут иметь общий вид
Select [All / Distinct]
Рассмотрим использование параметров раздела.
ALL. Это ключевое слово указывает, что в результат выборки должны быть включены все строки, возвращаемые запросом. То есть результат выборки может содержать повторяющиеся строки. Параметр ALL используется по умолчанию и его указание необязательно.
Пример. Вывести ФИО всех сотрудников предприятия.
Select All fam,
imya,
otch
From sotrudniki
или
Select fam,
imya,
otch
From sotrudniki
DISTINCT. Применение этого параметра позволяет исключить из возвращаемого результата повторяющиеся строки. Тем самым можно обеспечить уникальность каждой строки, возвращаемой запросом. Значения NULL считаются эквивалентными и включаются в выборку один раз. Если DISTINCT не указывается, то будет использоваться параметр ALL.
Пример. Вывести все фамилии сотрудников в одном экземпляре.
Select Distinct fam
From sotrudniki
Пример. Вывести все ФИО сотрудников в одном экземпляре.
Select Distinct fam,
imya,
otch
From sotrudniki
3. Список полей в команде выбора данных
После задания параметров команды SELECT формируется список столбцов, которые будут включены в результат выборки, а также значения для этих столбцов. В данном разделе оператора можно использовать следующие параметры:
Имя_столбца1 [as 'название'], Имя_столбца2 [as 'название'],. . .
Рассмотрим подробно назначение каждого из параметров:
*. Указание этого символа повлечет включение в результат выборки всех столбцов таблицы, указанной в разделе From. Порядок перечисления столбцов в результате выборки соответствует физическому порядку столбцов в таблице.
Имя_столбца. Подразумевает указание имени столбца, который должен быть включен в результат выборки. Столбец должен принадлежать таблице, указанной в разделе From. Для выборки нескольких столбцов их имена указываются через запятую. Порядок следования имен столбцов не обязательно должен совпадать с физических порядком столбцов в таблице, и может быть произвольным.
[as 'название']. С помощью этого параметра можно определять названия для столбцов. Использование псевдонимов позволяет изменять имена столбцов, под которыми они будут выведены в результат выборки, по сравнению с их первоначальными именами. С помощью псевдонимов можно лишить столбцы имен или сделать их все одинаковыми. Тем не менее, обычно псевдонимы служат для формирования в результате выборки набора столбцов с разными именами или для присваивания столбцам более понятных названий, возможно на национальном языке (в этом случае название заключается в одинарные кавычки). Также псевдонимы позволяют присваивать имена столбцам, формируемым на основе вычисления выражений. По умолчанию таким столбцам не присвоено никакого имени.
Пример. Отобрать ФИО сотрудников. Поля переименовать.
Select fam as 'Фамилия',
imya as 'Имя',
otch as 'Отчество'
From sotrudniki
Для задания условий в операторе выбора используют раздел Where условия.
Каждое условие записывается в виде
Имя_поля Операция Ключ_поиска
Операция – это одна из операций отношения:
= равно;
<>, != не равно;
> больше;
>=, !< больше или равно;
< меньше;
<=, !> меньше или равно
Ключ поиска для текстовых полей берется в одинарные кавычки, для полей типа дата/время ключ берется в кавычки и записывается в виде 'гггг-мм-дд' (MySQL) или 'дд.мм.гггг' (SQL Server) или #дд/мм/гггг# (Microsoft Access).
Пример. Отобрать ФИО сотрудников, оклад которых больше 1500 грн.
Select fam,
imya,
otch
From sotrudniki
Where oklad > 1500
Пример. Отобрать адрес и должность сотрудников, фамилия которых Иванов.
Select adres,
dolgnost
From sotrudniki
Where fam='Иванов'
Пример. Отобрать сотрудников, родившихся после июня 1970 года
Select *
From sotrudniki
Where datar>='01.07.1970'
Если по одному полю указывают несколько условий или условия задаются для нескольких полей, то их объединяют операторами AND или OR. Если оба этих оператора используются в условии, то оператор AND имеет больший приоритет.
Пример. Отобрать ФИО сотрудников, оклад которых находится между 1500 грн и 2000 грн
Select fam,
imya,
otch
From sotrudniki
Where oklad >= 1500
and oklad <= 2000
Пример. Отобрать адрес и должность сотрудников, фамилия которых Иванов и имя Сергей.
Select adres,
dolgnost
From sotrudniki
Where fam='Иванов'
and imya = 'Сергей'
Пример. Отобрать адрес и должность сотрудников, фамилия которых Иванов или Петров, а имя Сергей.
Select adres,
dolgnost
From sotrudniki
Where (fam='Иванов' or fam='Петров')
and imya = 'Сергей'
Пример. Отобрать сотрудников родившихся в 1978 году
Select *
From sotrudniki
Where datar>='01.01.1978'
and datar<='31.12.1978'
Пример. Отобрать фамилию мужчин, у которых оклад больше 2000, и женщин, у которых оклад больше 1500
Select fam
From sotrudniki
Where (pol = 'м' and oklad >2000)
or (pol = 'ж' and oklad >1500)
Функции в условиях поиска
Кроме операций отношения в условиях можно использовать функции.
between начальное_значение and конечное_значение – проверяет на вхождение в диапазон
in (значение1, …, значение n) – проверяет на равенство одному из указанных значений.
not – проверяет на неравенство.
Пример. Отобрать ФИО сотрудников, оклад которых находится между 1500 грн и 2000 грн
Select fam,
imya,
otch
From sotrudniki
Where oklad between 1500 and 2000
Пример. Отобрать сотрудников родившихся в 1978 году
Select *
From sotrudniki
Where datar between '01.01.1978' and '31.12.1978'
Пример. Отобрать сотрудников с должностями Программист, Бухгалтер, Секретарь
Select *
From sotrudniki
Where dolgnost in ('Программист', 'Бухгалтер', 'Секретарь')
Пример. Отобрать адрес и должность сотрудников, фамилия которых Иванов или Петров, а имя Сергей.
Select adres,
dolgnost
From sotrudniki
Where fam in ('Иванов', 'Петров') and imya = 'Сергей'
Пример. Отобрать сотрудников, которые не родились в 1978 году
Select *
From sotrudniki
Where datar not between '01.01.1978' and '31.12.1978'
Пример. Отобрать сотрудников с должностями кроме Программист, Бухгалтер, Секретарь
Select *
From sotrudniki
Where dolgnost not in ('Программист', 'Бухгалтер', 'Секретарь')
Поиск пустых значений в поле
Если в поле допускается хранение значений NULL то проверить его на равенство можно c помощью записи:
поле is null – поле пустое;
поле is not null – поле не пустое
Пример. Вывести список сотрудников, у которых адрес не заполненный.
Поле может быть не заполненным, если его не заполняли вообще (null) или его заполнили, а потом значение удалили ('' - пустой символ)
Select *
From sotrudniki
Where adres is null or adres = ''
Функция Like
Данная функция позволяет выполнить поиск по текстовым полям используя символ постановки.
% - любая последовательность
_(подчеркивание) - любой символ
\ - указывает, что следующий специальный символ нужно понимать как часть условия поиска
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А'
Select *
From sotrudniki
Where fam like 'a%'
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А', заканчивается на 'ко'.
Select *
From sotrudniki
Where fam like 'а%ko'
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А', заканчивается на 'ко' и состоит из 6 букв
Select *
From sotrudniki
Where fam like 'а_ _ _ko'
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А' или 'Р' или 'Т' и заканчивается на 'ко'.
Select *
From sotrudniki
Where fam like 'а%ко'
or fam like 'р%ко'
or fam like 'т%ко'
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А' или 'Р' или 'Т' и не заканчивается на 'ко'.
Select *
From sotrudniki
Where (fam like 'а%'
or fam like 'р%'
or fam like 'т%')
and fam not like '%ко'
В данном запросе скобки ставить не обязательно, но поставим их для упрощения чтения условия отбора.
Пример. Вывести список сотрудников, у которых фамилия начинается на 'А', заканчивается на 'ко', состоит из 6 букв и третья буква или 'к', или 'р', или 'с'
Select *
From sotrudniki
Where fam like 'a_k_ko'
or fam like 'a_p_ko'
or fam like 'a_c_ko'
Пример. Вывести сотрудников, у которых логин содержит символы 'a_a'. Обратите внимание, что условие поиска содержит знак подчеркивания, который является специальным символом. Чтобы этот символ понимался как часть условия, его нужно маскировать символом '\'
Select *
From sotrudniki
Where login like '%a\_a%'
5. Вычисления в запросах
При создании запроса в списке полей могут указываться формулы. Формула может содержать знаки операций (+, -, *, /), числа, скобки и имена др. полей.
По умолчанию такое вычисляемое поле будет безымянным, поэтому для него нужно явно указывать имя.
Пример. Вывести ФИО, оклад сотрудников, и премию как 20% от оклада.
Select fam as 'Фамилия',
imya as 'Имя',
otch as 'Отчество',
oklad as 'Оклад',
oklad * 0.2 as 'Премия'
From sotrudniki
Пример. Пусть имеются данные о товаре: название и цена в у.е. Вывести название, цену в у.е., цену в гривнах, цену в гривнах с НДС (+20%). Отобразить данные тех записей, у которых цена в у.е. >100
Select nazv as 'Наименование товара',
cena as 'Цена в у.е',
cena*5.05 as 'Цена в грн',
cena*5.05 +cena*5.05*0.2 as 'Цена в грн с Ндс'
From tovary
Where cena >100
Пример. Пусть имеется таблица students с информацией о студентах. Вывести на экран фамилию, имя и стипендию студентов. Стипендия рассчитывается по формуле: средний балл*100.
Select fam,
imya,
srbal*100 as stip
From students
Функция Case в запросах
Данная функция также используется для создания вычисляемых полей. Она позволяет организовать вывод в поле разных значений в зависимости от условий. Функция имеет вид:
Case When условие1 Then вывод, если выполнилось
When условие2 Then вывод, если выполнилось
. . .
When условиеn Then вывод, если выполнилось
Else вывод, если не выполнилось
End
Пример: Для каждого сотрудника рассчитать премию по формуле:
- 20% оклада для женщин;
- 15% оклада для мужчин.
Select fam,
imya,
case when pol= 'м' then oklad *0.15
else oklad*0.2 end as prem
From sotrudniki
Пусть имеется таблица студентов со средними баллами. Для каждого студента выбрать фамилию, имя и размер стипендии. Стипендия рассчитывается по формуле:
1500 – средний балл 5;
1300 – средний балл от 4 и выше;
0 – средний балл ниже 4.
Стипендию получают только те студенты, у которых форма финансирования = "Бюджет".
Select fam,
imya,
otch,
case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end as stip
From students
6. Итоговые функции в запросах
В языке SQL имеются специальные функции позволяющие получать общие показатели по таблице:
count(*) – количество записей в таблице
count(поле) – количество не пустых значений (не null) в поле
sum(поле) – сумма
avg(поле) – среднее
minполе) – минимальное
max(поле) – максимальное
Запросы с функциями всегда возвращают одну запись, в которой каждая колонка отображает расчитанный результат.
Пример. Определить на предприятии общее число сотрудников и их ср оклад.
Select count(*) as 'Всего работников',
avg(oklad) as 'Средний оклад'
From sotrudniki
Пример. Определить средний размер премии на предприятии у сотрудников мужчин.
select avg(oklad*0.2) as 'Средняя премия'
From sotrudniki
Where pol='м'
В списке полей запроса можно использовать текстовые константы в одинарных кавычках. Это позволяет выдавать результат в виде логически связанных фраз.
Select 'Общее число сотрудников: ', count (*),
'. Их средний оклад: ', avg(oklad)
From sotrudniki
Внутри итоговых функций могут использоваться сложные формулы.
Определить среднюю стипендию по учебному заведению (см. запрос расчета стипендии).
Select avg(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as sredstip
From students
Определить суммарную стипендию по учебному заведению (см. запрос расчета стипендии).
Select sum(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as sumstip
From students
7. Группировка данных
С помощью группировки можно подсчитать итоговые показатели не по всей таблице, а по отдельным группам. Группировка чаще всего используется вместе c агрегирующими функциями.
Для выполнения группировки необходимо:
- в списке полей запроса перечисляют те поля, по которым нужно выполнить группировку, а также нужные агрегирующие функции для расчета;
- в разделе Group by запроса указывают все поля из списка полей с соблюдением их порядка следования.
Пример. Рассчитать среднюю, максимальную и минимальную стипендию в каждой группе учебного заведения. Предположим, что стипендия расчитывается по формуле: ср.балл * 300, и ее получают студенты со средним баллом от 4 и выше, и обучающиеся на бюджете.
Select grupa,
avg(srbal*300) as 'Ср. стипендия',
max(srbal*300) as 'Макс. стипендия',
min(srbal*300) as 'Мин. стипендия'
From students
Where srbal>=4
and finance='Бюджет'
Group by grupa
Пример. Усовершенствуем запрос: подсчитаем эти же показатели по группам и полу в каждой группе.
Select grupa,
pol,
avg(srbal*100) as 'Ср. стипендия',
max(srbal*120) as 'Макс. стипендия',
min(srbal*120) as 'Мин. стипендия'
From students
Where srbal>=4
and finance='Бюджет'
Group by grupa, pol
Пример. Усовершенствуем запрос. Пусть стипендия рассчитывается по формуле:
1500 – средний балл 5;
1300 – средний балл от 4 и выше;
0 – средний балл ниже 4.
Стипендию получают только те студенты, у которых форма финансирования = "Бюджет".
Select grupa,
pol,
avg(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as 'Ср. стипендия',
max(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as 'Макс. стипендия',
min(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as 'Мин. стипендия'
From students
Group by grupa, pol
Замечание. В качестве группировки могут использоваться поля, в которых есть повторяющиеся значения. В противном случае группировка не имеет смысла.
Отбор по группам
Если на группы или их функции накладываются ограничения, то эти ограничения задаются в специальном разделе Having условия.
Пример. Подсчитать количество студентов и среднюю стипендию по каждой из групп: 18, 21, 37. Пусть стипендия рассчитывается по формуле:
1500 – средний балл 5;
1300 – средний балл от 4 и выше;
0 – средний балл ниже 4.
Стипендию получают только те студенты, у которых форма финансирования = "Бюджет".
Отсортировать данные по количеству студентов в порядке убывания.
Select grupa,
count(*) as kolstud,
avg(case when srbal=5 and finance='Бюджет' then 1500
when srbal>=4 and finance='Бюджет' 1300
else 0 end) as sredstip
From students
Group by grupa
Having grupa like '18%'
or grupa like '21%'
or grupa like '37%'
Order by kolstud desc
В разделе Having можно использовать не только поля, по которым выполняется группировка, но и значения рассчитываемых функций.
Пример. Вывести список групп и количество студентов в них. Показать только те группы, в которых найденное количество больше 25.
Select grupa,
count(*) as kolstud
From students
Group by grupa
Having kolstud>25
Если в разделе Having используется функция, то ее необязательно указывать в списке вывода запроса. В этом случае функция не будет иметь имени и ее придется записать полностью при задании условия.
Пример. Изменим предыдущий запрос: выведем только названия групп с количеством студентов больше 25 (само количество выводить нет будем).
Select grupa
From students
Group by grupa
Having count(*)>25
Замечания.
Поле, которое указано в разделе Group by, не может использоваться в разделе Where, но может использоваться в разделе Having.
Агрегирующие функции не могут использоваться в разделе Where, но могут использоваться в разделе Having.
Для упорядочивания данных в запросах используют параметр:
Order by поле1 [ASC / DESC], поле2 [ASC / DESC], . . .
Допускается указывать несколько полей через запятую. Параметр ASC указывает на то, что данные в поле сортируются по возрастанию. Данный параметр срабатывает по умолчанию и его указывать не обязательно. Для сортировки по убыванию указывают параметр DESC
Пример: Отобрать ФИО сотрудников с должностью Программист и стажем работы больше 5 лет. Данные отсортировать по фамилии.
Select fam,
imya,
otch
From sotrudniki
Where dolgnost = 'программист'
and stag>5
Order by fam
Пример: Отобрать ФИО сотрудниц, родившихся в 1970 году. Отсортировать по дате рождения по убыванию и по фамилии по возрастанию.
Select fam,
imya,
otch
From sotrudniki
Where pol='ж'
and datar between '01.01.1970' and '31.12.1970'
Order by datar DESC, fam
Пример: Отобрать ФИО сотрудников и сумму их премии (20% от оклада). Отсортировать по фамилии по возрастанию и по премии по убыванию.
Select fam,
imya,
otch,
oklad*0.2 as prem
From sotrudniki
Order by fam, prem DESC
Допускается при сортировке указывать не имена полей, а их порядковые номера в списке выбора. Запишем предыдущий запрос сортировкой по номерам полей (обратите внимание, что поле fam имеет порядковый номер 1, а поле prem – номер 4).
Select fam,
imya,
otch,
oklad*0.2 as prem
From sotrudniki
Order by 1, 4 DESC
Допускается указывать псевдонимы полей, если они были происвоены в запросе.
Select fam as f,
imya as i,
otch as o,
oklad*0.2 as prem
From sotrudniki
Order by f, prem DESC
Допускается при сортировке использовать комбинирование разных типов записи поля.
Select fam as f,
imya as i,
otch as o,
oklad*0.2 as prem
From sotrudniki
Order by f, imya, 4 DESC
9. Отбор данных из двух таблиц
Реальные БД состоят из нескольких таблиц, связанных между собой с помощью внешних ключей. Запрос по нескольким таблицам имеет ряд особенностей:
- в списке полей перечисляются все поля из всех нужных таблиц. Если несколько таблиц имеют поля с одним именем, то имя поля записывается так:
имя_таблицы.имя_поля;
- в разделе From таблицы записываются так:
таблица1 inner join таблица2
- вместо раздела Where указывают раздел On, в котором обязательно указывают условие связывания таблиц:
талица1.поле=таблица2.поле
Далее в разделе Where указываются другие условия
Пример. Пусть имеются таблицы students (id_stud, fam, imya, otch, datar) и ocenki (id_ocenka, predmet, ocenka, id_stud), связанные по полю id_stud.
Пример. Вывести список студентов и их оценки по математике. Данные отсортировать по фамилии.
Select fam,
imya,
otch,
ocenka
From students inner join ocenki
On students.id_stud=ocenki.id_stud
Where predmet='Математика'
Order by fam
Пример. Вывести код студента, фамилию, имя, оценку по физике для всех студентов. В этом запросе поле id_stud имеется в обеих таблицах, поэтому при его указании нужно также указать, из какой именно таблицы показать поле.
Select students.id_stud,
fam,
imya,
ocenka
From students inner join ocenki
On students.id_stud=ocenki.id_stud
Where predmet='Физика'
Если таблицы имеют длинные названия, то указывать эти имена в запросах становится накладно и размер текста запроса значительно увеличивается. Запрос можно сократить за счет применения псевдонимов: каждой таблице в разделе From присваивается сокращенное обозначение и затем оно используется в тексте запроса.
Пример. Запишем предыдущий запрос через псевдоним
Select a.id_stud,
fam,
imya,
ocenka
From students as a inner join ocenki as b
On a.id_stud=b.id_stud
Where predmet='Физика'
Пример. Для каждого студента рассчитать его средний балл.
Select fam,
imya,
avg(ocenka) as srbal
From students as a inner join ocenki as b
On a.id_stud=b.id_stud
Group by fam, imya
Пример. Вывести список студентов, у которых средний балл 4 и выше.
Select fam,
imya
From students as a inner join ocenki as b
On a.id_stud=b.id_stud
Group by fam, imya
Having avg(ocenka)>=4
10. Выбор данных из нескольких таблиц
Рассмотренный пример включал только две таблицы, которые не в полной мере описывают предметную область "Учебное заведение". Также в учебном заведении имеются группы, специальности, отделения.
Для построения реальных составных запросов предположим, что у нас имеется БД учебного заведения с таблицами:
- otdelen (id_otd, nazv_otd, zav_otd) - отделения
- spec (id_spec, id_otd, nazv_spec) - специальности
- grupy (id_grup, id_spec, nazv_grup, kl_ruk) - группы
- students (id_stud, id_grup, fam, imya, otch, datar, pol, finance) - студенты
- ocenki (id_oc, id_stud, predmet, ocenka) - оценки
При построении запроса по более чем двум таблицам раздел from записывается так:
from табл1 inner join Табл2 on табл1.поле=табл2.поле
inner join Табл3 on табл2.поле=табл3.поле
inner join Табл4 on табл3.поле=табл4.поле и т.д.
Пример. Определить количество студентов на каждом отделении.
Select nazv_otd,
count(students.id_stud) as kol_stud
From otdelen as a inner join spec as b on a.id_otd=b.id_otd
inner join grupy as c on b.id_spec=c.id_spec
inner join students as d on c.id_stud=d.id_stud
Group by nazv_otd
Обратите внимание: если запрос строится по нескольким таблицам, то для подсчета количества записей в таблице нельзя использовать функцию
count(*), так как не понятно, по какой именно таблице выполняется расчет. В этом случае используют запись count(таблица.ключевое_поле).
Пример. Для каждой специальности подсчитать количество студентов, у которых по физике оценка 4.
Select nazv_spec,
count(students.id_stud) as kol_stud
From spec as a inner join grupy as b on a.id_spec=b.id_spec
inner join students as c on b.id_grup=c.grup
inner join ocenki as d on c.id_stud=d.id_stud
Where predmet='Физика' and ocenka>=4
Group by nazv_spec
Пример. Для каждой группы вывести количество парней и девушек.
Select nazv_grup,pol,
cout(students.id_stud) as kol_stud
From grupy as a inner join students as b on a.id_grup=b.id_grup
Group by nazv_grup, pol
Пример. Вывести список групп, в которых количество девушек больше 10.
Select nazv_grup
From grupy as a inner join students as b
On a.id_grup=b.id_grup
Where pol='ж'
Group by nazv_grup
Having count(students.id_stud)>10
11. Способы связывания таблиц
Наиболее часто при связывании таблиц используют операцию внутреннего связывания inner join.
Данная операция говорит, что выводится результат "пересечения" двух таблиц. То есть выводятся данные, которые есть во всех таблицах, участвующие в запросе.
Например, если отобрать оценки всех студентов по математике с помощью запроса вида:
Select fam,
imya,
otch,
ocenka
From students inner join ocenki
On students.id_stud=ocenki.id_stud
Where predmet='Математика'
Order by fam
то на экране появится список тех студентов, у которых оценка по математикем" есть. Если же студент не имеет оценки по математике, то он показан не будет, что может ввести пользователя в заблуждение, будто такого студента нет в группе вообще.
В данной задаче целесообразнее показать всех студентов группы из главной таблицы. Оценки же появятся только у тех записей, для которых они введены. Для остальных записей оценка будет равна NULL. То есть будет понятно, что пока оценки нет, но студент виден и он существует.
Запрос, в котором левая таблица должна отобразиться полностью, реализуется с помощью операции "левого связывания" left outer join.
В нашем случае запрос имеет вид:
Select fam,
imya,
otch,
ocenka
From students left outer join ocenki
On students.id_stud=ocenki.id_stud
Where predmet='Математика'
Order by fam
Реже встречается обратная операция, когда из подчиненной таблицы (правой) отбираются все записи, а из главной только связанные. Такое связывание реализуют с помощью операции right outer join
В нашем случае, если поменять таблицы местами, то запрос запишется так:
Select fam,
imya,
otch,
ocenka
From ocenki right outer join students
On students.id_stud=ocenki.id_stud
Where predmet='Математика'
Order by fam
Существует еще один тип связи, при котором из обеих таблиц отбираются все записи без учета наличия связанны записей как в левой, так и в правой таблицах. Такое связывание реализуют с помощью операции full outer join.
Select fam,
imya,
otch,
ocenka
From ocenki full outer join students
On students.id_stud=ocenki.id_stud
Where predmet='Математика'
Order by fam
12. Объединение запросов UNION
Существует возможность объединения данных из нескольких запросов в один общий набор данных. При этом объединяемые запросы должны полностью совпадать по количеству и типу возвращаемых запросами полей. Команда объединения имеет вид:
запрос1
union
запрос2
[where условие]
[order by поля]
Обратите внимание, что объединяемые запросы кроме отдельных условий отбора могут иметь общий раздел where после операции объединения. Более того, объединяемые запросы автоматически сортируются по всем полям и не должны иметь своих отдельных разделов сортировки. Если хотите изменить порядок сортировки, то используйте общий раздел order by.
Пример. Отобрать фамилию, имя, отчество студентов, а затем фамилию, имя, отчество студенток.
select fam, imya, otch from stud where pol='м'
union
select fam, imya, otch from stud where pol='ж'
Данный пример также может быть решен с помощью одного запроса с составным условием (where pol='м' or pol='ж').
Операция union не только объединяет два запроса, но и автоматически сортирует результирующий набор данных по всем его полям по возрастанию.
Часто такая операция используется для получения соединения full outer join в тех СУБД, где такое соединение не поддерживается (Acces, MySQL, SQLite). Данное соединение можно получить, объединив запрос с left outer join и с right outer join.
Пример. Пусть имеется запрос с полным связыванием таблиц
Select fam,
imya,
otch,
ocenka
From ocenki full outer join students
On students.id_stud=ocenki.id_stud
Order by fam
Необходимо переписать его с помощью объединения запросов для СУБД, в которой полное связывание не поддерживается.
Select fam,
imya,
otch,
ocenka
From ocenki left outer join students
On students.id_stud=ocenki.id_stud
union
Select fam,
imya,
otch,
ocenka
From ocenki right outer join students
On students.id_stud=ocenki.id_stud
Order by fam
Вопросы для самоконтроля
1. Приведите команду SQL для выборки данных из таблицы.
2. Какие параметры запроса выборки данных из таблицы вы знаете?
3. Опишите как задается список полей в запросе выборки данных из таблицы.
4. Как задаются условия по полям разных типов в запросе выборки данных из таблицы.
5. Как использовать формулы в запросе выборки данных из таблицы. Опишите применение функции Case.
6. Какие итоговые функции можно использовать в запросах выборки данных из таблицы?
7. Для чего задается группировка. Как задать группировку в запросах?
8. Как выполнить поиск по сгруппированным данным в запросах?
9. Как выполнить сортировку отобранных данных в запросах?
10. Какие правила используют при создании запроса по нескольким таблицам? Для чего создают псевдонимы таблиц?
11. Какие способы связывания таблиц в запросах вы знаете?
12. Опишите принцп объединения нескольких запросов в одном наборе данных.
13. Как организовать полное связывание таблиц (FULL OUTER JOIN) в СУБД, которые такого параметра связывания не имеют?