Практикум по языку SQL. Учебное пособие
.pdf
Подзадача 2
Найти множество городов, куда выполнили поставки поставщики зеленых деталей.
Информация о городах изделий хранится в таблице j, столбец town. Присоединим к каждой строке таблицы spj соответствующую номеру изделия строку из таблицы изделий j. Выберем только строки, где поставщик – один из найденных запросом из подзадачи 1, и выведем только значение столбца j.town (город) без повторов:
Запрос:
select distinct j1.town from spj t
join j j1 on j1.n_izd=t.n_izd where t.n_post in ( select n_post
from spj a
join p on p.n_det=a.n_det where p.cvet='Зеленый')
Подзадача 3
Результат запроса:
town
Лондон Афины Рим
Найти множество городов, куда могут быть сделаны поставки.
Для этого нужно вывести без повторений города (столбец town) из таблицы j.
Запрос: |
Результат запроса: |
||
select distinct j.town |
|
|
|
|
town |
|
|
from j |
|
|
|
|
Афины |
|
|
|
|
|
|
|
|
Лондон |
|
|
|
Осло |
|
|
|
Париж |
|
|
|
Рим |
|
Окончательный запрос
Выбрать города, в которые не делал поставок ни один поставщик, поставлявший зеленые детали.
Осталось найти разность запросов подзадачи 3 и подзадачи 2.
Запрос: |
Результат запроса: |
|||
select town |
|
|
|
|
|
town |
|
||
from j |
|
|
||
|
Париж |
|
||
except |
|
|
|
|
|
|
Осло |
|
|
select j1.town |
|
|
||
|
|
|
||
51
from spj t
join j j1 on j1.n_izd = t.n_izd where t.n_post in ( select n_post
from spj a
join p on p.n_det=a.n_det where p.cvet='Зеленый')
Задание для самостоятельной работы
Выбрать детали, не поставлявшиеся ни для одного из изделий, для которых поставлял детали поставщик S3.
ПРИМЕР 15 (Лабораторная работа 4 – задание 3)
Найти поставщиков, имеющих поставки, вес которых составляет менее 20 % от максимального веса поставки красной детали, выполненной этим поставщиком. Вывести номер поставщика, вес поставки, максимальный вес поставки красной детали, сделанной поставщиком.
Анализ задания
Для каждого поставщика нужно отобрать поставки деталей красного цвета.
Найти вес каждой из этих поставок и определить наибольшую среди этих величин (наибольший вес).
Для каждого поставщика этот наибольший вес будет свой.
Затем для каждого поставщика сравнить вес каждой его поставки с найденным наибольшим весом, деленным на 5 (т. е. с 20 % от наибольшего веса). Если вес поставки меньше, включить информацию о поставке в результат, если больше или равен – не включать.
Подзадача 1
Вывести поставки деталей красного цвета и для каждой поставки определить ее вес.
Информация о поставках хранится в таблице spj, информация о деталях хранится в таблице p, нам нужны столбцы cvet и ves. Используем секцию join, чтобы присоединить к каждой строке таблицы spj соответствующую номеру детали строку из таблицы деталей p. Выберем только те поставки, где цвет детали – красный, и добавим в целевой список выражение для вычисления веса поставки.
52
Запрос: |
Результат запроса: |
|
|
|
||||||
select t.*, |
t.kol*p.ves pves |
|
|
|
|
|
|
|
||
|
n_post |
n_det |
n_izd |
kol |
pves |
|||||
from spj t |
||||||||||
S1 |
P1 |
|
J4 |
700 |
8400 |
|||||
join p on p.n_det=t.n_det |
|
|
||||||||
|
S1 |
P1 |
|
J1 |
200 |
2400 |
||||
where |
p.cvet='Красный' |
|
|
|||||||
|
S3 |
P4 |
|
J2 |
500 |
7000 |
||||
|
|
|
|
|
||||||
|
|
|
|
S4 |
P6 |
|
J7 |
300 |
5700 |
|
|
|
|
|
S4 |
P6 |
|
J3 |
300 |
5700 |
|
|
|
|
|
S5 |
P1 |
|
J4 |
100 |
1200 |
|
|
|
|
|
S5 |
P4 |
|
J4 |
800 |
11200 |
|
|
|
|
|
S5 |
P6 |
|
J2 |
200 |
3800 |
|
|
|
|
|
S5 |
P6 |
|
J4 |
500 |
9500 |
|
Выражениям в целевом списке рекомендуется всегда присваивать псевдонимы, в данном случае выражение t.kol*p.ves обозначено псевдонимом pves.
Подзадача 2
Найти для каждого поставщика максимальный вес поставки красной детали.
Полученный в предыдущей подзадаче список нужно разделить на группы (отдельная группа для каждого поставщика) и выбрать наибольшее значение в столбце pves в каждой группе. Чтобы разбить список на группы, в запросе следует использовать секцию group by, а для нахождения наибольшего значения – функцию max.
Запрос:
select t.n_post, max(t.kol*p.ves) mves from spj t
join p on p.n_det=t.n_det where p.cvet='Красный' group by t.n_post
Подзадача 3
Результат запроса:
n_post |
mves |
S1 |
8400 |
S3 |
7000 |
S4 |
5700 |
S5 |
11200 |
Для каждой поставки вывести номер поставщика, вес поставки, максимальный вес поставки красной детали, сделанной поставщиком.
К каждой строке таблицы spj, помимо соответствующей номеру детали строки из таблицы деталей p, присоединим строку из запроса подзадачи 2 по соответствию номера поставщика. Для этого запрос из подзадачи 2 возьмем в скобки, зададим ему псевдоним b.
53
Запрос:
select a.n_post, a.kol*pa.ves pves, b.mves from spj a
join p pa on pa.n_det=a.n_det
join ( select t.n_post, max(t.kol*p.ves) mves from spj t
join p on p.n_det=t.n_det where p.cvet='Красный' group by t.n_post
) b on b.n_post=a.n_post order by 1,2
Окончательный запрос
Результат запроса: |
|
||
|
|
|
|
|
n_post |
pves |
mves |
|
S1 |
2400 |
8400 |
|
S1 |
8400 |
8400 |
|
S3 |
3400 |
7000 |
|
S3 |
7000 |
7000 |
|
S4 |
5700 |
5700 |
|
S4 |
5700 |
5700 |
|
S5 |
1200 |
11200 |
|
S5 |
1200 |
11200 |
|
S5 |
1700 |
11200 |
|
S5 |
3400 |
11200 |
|
S5 |
3400 |
11200 |
|
S5 |
3800 |
11200 |
|
S5 |
4800 |
11200 |
|
S5 |
6000 |
11200 |
|
S5 |
9500 |
11200 |
|
S5 |
11200 |
11200 |
Найти поставщиков, имеющих поставки, вес которых составляет менее 20 % от максимального веса поставки красной детали, сделанной этим поставщиком. Вывести номер поставщика, вес поставки, максимальный вес поставки красной детали, сделанной поставщиком.
Осталось сравнить значения в столбцах pves и mves и оставить только те строки, где значения столбца pves меньше, чем значение столбца mves, деленное на 5.
Запрос:
select a.n_post, a.kol*pa.ves pves, b.mves from spj a
join p pa on pa.n_det=a.n_det
join ( select t.n_post, max(t.kol*p.ves) mves from spj t
join p on p.n_det=t.n_det where p.cvet='Красный' group by t.n_post
) b on b.n_post=a.n_post where a.kol*pa.ves< b.mves/5.0 order by 1,2
Результат запроса: |
|
||
|
|
|
|
|
n_post |
pves |
mves |
|
S5 |
1200 |
11200 |
|
S5 |
1200 |
11200 |
|
S5 |
1700 |
11200 |
54
Чтобы исключить из результата поставки с одинаковым весом, можно использовать предикат distinct.
Задание для самостоятельной работы
Найти изделия, имеющие поставки, объем которых в 8 раз меньше объема наибольшей поставки для изделия. Вывести номер изделия, объем поставки, объем наибольшей поставки для изделия.
ПРИМЕР 16 (Лабораторная работа 5 – задание 2)
Для каждого поставщика из Парижа найти число поставок каждой детали, им поставлявшейся. Вывести номер поставщика, город поставщика, номер детали, название детали, число поставок.
Анализ задания
В Париже проживают несколько поставщиков.
Нужно выбрать поставки, сделанные этими поставщиками. Разделить их на группы: каждая группа – поставки одним поставщиком одной из деталей. Определить число поставок в каждой группе. К полученным строкам добавить информацию о городе поставщика и названии детали.
Подзадача 1
Выбрать поставки, сделанные поставщиками из Парижа.
Информация о поставках хранится в таблице spj, информация о поставщиках хранится в таблице s, город в столбце town. Присоединим к каждой строке таблицы spj соответствующую номеру детали строку из таблицы поставщиков s. Выберем только те поставки, где город поставщика – Париж.
Запрос: |
Результат запроса: |
|
|
|||||
select spj.* |
|
|
|
|
||||
n_post |
n_det |
n_izd |
kol |
|||||
from spj t |
||||||||
S2 |
P3 |
J1 |
400 |
|||||
join s s1 on t.n_post = s1.n_post |
|
|||||||
|
S2 |
P3 |
J7 |
800 |
||||
where |
s1.town='Париж' |
|
|
|||||
|
|
S2 |
P3 |
J6 |
400 |
|||
order by t.n_post, t.n_det |
||||||||
S2 |
P3 |
J5 |
600 |
|||||
|
|
|
|
|||||
|
|
|
|
S2 |
P3 |
J4 |
500 |
|
|
|
|
|
S2 |
P3 |
J3 |
200 |
|
|
|
|
|
S2 |
P3 |
J2 |
200 |
|
|
|
|
|
S2 |
P5 |
J2 |
100 |
|
|
|
|
|
S3 |
P3 |
J1 |
200 |
|
|
|
|
|
S3 |
P4 |
J2 |
500 |
|
55
Подзадача 2
Для каждого поставщика из Парижа найти число поставок каждой детали, им поставлявшейся.
Сгруппируем поставки по поставщикам и по деталям, для подсчета числа поставок воспользуемся агрегатной функцией count.
Запрос:
select t.n_post, t.n_det, count(*) p_sr from spj t
join s s1 on t.n_post = s1.n_post where s1.town='Париж'
group by t.n_post, t.n_det
Окончательный запрос
Результат запроса: |
|
||
|
|
|
|
n_post |
n_det |
|
p_sr |
S2 |
P3 |
|
7 |
S2 |
P5 |
|
1 |
S3 |
P3 |
|
1 |
S3 |
P4 |
|
1 |
Для каждого поставщика из Парижа найти число поставок каждой детали, им поставлявшейся. Вывести номер поставщика, город поставщика, номер детали, название детали, число поставок.
Осталось добавить в каждой строке город поставщика и название детали. Эти столбцы нельзя просто добавить в целевой список, так как в запросе есть группировка. Если в запросе есть секция group by, в целевом списке могут стоять только:
имена столбцов, перечисленных в group by;
агрегатные функции.
Возникает соблазн добавить город поставщика и название детали в список группировки, но это решение, во-первых, не является оптимальным; во-вторых, делает запрос менее читабельным.
Поэтому оформим предыдущий запрос как виртуальную таблицу: заключим запрос в скобки и присвоим псевдоним а. Присоединим к виртуальной таблице а соответствующие строки таблиц s и p, выведем нужные столбцы.
Запрос:
select a.n_post,s.town, a.n_det,p.name, a.p_sr from (select t.n_post, t.n_det, count(*) p_sr
from spj t
join s s1 on t.n_post = s1.n_post where s1.town='Париж'
group by t.n_post, t.n_det ) a
56
join p on a.n_det = p.n_det join s on a.n_post = s.n_post order by a.n_post, a.n_det
Результат запроса:
n_post |
town |
n_det |
name |
p_sr |
S2 |
Париж |
P3 |
Винт |
7 |
S2 |
Париж |
P5 |
Кулачок |
1 |
S3 |
Париж |
P3 |
Винт |
1 |
S3 |
Париж |
P4 |
Винт |
1 |
Задание для самостоятельной работы
Для каждой детали из Лондона найти максимальный объем поставки этой детали каждым поставщиком, ее поставлявшим. Вывести номер детали, город детали, номер поставщика, фамилию поставщика, максимальный объем поставки детали поставщиком.
ПРИМЕР 17 (Лабораторная работа 5 – задание 3)
Найти города поставщиков, поставлявших деталь P1, и определить, какой процент составляет суммарный вес поставок поставщиками из каждого города от общего веса поставленных деталей P1. Вывести город, суммарный вес поставок поставщиков из этого города, общий вес поставленных деталей P1, процент.
Анализ задания
Нужно определить общий вес всех поставленных деталей P1. Эта величина – 100 %.
Для каждой поставки детали P1 определить, в каком городе живет поставщик, сделавший поставку. Разделить поставки на группы: каждая группа – поставки поставщиками из одного города. Для каждой группы вычислить суммарный вес деталей P1 и определить, сколько процентов эта величина составляет от 100 %.
Подзадача 1
Определить общий вес всех поставленных деталей P1.
Информация о поставках хранится в таблице spj. Также потребуется информация о весе деталей, хранящаяся в таблице p, столбец ves. Присоединим к каждой строке таблицы spj соответствующую номеру
57
детали строку из таблицы деталей p, отберем только поставки детали P1 и просуммируем веса поставок.
Запрос: |
Результат запроса: |
|||||
select |
sum(t.kol*p.ves) oves |
|
|
oves |
|
|
|
|
|
||||
from spj t |
|
|
||||
|
12000 |
|
||||
join p on p.n_det=t.n_det |
|
|
|
|
||
|
|
|
|
|
||
where t.n_det= 'P1' |
|
|
|
|
||
Подзадача 2
Вывести поставки детали P1 с дополнительной информацией о городе поставщика и весе поставки.
Присоединим к каждой строке таблицы spj соответствующую номеру детали строку из таблицы деталей p и соответствующую номеру поставщика строку из таблицы s. Отберем только поставки детали P1. Выведем все столбцы таблицы spj, столбец town (город) из таблицы s и добавим выражение для вычисления веса поставки.
Запрос:
select t.*, s.town, t.kol*p.ves pves from spj t
join s on s.n_post=t.n_post join p on p.n_det=t.n_det where t.n_det= 'P1'
Результат запроса: |
|
|
|
|
||
|
|
|
|
|
|
|
n_post |
n_det |
n_izd |
kol |
town |
pves |
|
S1 |
P1 |
|
J1 |
200 |
Лондон |
2400 |
S1 |
P1 |
|
J4 |
700 |
Лондон |
8400 |
S5 |
P1 |
|
J4 |
100 |
Афины |
1200 |
Подзадача 3
Вычислить суммарный вес поставок детали P1 поставщиками из каждого города.
Добавим в предыдущий запрос группировку по городу поставщика и просуммируем веса поставок.
Запрос:
select s.town, sum(t.kol*p.ves) pves from spj t
join s on s.n_post=t.n_post join p on p.n_det=t.n_det where t.n_det= 'P1' group by s.town
Результат запроса:
town |
pves |
Афины |
1200 |
Лондон |
10800 |
Подзадача 4
Присоединить к каждой строке предыдущего запроса величину, полученную в первой подзадаче.
58
Запрос из подзадачи 1 всегда возвращает одну строку, и эту строку нужно присоединить к каждой строке запроса подзадачи 3. Для этого оформим оба запроса как виртуальные таблицы (заключим запросы в скобки и обозначим псевдонимом) и используем соединение cross join (декартово произведение, соединение каждой строки одной таблицы с каждой строкой другой).
Запрос:
select a.town, a.pves, b.oves
from ( select s.town, sum(t.kol*p.ves) pves from spj t
join s on s.n_post=t.n_post join p on p.n_det=t.n_det where t.n_det= 'P1' group by s.town
) a
cross join ( select sum(t.kol*p.ves) oves from spj t
join p on p.n_det=t.n_det where t.n_det= 'P1'
) b
Окончательный запрос
Результат запроса: |
|
||
|
|
|
|
|
town |
pves |
oves |
|
Афины |
1200 |
12000 |
|
Лондон |
10800 |
12000 |
Найти города поставщиков, поставлявших деталь P1, и определить, какой процент составляет суммарный вес поставок поставщиками из каждого города от общего веса поставленных деталей P1. Вывести город, суммарный вес поставок поставщиков из этого города, общий вес поставленных деталей P1, процент.
Осталось вычислить, какой процент составляет значение в столбце pves от значения в столбце oves.
Запрос:
select a.town, a.pves, b.oves, round(a.pves*100.0/b.oves,2) proc
from ( select s.town, sum(t.kol*p.ves) pves from spj t
join s on s.n_post=t.n_post join p on p.n_det=t.n_det where t.n_det= 'P1' group by s.town
) a
Результат запроса: |
|
|
|
|
|
|
|
town |
pves |
oves |
proc |
Афины |
1200 |
12000 |
10.00 |
Лондон |
10800 |
12000 |
90.00 |
59
cross join ( select sum(t.kol*p.ves) oves from spj t
join p on p.n_det=t.n_det where t.n_det= 'P1') b
Задание для самостоятельной работы
1.Найти детали, которые поставлял поставщик S4, и определить, какой процент составляет суммарный вес поставок каждой детали от общего веса деталей, поставленных S4. Вывести номер детали, суммарный вес поставок этой детали, общий вес деталей поставщика S4, процент.
2.Найти изделия, для которых поставлял детали поставщик S2,
иопределить, какой процент составляют поставки для каждого изделия от общего числа поставок S2. Вывести номер изделия, число поставок для этого изделия, общее число поставок поставщика S2, процент.
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1.Стасышин В.М. Язык структурных запросов SQL: учеб. пособие. – Новосибирск: Изд-во НГТУ, 1996. – 33 c.
2.Грабер М. Введение в SQL. – М.: ЛОРИ, 1996.
3.Грофф Д.Р., Вайнберг П.Н. SQL: полное руководство. – Киев: BMV,
«Ирина», 2001.
60
