Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практикум по языку SQL. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
895 Кб
Скачать

Подзадача 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