https://iu5bmstu.ru/api.php?action=feedcontributions&user=81.9.52.28&feedformat=atom
Кафедра ИУ5 МГТУ им. Н.Э.Баумана, студенческое сообщество - Вклад [ru]
2024-03-29T09:24:27Z
Вклад
MediaWiki 1.41.0
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3887
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T18:21:40Z
<p>81.9.52.28: /* Билет 11 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
<s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать.<br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ <br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
GROUP BY gorod<br />
HAVING MIN(kolichestvo) > 1000<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём изделие не 'J1', а 'J18', которое было создано специально для этого запроса. Если оставить 'J1', то наглядности не получится, так как по нашей схеме БД это изделие не попадает под условие "только и только", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
nomer_izdelia != 'J18'<br />
AND<br />
nomer_postavshika = S.nomer_postavshika)<br />
OR<br />
(<br />
nomer_izdelia = 'J18'<br />
AND<br />
nomer_postavshika != S.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
<!-- этот запрос не подходит под "только и только", подробности в начале страницы<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight> --><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Безликий<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика",<br />
COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И даже ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18'<br />
AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18'<br />
AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.p<br />
WHERE NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3872
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T12:10:23Z
<p>81.9.52.28: /* Билет 21 */ Необходимо название изделий, оно в таблице J</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'J1', а 'S18', который был создан специально для этого запроса. Если оставить 'J1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "только и только", и запрос вернёт пустой результат.<br />
<br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE <br />
(<br />
nomer_izdelia != 'J18' AND <br />
nomer_postavshika = s.nomer_postavshika <br />
)<br />
OR<br />
(<br />
nomer_izdelia = 'J18' AND <br />
nomer_postavshika != s.nomer_postavshika <br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Безликий<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE <br />
NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.p P<br />
WHERE NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3871
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T11:56:08Z
<p>81.9.52.28: /* Билет 14 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'J1', а 'S18', который был создан специально для этого запроса. Если оставить 'J1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "только и только", и запрос вернёт пустой результат.<br />
<br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE <br />
(<br />
nomer_izdelia != 'J18' AND <br />
nomer_postavshika = s.nomer_postavshika <br />
)<br />
OR<br />
(<br />
nomer_izdelia = 'J18' AND <br />
nomer_postavshika != s.nomer_postavshika <br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Безликий<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.SPJ SPJ<br />
WHERE <br />
NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = SPJ.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.p P<br />
WHERE NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3868
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T11:50:07Z
<p>81.9.52.28: /* Билет 14 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE <br />
(<br />
nomer_izdelia != 'J18' AND <br />
nomer_postavshika = s.nomer_postavshika <br />
)<br />
OR<br />
(<br />
nomer_izdelia = 'J18' AND <br />
nomer_postavshika != s.nomer_postavshika <br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Безликий<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.p P<br />
WHERE NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3867
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T11:23:26Z
<p>81.9.52.28: /* Билет 29 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.p P<br />
WHERE NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3866
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T10:41:36Z
<p>81.9.52.28: /* Билет 15 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT J.nazvanie<br />
FROM spasoi_ekz.j J<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.j J<br />
ON X.nomer_izdelia = J.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('Штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3862
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T09:51:26Z
<p>81.9.52.28: /* Билет 19 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj JOIN spasoi_ekz.j<br />
ON spj.nomer_izdelia = j.nomer_izdelia<br />
AND j.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON spj.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X <br />
JOIN spasoi_ekz.j ON X.nomer_izdelia = j.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3860
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T09:34:47Z
<p>81.9.52.28: /* Билет 22 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj JOIN spasoi_ekz.j<br />
ON spj.nomer_izdelia = j.nomer_izdelia<br />
AND j.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.s S<br />
ON spj.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X <br />
JOIN spasoi_ekz.j ON X.nomer_izdelia = j.nomer_izdelia<br />
WHERE X.nomer_detali != 'P1' <br />
AND j.nazvanie = LOWER('штуцер 01-02')<br />
AND S.nomer_postavshika = X.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3851
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-16T07:33:28Z
<p>81.9.52.28: /* Билет 19 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
WHERE X.cvet = 'красный'<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3850
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T21:43:09Z
<p>81.9.52.28: /* Билет 17 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_postavshika = spj.nomer_postavshika<br />
) > 1000<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3849
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T19:38:15Z
<p>81.9.52.28: /* Билет 20 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3848
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T19:36:45Z
<p>81.9.52.28: /* Билет 20 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3847
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T19:35:03Z
<p>81.9.52.28: /* Билет 20 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3846
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T18:25:36Z
<p>81.9.52.28: /* Билет 5 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3845
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-15T17:42:31Z
<p>81.9.52.28: /* Билет 13 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(*) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X JOIN spasoi_ekz.s S<br />
ON X.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie <= 1000000<br />
AND X.nomer_izdelia = SPJ.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант этого запроса без NOT EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3838
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T22:46:19Z
<p>81.9.52.28: /* Билет 15 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
C использованием NOT EXISTS:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj<br />
JOIN spasoi_ekz.j ON spj.nomer_izdelia = j.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X<br />
JOIN spasoi_ekz.s ON X.nomer_postavshika = s.nomer_postavshika<br />
WHERE s.sostoyanie <= 1000000 AND<br />
X.nomer_izdelia = spj.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3837
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T22:45:42Z
<p>81.9.52.28: /* Билет 15 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
WHERE nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s S<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = S.nomer_postavshika <br />
) > 1000<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Вариант подлиннее для тех, кто не ищет лёгких путей''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<!-- а этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
C использованием NOT EXISTS:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT j.nazvanie<br />
FROM spasoi_ekz.spj<br />
JOIN spasoi_ekz.j ON spj.nomer_izdelia = j.nomer_izdelia<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj X<br />
JOIN spasoi_ekz.s ON X.nomer_postavshika = s.nomer_postavshika<br />
JOIN spasoi_ekz.j ON X.nomer_izdelia = j.nomer_izdelia<br />
WHERE s.sostoyanie <= 1000000 AND<br />
X.nomer_izdelia = spj.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3834
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T21:19:01Z
<p>81.9.52.28: /* Билет 11 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
spj.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT s.gorod, SUM(s.sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE ( <br />
SELECT MIN(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE X.nomer_postavshika = s.nomer_postavshika <br />
) > 1000<br />
GROUP BY s.gorod;<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3833
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T21:18:29Z
<p>81.9.52.28: /* Билет 11 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
spj.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT s.gorod, SUM(s.sostoyanie)<br />
FROM spasoi_ekz.sWHERE ( SELECT MIN(kolichestvo) FROM spasoi_ekz.spj X WHERE X.nomer_postavshika = s.nomer_postavshika ) > 1000GROUP BY s.gorod;<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3832
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T20:54:12Z
<p>81.9.52.28: /* Билет 10 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/ArwqOGAy5pPfi отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
S18 | Безликий | 1 | Йокогама<br />
(18 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
P26 | лезвие | бесцветный | 120 | Йокогама<br />
(26 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
J18 | кинжал | Йокогама<br />
(18 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
S18 | P26 | J18 | 1<br />
(56 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE imya LIKE '%Иванов%'<br />
AND P.nazvanie = LOWER('Болт')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj X<br />
WHERE SPJ.nomer_izdelia = X.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya LIKE '%Иванов%'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё вариант этого же запроса, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya LIKE '%Иванов%'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P26 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(20 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj <br />
spj.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
P26<br />
(3 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 16<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(1 row)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
<!-- С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и --><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3822
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T20:22:16Z
<p>81.9.52.28: /* Билет 7 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/MmOgbWnr5cATO отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
(17 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
(25 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
(17 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
(55 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND X.nomer_izdelia = nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без EXISTS''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE S.gorod = P.gorod<br />
AND J.nazvanie = LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT j.nazvanie<br />
FROM spasoi_ekz.spj <br />
JOIN spasoi_ekz.s ON spj.nomer_postavshika = s.nomer_postavshika <br />
JOIN spasoi_ekz.p ON spj.nomer_detali = p.nomer_detali <br />
JOIN spasoi_ekz.j ON spj.nomer_izdelia = j.nomer_izdelia<br />
WHERE imya LIKE 'Иванов' AND<br />
p.nazvanie LIKE LOWER('Болт') AND<br />
kolichestvo > ( <br />
SELECT AVG(kolichestvo) <br />
FROM spasoi_ekz.spj X <br />
WHERE spj.nomer_izdelia = X.nomer_izdelia <br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya = 'Иванов'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(19 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
(2 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 15<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(2 rows)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Второй вариант запроса''<br />
<div class="mw-collapsible-content"><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
</div><br />
</div><br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, nomer_izdelia<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3819
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T20:07:31Z
<p>81.9.52.28: /* Билет 6 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/MmOgbWnr5cATO отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
(17 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
(25 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
(17 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
(55 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS <br />
( <br />
SELECT * <br />
FROM spasoi_ekz.spj <br />
WHERE nomer_postavshika != 'S1' AND <br />
X.nomer_izdelia = nomer_izdelia <br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, с JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT p.nazvanie<br />
FROM spasoi_ekz.spj <br />
JOIN spasoi_ekz.s ON spj.nomer_postavshika = s.nomer_postavshika <br />
JOIN spasoi_ekz.p ON spj.nomer_detali = p.nomer_detali <br />
JOIN spasoi_ekz.j ON spj.nomer_izdelia = j.nomer_izdelia<br />
WHERE s.gorod = p.gorod AND<br />
j.nazvanie LIKE LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya = 'Иванов'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(19 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
(2 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 15<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(2 rows)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Второй вариант запроса''<br />
<div class="mw-collapsible-content"><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
</div><br />
</div><br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, nomer_izdelia<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE (<br />
J.nazvanie != LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali = P.nomer_detali<br />
)<br />
OR (<br />
J.nazvanie = LOWER('Штуцер 01-03')<br />
AND<br />
SPJ.nomer_detali != P.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3817
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T20:05:11Z
<p>81.9.52.28: /* Билет 6 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/MmOgbWnr5cATO отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
(17 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
(25 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
(17 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
(55 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
В трёх билетах в задании на запрос встречается формулировка "''только и только''". Как оказалось, это означает следующее: если холодильники поставляет ''только и только'' Уася, то:<br />
# кроме Уаси никто не поставляет холодильники;<br />
# Уася не поставляет ничего, кроме холодильников.<br />
<br />
Существующие запросы, естественно, оказались неправильными и их пришлось переписать. <s>Великий и могучий русский языка, ну что за экономия на бумаге.</s><br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS <br />
( <br />
SELECT * <br />
FROM spasoi_ekz.spj <br />
WHERE nomer_postavshika != 'S1' AND <br />
X.nomer_izdelia = nomer_izdelia <br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, с JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT p.nazvanieFROM spasoi_ekz.spj JOIN spasoi_ekz.s ON spj.nomer_postavshika = s.nomer_postavshika JOIN spasoi_ekz.p ON spj.nomer_detali = p.nomer_detali JOIN spasoi_ekz.j ON spj.nomer_izdelia = j.nomer_izdeliaWHERE s.gorod = p.gorod ANDj.nazvanie LIKE LOWER('Велосипед 01/23');<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya = 'Иванов'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(19 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
(2 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 15<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Чтобы продемонстрировать выполнение запроса наглядно, возьмём поставщика не 'S1', а 'S18', который был создан специально для этого запроса. Если оставить 'S1', то наглядности не получится, так как по нашей схеме БД этот поставщик не попадает под условие "''только и только''", и запрос вернёт пустой результат.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S18' AND nomer_izdelia = J.nomer_izdelia<br />
)<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S18' AND nomer_izdelia != J.nomer_izdelia<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кинжал<br />
(2 rows)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Второй вариант запроса''<br />
<div class="mw-collapsible-content"><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
</div><br />
</div><br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Штуцер 01-03')<br />
AND SPJ.nomer_detali = P.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3814
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T19:27:44Z
<p>81.9.52.28: /* Билет 4 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/MmOgbWnr5cATO отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
(17 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
(25 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
(17 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
(55 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_izdelia<br />
FROM spasoi_ekz.spj X<br />
WHERE NOT EXISTS <br />
( <br />
SELECT * <br />
FROM spasoi_ekz.spj <br />
WHERE nomer_postavshika != 'S1' AND <br />
X.nomer_izdelia = nomer_izdelia <br />
);<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya = 'Иванов'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(19 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
(2 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 15<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND nomer_izdelia = J.nomer_izdelia<br />
);<br />
<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE nomer_postavshika = 'S1'<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
уникальное изделие<br />
кружевное бельё<br />
(2 rows)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Второй вариант запроса''<br />
<div class="mw-collapsible-content"><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
</div><br />
</div><br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Штуцер 01-03')<br />
AND SPJ.nomer_detali = P.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=SQL-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B_%D0%BA_%D1%8D%D0%BA%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%83_%D0%BF%D0%BE_%D0%A1%D0%9F%D0%90%D0%A1%D0%9E%D0%98_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3813
SQL-запросы к экзамену по СПАСОИ (10 семестр)
2013-06-14T19:26:17Z
<p>81.9.52.28: /* Билет 4 */</p>
<hr />
<div><div style="float:right; clear:both; margin-right:1.0em;">__TOC__</div><br />
<br />
Билет экзамена по [[:Категория:Структурное проектирование АСОИ (10 семестр) | СПАСОИ]] состоит из двух частей:<br />
# теория;<br />
# SQL-запрос.<br />
<br />
На этой странице собраны все сформированные запросы по билетам.<br />
<br />
Странно, что ни в одном билете нет запроса с сортировкой результатов. Возможно, они буду в дополнительных заданиях.<br />
<br />
== Схема БД ==<br />
<br />
Схема БД используется всё [[СПАСОИ_(10)_-_Лекция_№8_-_SQL#Некоторые возможности языка SQL | та же]], что была в прошлом семестре и на лекциях.<br />
<br />
Для написания запросов и проверки их выполнения создана БД в СУБД [http://www.postgresql.org/ PostgreSQL].<br />
<br />
Скрипт создания можно загрузить [http://yadi.sk/d/MmOgbWnr5cATO отсюда].<br />
<br />
=== Таблицы БД ===<br />
<br />
==== Поставщики ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | imya | sostoyanie | gorod<br />
-------------------+------------------+------------+------------<br />
S5 | Мелисандра | 65000 | Мадрид<br />
S2 | Бран Старк | 60000 | Мурманск<br />
S1 | Якен Хгар | 1500000 | Йокогама<br />
S7 | Сирио Форель | 1500000 | Йокогама<br />
S4 | Джейме Ланнистер | 750000 | Лондон<br />
S3 | Серсея Ланнистер | 1200000 | Лондон<br />
S8 | Тирион Ланнистер | 2571 | Манчестер<br />
S9 | Иванов | 35000 | Мытищи<br />
S10 | Русе Болтон | 44444 | Баренцбург<br />
S11 | Петров Иван | 35000 | Мытищи<br />
S14 | Рендилл Тарли | 1111111 | Прага<br />
S13 | Сэмвелл Тарли | 999999 | Прага<br />
S6 | Оша | | Москва<br />
S16 | Ходор | | Москва<br />
S15 | Мелисса Флорент | 888888 | Стокгольм<br />
S12 | Петров Пётр | 35001 | Мытищи<br />
S17 | Томми Версетти | 123456789 | Майами<br />
(17 rows)<br />
<br />
==== Детали ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.p;<br />
</syntaxhighlight><br />
<br />
nomer_detali | nazvanie | cvet | ves | gorod<br />
--------------+----------------------+---------------+------+-----------------<br />
P9 | подставка | синий | 400 | Нижний Новгород<br />
P10 | стойка | синий | 2000 | Нижний Новгород<br />
P11 | абажур | синий | 400 | Нижний Новгород<br />
P1 | гайка | чёрный | 20 | Лондон<br />
P3 | ось | белый | 5000 | Эдинбург<br />
P4 | зубчатое колесо | чёрный | 50 | Эдинбург<br />
P6 | транзистор | коричневый | 2 | Токио<br />
P7 | печатная плата | зелёный | 200 | Токио<br />
P8 | диод | коричневый | 1 | Токио<br />
P12 | универсальная деталь | универсальный | 1 | Париж<br />
P13 | уникальная деталь | уникальный | 1 | Бостон<br />
P14 | болт | серый | 20 | Ижевск<br />
P15 | рама | красный | 3000 | Манчестер<br />
P16 | колесо | белый | 1500 | Манчестер<br />
P5 | втулка | серый | 350 | Манчестер<br />
P17 | бумага | белый | 1 | Астрахань<br />
P18 | плитка | белый | 300 | Флоренция<br />
P19 | орнамент | серый | 800 | Флоренция<br />
P20 | уголок | серый | 100 | Флоренция<br />
P21 | гайка 01-01 | серебристый | 20 | Клин<br />
P22 | усиленная рама | красный | 3200 | Череповец<br />
P23 | винт | розовый | 5 | Ижевск<br />
P24 | труселя | красный | 20 | Челябинск<br />
P25 | штуцерная деталь | коричневый | 450 | Череповец<br />
P2 | шуруп | чёрный | 5 | Лондон<br />
(25 rows)<br />
<br />
==== Изделия ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.j;<br />
</syntaxhighlight><br />
<br />
nomer_izdelia | nazvanie | gorod<br />
---------------+-----------------------+-----------------<br />
J1 | автомобиль | Магнитогорск<br />
J2 | процессор | Зеленоград<br />
J3 | торшер | Нижний Новгород<br />
J4 | универсальное изделие | Париж<br />
J5 | уникальное изделие | Бостон<br />
J6 | велосипед 01/23 | Манчестер<br />
J7 | изделие из болтов | Челябинск<br />
J8 | шкаф | Ярославль<br />
J9 | рама 02-01 | Череповец<br />
J10 | книга | Астрахань<br />
J11 | панно 01-03 | Флоренция<br />
J12 | велосипед 03-04 | Клин<br />
J13 | рама 02-03 | Череповец<br />
J14 | штуцер 01-02 | Череповец<br />
J15 | велосипед 01-04 | Клин<br />
J16 | кружевное бельё | Челябинск<br />
J17 | штуцер 01-03 | Череповец<br />
(17 rows)<br />
<br />
==== Сборки ====<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT * FROM spasoi_ekz.spj;<br />
</syntaxhighlight><br />
<br />
nomer_postavshika | nomer_detali | nomer_izdelia | kolichestvo<br />
-------------------+--------------+---------------+-------------<br />
S1 | P6 | J2 | 20<br />
S1 | P7 | J2 | 5<br />
S2 | P1 | J1 | 4<br />
S6 | P4 | J1 | 2<br />
S6 | P5 | J1 | 6<br />
S3 | P9 | J3 | 1<br />
S4 | P10 | J3 | 1<br />
S5 | P11 | J3 | 1<br />
S2 | P4 | J1 | 8<br />
S6 | P3 | J1 | 50<br />
S7 | P8 | J2 | 25<br />
S1 | P12 | J4 | 1<br />
S2 | P12 | J4 | 1<br />
S3 | P12 | J4 | 1<br />
S4 | P12 | J4 | 1<br />
S5 | P12 | J4 | 1<br />
S7 | P12 | J4 | 1<br />
S7 | P2 | J1 | 1<br />
S6 | P2 | J1 | 9<br />
S6 | P12 | J4 | 7<br />
S1 | P13 | J5 | 14<br />
S6 | P14 | J1 | 9000<br />
S2 | P14 | J1 | 3<br />
S6 | P1 | J1 | 12<br />
S8 | P15 | J6 | 1<br />
S8 | P16 | J6 | 2<br />
S3 | P5 | J6 | 10<br />
S10 | P2 | J8 | 4<br />
S8 | P1 | J7 | 16<br />
S9 | P14 | J7 | 3<br />
S11 | P10 | J3 | 2<br />
S12 | P15 | J1 | 3<br />
S11 | P11 | J3 | 4<br />
S10 | P14 | J9 | 5<br />
S13 | P17 | J10 | 1001<br />
S14 | P17 | J10 | 1111<br />
S15 | P17 | J10 | 1010<br />
S5 | P18 | J11 | 9<br />
S5 | P19 | J11 | 1<br />
S5 | P20 | J11 | 4<br />
S9 | P14 | J8 | 25<br />
S12 | P21 | J12 | 15<br />
S11 | P22 | J13 | 9<br />
S11 | P1 | J14 | 26<br />
S12 | P1 | J14 | 13<br />
S12 | P2 | J14 | 54<br />
S12 | P23 | J4 | 101<br />
S12 | P16 | J15 | 40<br />
S7 | P21 | J12 | 3<br />
S8 | P21 | J12 | 4<br />
S9 | P21 | J12 | 5<br />
S1 | P24 | J16 | 1<br />
S1 | P15 | J6 | 3<br />
S4 | P25 | J17 | 1<br />
S17 | P16 | J1 | 4<br />
(55 rows)<br />
<br />
== Готовые запросы ==<br />
<br />
Если видите, что тот или иной запрос можно составить короче и рациональней - смело вносите правку.<br />
<br />
=== Билет 1 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJX<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = SPJX.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
S2<br />
(2 rows)<br />
<br />
=== Билет 2 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, поставляемых более чем одним поставщиком.<br />
<br />
Текст запроса, каким его дал Григорьев на лекции, впоследствии исправив его:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
SUM(kolichestvo) AS "Сколько штук поставляется",<br />
COUNT(DISTINCT nomer_postavshika) AS "Сколько у неё поставщиков"<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali AS "Номер детали",<br />
kol AS "Сколько штук поставляется"<br />
FROM (<br />
SELECT nomer_detali,<br />
SUM(kolichestvo) AS kol,<br />
COUNT(DISTINCT nomer_postavshika)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_postavshika) > 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Сколько штук поставляется | Сколько у неё поставщиков<br />
--------------+---------------------------+---------------------------<br />
P1 | 71 | 5<br />
P10 | 3 | 2<br />
P11 | 5 | 2<br />
P12 | 13 | 7<br />
P14 | 9036 | 4<br />
P15 | 7 | 3<br />
P16 | 46 | 3<br />
P17 | 3122 | 3<br />
P2 | 68 | 4<br />
P21 | 27 | 4<br />
P4 | 10 | 2<br />
P5 | 16 | 2<br />
(12 rows)<br />
<br />
=== Билет 3 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков, поставляющих детали с номером 'P1' для какого-либо изделия в количестве (в поставке) большим, чем средний объём поставок деталей с номером 'P2' для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_postavshika <br />
FROM spasoi_ekz.spj X<br />
WHERE X.nomer_detali = 'P1'<br />
AND X.kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia = X.nomer_izdelia<br />
AND nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_postavshika<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) A<br />
WHERE nomer_detali = 'P1' AND kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
AND nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P2'<br />
)<br />
) B<br />
WHERE nomer_detali = 'P2'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nomer_postavshika<br />
-------------------<br />
S6<br />
(1 row)<br />
<br />
=== Билет 4 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий, для которых детали поставляет только поставщик с номером ‘S1’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nomer_izdeliaFROM spasoi_ekz.spj XWHERE not exists ( SELECT * FROM spasoi_ekz.spj WHERE nomer_postavshika != 'S1' AND X.nomer_izdelia = nomer_izdelia );<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
AND nomer_izdelia NOT IN(<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_izdelia<br />
---------------<br />
J5<br />
J16<br />
(2 rows)<br />
<br />
=== Билет 5 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием "Болт" в количестве (в поставке) большим, чем средний объём всех поставок деталей с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но без JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.p<br />
WHERE LOWER(nazvanie) = LOWER('Болт')<br />
)<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_detali = 'P1'<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
------<br />
Оша<br />
Иванов<br />
(2 rows)<br />
<br />
=== Билет 6 ===<br />
<br />
Написать запрос SELECT: выдать названия деталей, поставляемых поставщиком, проживающим в том же городе, где изготавливаются эти детали, для изделия с названием ‘Велосипед 01/23’.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.S S, spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE S.gorod = P.gorod<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
AND nomer_izdelia = (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.j<br />
WHERE nazvanie = LOWER('Велосипед 01/23')<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------<br />
рама<br />
колесо<br />
(2 rows)<br />
<br />
=== Билет 7 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входят детали с названием 'Болт', поставляемых поставщиками с именем 'Иванов', в количестве (в поставке) большим, чем средний объём поставок для этого изделия.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j<br />
WHERE nomer_izdelia IN (<br />
SELECT nomer_izdelia<br />
FROM (spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND imya = 'Иванов'<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND nazvanie = LOWER('Болт')) A<br />
WHERE kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = A.nomer_izdelia<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM (<br />
SELECT J.nazvanie, kolichestvo<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
) A<br />
WHERE kolichestvo ><br />
(<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia IN(<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.s S, spasoi_ekz.p P, spasoi_ekz.j J, spasoi_ekz.spj SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia<br />
AND P.nomer_detali = SPJ.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
AND S.imya = 'Иванов'<br />
AND S.nomer_postavshika = SPJ.nomer_postavshika<br />
)<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-------------------<br />
шкаф<br />
(1 row)<br />
<br />
=== Билет 8 ===<br />
<br />
Написать запрос SELECT: выдать номера изделий и общее количество деталей для них, поставляемых поставщиками с именем 'Петров'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_izdelia AS "Номер изделия", SUM(kolichestvo) AS "Количество деталей" <br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
-- так как "поставщикАМИ" и возможны<br />
-- Иван Петров и Петров Иван, то LIKE %Петров%<br />
AND imya LIKE '%Петров%'<br />
GROUP BY nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Номер изделия | Количество деталей<br />
---------------+--------------------<br />
J4 | 101<br />
J3 | 6<br />
J13 | 9<br />
J15 | 40<br />
J1 | 3<br />
J12 | 15<br />
J14 | 93<br />
(7 rows)<br />
<br />
=== Билет 9 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей и общее их количество для всех номеров деталей, которые входят только в одно изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali, kol FROM (<br />
SELECT nomer_detali, SUM(kolichestvo) AS kol, COUNT(DISTINCT nomer_izdelia) = 1<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_detali HAVING COUNT(DISTINCT nomer_izdelia) = 1<br />
) A;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
<br />
Результат:<br />
<br />
nomer_detali | sum<br />
--------------+------<br />
P10 | 3<br />
P11 | 5<br />
P12 | 13<br />
P13 | 14<br />
P17 | 3122<br />
P18 | 9<br />
P19 | 1<br />
P20 | 4<br />
P21 | 27<br />
P22 | 9<br />
P23 | 101<br />
P24 | 1<br />
P25 | 1<br />
P3 | 50<br />
P4 | 10<br />
P6 | 20<br />
P7 | 5<br />
P8 | 25<br />
P9 | 1<br />
(19 rows)<br />
<br />
=== Билет 10 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих детали с названием 'Болт' для изделия с названием 'Рама 02-01' в количестве (в поставке) большим, чем минимальное значение поставки детали с номером 'P1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-01')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nazvanie = LOWER('Болт')<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND P.nomer_detali = 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Русе Болтон<br />
(1 row)<br />
<br />
=== Билет 11 ===<br />
<br />
Написать запрос SELECT: выдать названия городов и суммарное состояние проживающих в каждом городе поставщиков, у которых минимальный объём поставки деталей больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, SUM(sostoyanie)<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING MIN(kolichestvo) > 1000<br />
)<br />
GROUP BY gorod;<br />
</syntaxhighlight><br />
<!-- этот запрос выполняет не совсем то и не правильно<br />
<syntaxhighlight lang="sql"><br />
SELECT gorod, sost<br />
FROM (<br />
SELECT gorod, SUM(sostoyanie) AS sost, SUM(SPJ.kolichestvo)<br />
FROM spasoi_ekz.spj, spasoi_ekz.s<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.gorod HAVING SUM(SPJ.kolichestvo) > 1000<br />
) A;<br />
</syntaxhighlight> --> <br />
<br />
Результат:<br />
<br />
gorod | sum<br />
-----------+---------<br />
Прага | 2111110<br />
Стокгольм | 888888<br />
(2 rows)<br />
<br />
=== Билет 12 ===<br />
<br />
Написать запрос SELECT: выдать номера деталей, поставляемых для какого-либо изделия поставщиком, проживающим в том же городе, где изготавливается это изделие.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.s S, spasoi_ekz.j J<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
AND S.gorod = J.gorod<br />
AND J.nomer_izdelia = SPJ.nomer_izdelia;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nomer_detali<br />
--------------<br />
P15<br />
P16<br />
(2 rows)<br />
<br />
=== Билет 13 ===<br />
<br />
Написать <u>один</u> запрос SELECT: выдать количества строк в таблице S (Поставщик) 1) с пустыми значениями и 2) непустыми значениями в столбце Состояние.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT COUNT(nomer_postavshika) - COUNT(sostoyanie) AS "С пустым состоянием", <br />
COUNT(sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос, но длиннее и нерациональней''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
<br />
SELECT COUNT(Snull.*) AS "С пустым состоянием", COUNT(Snotnull.sostoyanie) AS "С не пустым состоянием"<br />
FROM spasoi_ekz.s Snull RIGHT OUTER JOIN spasoi_ekz.s Snotnull<br />
ON Snull.nomer_postavshika = Snotnull.nomer_postavshika<br />
AND Snull.sostoyanie IS NULL;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
С пустым состоянием | С не пустым состоянием<br />
---------------------+-----------------------<br />
2 | 15<br />
(1 row)<br />
<br />
=== Билет 14 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют детали только и только для изделия с номером 'J1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj A JOIN spasoi_ekz.s S<br />
ON A.nomer_postavshika = S.nomer_postavshika<br />
WHERE nomer_izdelia = 'J1'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_izdelia != 'J1'<br />
AND nomer_postavshika = A.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
----------------<br />
Томми Версетти<br />
(1 row)<br />
<br />
=== Билет 15 ===<br />
<br />
Написать запрос SELECT: выдать наименования изделий, для которых детали поставляют только те поставщики, у которых состояние больше 1000000 у.е.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE sostoyanie > 1000000<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE sostoyanie < 1000000<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
кружевное бельё<br />
уникальное изделие<br />
процессор<br />
(3 rows)<br />
<br />
=== Билет 16 ===<br />
Написать запрос SELECT: выдать цвета и для каждого цвета общее количество деталей, входящих в изделие с названием 'Панно 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT cvet AS "Цвет", SUM(kolichestvo) AS "Деталей"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Панно 01-03')<br />
JOIN spasoi_ekz.P P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
GROUP BY cvet;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Цвет | Деталей<br />
-------+---------<br />
белый | 9<br />
серый | 5<br />
(2 rows)<br />
<br />
=== Билет 17 ===<br />
<br />
Написать запрос SELECT: выдать номера поставщиков и количество сделанных ими поставок при условии, что среднее число деталей во всех этих поставках больше 1000.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nom AS "Номер поставщика", cnt AS "Количество поставок"<br />
FROM (<br />
SELECT S.nomer_postavshika AS nom,<br />
COUNT(SPJ.nomer_postavshika) AS cnt,<br />
AVG(SPJ.kolichestvo) AS kol<br />
FROM spasoi_ekz.s S, spasoi_ekz.spj SPJ<br />
WHERE S.nomer_postavshika = SPJ.nomer_postavshika<br />
GROUP BY S.nomer_postavshika<br />
) A<br />
WHERE kol > 1000;<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос немного попроще''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nomer_postavshika AS "Номер поставщика", COUNT(*) AS "Количество поставок"<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
GROUP BY nomer_postavshika HAVING AVG(kolichestvo) > 1000<br />
)<br />
GROUP BY nomer_postavshika;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер поставщика | Количество поставок<br />
------------------+---------------------<br />
S13 | 1<br />
S6 | 7<br />
S14 | 1<br />
S15 | 1<br />
(4 rows)<br />
<br />
=== Билет 18 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, имеющих состояние больше 1000 и поставляющих деталь с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем средний объём поставки, выполненной поставщиками с именем 'Иванов'.<br />
<br />
<br />
[[Файл:2nd dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="5px">'''Второй по сложности запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="4px">'''Вот уж не свезло, так не свезло'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE sostoyanie > 1000<br />
AND P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika <br />
WHERE S.imya = 'Иванов'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 19 ===<br />
<br />
Написать запрос SELECT: выдать названия красных деталей, которые входят только в изделие с названием 'Рама 02-03' в количестве, меньшем 10 единиц в поставке.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT X.nazvanie<br />
FROM spasoi_ekz.p X JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_detali = X.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE X.cvet = 'красный'<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
AND kolichestvo < 10<br />
AND NOT EXISTS (<br />
SELECT J.nomer_izdelia<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Рама 02-03')<br />
AND X.nomer_detali = SPJ.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT P.nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('Рама 02-03')<br />
WHERE kolichestvo < 10<br />
AND SPJ.nomer_detali NOT IN (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie != LOWER('Рама 02-03')<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
----------------<br />
усиленная рама<br />
(1 row)<br />
<br />
=== Билет 20 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих только белые детали.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE cvet = 'белый'<br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND P.cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'белый'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE S.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet != 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''И ещё один вариант этого же запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s<br />
WHERE nomer_postavshika NOT IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet != 'белый'<br />
)<br />
AND nomer_postavshika IN (<br />
SELECT spj.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ, spasoi_ekz.p P<br />
WHERE SPJ.nomer_detali = P.nomer_detali<br />
AND p.cvet = 'белый'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
imya<br />
-----------------<br />
Рендилл Тарли<br />
Сэмвелл Тарли<br />
Мелисса Флорент<br />
Томми Версетти<br />
(4 rows)<br />
<br />
=== Билет 21 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, для которых детали поставляет только и только поставщик с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.j J, spasoi_ekz.SPJ SPJ<br />
WHERE J.nomer_izdelia = SPJ.nomer_izdelia <br />
AND NOT EXISTS (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
AND nomer_izdelia = J.nomer_izdelia<br />
);<br />
<br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Ещё один вариант запроса''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
WHERE nomer_postavshika = 'S1'<br />
AND SPJ.nomer_izdelia NOT IN (<br />
SELECT nomer_izdelia<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika != 'S1'<br />
);<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
nazvanie<br />
--------------------<br />
уникальное изделие<br />
кружевное бельё<br />
(2 rows)<br />
<br />
=== Билет 22 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют только детали с номером 'P1' для изделия с именем 'Штуцер 01-02'.<br />
<br />
Текст запроса:<br />
<br />
<!-- неверный запрос - номер изделия, а не название<br />
SELECT imya FROM S X<br />
JOIN SPJ Y ON X.nomer_postavshika=Y.nomer_postavshika<br />
WHERE X.nomer_postavshika NOT IN (<br />
SELECT DISTINCT nomer_postavshika FROM SPJ Z<br />
WHERE Z.nomer_izdelia != 'Штуцер 01-02'<br />
AND Z.nomer_detali!='P1');--><br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali = 'P1'<br />
JOIN spasoi_ekz.s S<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
WHERE SPJ.nomer_postavshika NOT IN (<br />
SELECT nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON SPJ.nomer_izdelia = J.nomer_izdelia<br />
AND J.nazvanie = LOWER('штуцер 01-02')<br />
JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND SPJ.nomer_detali != 'P1'<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Иван<br />
(1 row)<br />
<br />
=== Билет 23 ===<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют деталь с названием 'Винт' в количестве большим 100 единиц в одной поставке и имеют состояние больше среднего по их родному городу.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT S.imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON S.nomer_postavshika = SPJ.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
WHERE P.nazvanie = LOWER('Винт')<br />
AND SPJ.kolichestvo > 100<br />
AND S.sostoyanie > (<br />
SELECT AVG(SS.sostoyanie)<br />
FROM spasoi_ekz.s SS<br />
WHERE SS.gorod = S.gorod<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 24 ===<br />
<br />
Написать запрос SELECT: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в одном городе.<br />
<br />
С этим запросом возникла неожиданная проблема - задание то ли неполное, то ли неправильное, потому что нельзя однозначно сказать, что по нему требуется сделать.<br />
<br />
Так что тут несколько вариантов запросов (кто как понял).<br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Первый вариант запроса''<br />
<div class="mw-collapsible-content"><br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, kol<br />
FROM spasoi_ekz.p A, (<br />
SELECT X.gorod, SUM(kolichestvo) as kol<br />
FROM spasoi_ekz.p X, spasoi_ekz.spj Y<br />
WHERE Y.nomer_detali = X.nomer_detali<br />
GROUP BY X.gorod<br />
) B<br />
WHERE A.gorod = B.gorod;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | kol<br />
----------------------+------<br />
подставка | 9<br />
стойка | 9<br />
абажур | 9<br />
гайка | 139<br />
ось | 60<br />
зубчатое колесо | 60<br />
транзистор | 50<br />
печатная плата | 50<br />
диод | 50<br />
универсальная деталь | 13<br />
уникальная деталь | 14<br />
болт | 9137<br />
рама | 69<br />
колесо | 69<br />
втулка | 69<br />
бумага | 3122<br />
плитка | 14<br />
орнамент | 14<br />
уголок | 14<br />
гайка 01-01 | 27<br />
усиленная рама | 10<br />
винт | 9137<br />
труселя | 1<br />
штуцерная деталь | 10<br />
шуруп | 139<br />
(25 rows)<br />
</div><br />
</div><br />
и<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Второй вариант запроса''<br />
<div class="mw-collapsible-content"><br />
В уточнение задания Григорьев сказал следующее: "''Следует учесть, что в качестве наименования города может выступать переменная, в которую в некоторой программе должно быть занесено конкретное значение перед выполнением запроса''".<br />
<br />
То есть, вообще говоря, задание на запрос неполное, и его можно трактовать так: выдать наименования деталей и общее их количество для всех наименований деталей, изготавливаемых в городе <code>%НАЗВАНИЕГОРОДА%</code>. Вот эта переменная задаётся где-то в программе, а в БД идёт запрос с уже подставленным конкретным названием. <br />
<br />
Этот вариант запроса составлен, например, для Лондона. <br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie, SUM(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
WHERE gorod = 'Лондон'<br />
GROUP BY nazvanie;<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie | sum<br />
----------+-----<br />
гайка | 71<br />
шуруп | 68<br />
(2 rows)<br />
</div><br />
</div><br />
<br />
=== Билет 25 ===<br />
<br />
<br />
Написать запрос SELECT: выдать имена поставщиков, поставляющих хотя бы одну белую деталь для изделия с названием 'Велосипед 01-04' с объёмом поставки большим, чем средний объём поставки этого поставщика.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT imya<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE cvet = 'белый'<br />
AND J.nazvanie = LOWER('Велосипед 01-04')<br />
AND kolichestvo > (<br />
SELECT AVG(kolichestvo)<br />
FROM spasoi_ekz.spj SPJ<br />
WHERE SPJ.nomer_postavshika = S.nomer_postavshika<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
-------------<br />
Петров Пётр<br />
(1 row)<br />
<br />
=== Билет 26 ===<br />
<br />
Написать запрос SELECT: выдать номера красных деталей и количество поставок этих деталей.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT P.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY P.nomer_detali; <br />
</syntaxhighlight><br />
<br />
<div class="toccolours mw-collapsible mw-collapsed"><br />
''Этот же запрос через JOIN''<br />
<div class="mw-collapsible-content"><br />
<syntaxhighlight lang="sql"><br />
SELECT SPJ.nomer_detali AS "Номер детали", COUNT(kolichestvo) AS "Количество поставок с ней"<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.p P<br />
ON SPJ.nomer_detali = P.nomer_detali<br />
AND cvet = 'красный'<br />
GROUP BY SPJ.nomer_detali;<br />
</syntaxhighlight><br />
</div><br />
</div><br />
<br />
Результат:<br />
<br />
Номер детали | Количество поставок с ней<br />
--------------+---------------------------<br />
P15 | 3<br />
P22 | 1<br />
P24 | 1<br />
(3 rows)<br />
<br />
=== Билет 27 ===<br />
<br />
Написать запрос SELECT: выдать наименования городов и среднее состояние поставщиков для каждого города, поставляющих детали с названием 'Гайка 01-01' для изделия с названием 'Велосипед 03-04' в количестве (в поставке) большим, чем минимальный объём поставки, выполненной поставщиком с номером 'S1'.<br />
<br />
<br />
[[Файл:1st dufficulty.png|center]]<br />
<br />
<br />
<p align="center"><font size="7px">'''Сложнейший запрос экзамена!'''</font></p><br />
<br />
<p align="center"><font size="5px">'''Сохрани Джа, вытащить такое'''</font></p><br />
<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT S.gorod AS "Город", AVG(S.sostoyanie) AS "Среднее состояние"<br />
FROM spasoi_ekz.s S JOIN spasoi_ekz.spj SPJ<br />
ON SPJ.nomer_postavshika = S.nomer_postavshika<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ.nomer_detali<br />
JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE P.nazvanie = LOWER('Гайка 01-01')<br />
AND J.nazvanie = LOWER('Велосипед 03-04')<br />
AND kolichestvo > (<br />
SELECT MIN(kolichestvo)<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = 'S1'<br />
)<br />
GROUP BY S.gorod;<br />
<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
Город | Среднее состояние<br />
-----------+-----------------------<br />
Мытищи | 35000.500000000000<br />
Йокогама | 1500000.000000000000<br />
Манчестер | 2571.0000000000000000<br />
(3 rows)<br />
<br />
=== Билет 28 ===<br />
<br />
Написать запрос SELECT: выдать названия изделий, куда входит хотя бы одна красная деталь весом больше 10 граммов, поставляемая только поставщиком с номером 'S1'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT J.nazvanie<br />
FROM spasoi_ekz.j J JOIN spasoi_ekz.spj SPJ1<br />
ON J.nomer_izdelia = SPJ1.nomer_izdelia<br />
JOIN spasoi_ekz.p P<br />
ON P.nomer_detali = SPJ1.nomer_detali<br />
WHERE P.ves > 10<br />
AND P.cvet = 'красный'<br />
AND NOT EXISTS (<br />
SELECT SPJ2.nomer_postavshika<br />
FROM spasoi_ekz.spj SPJ2 <br />
WHERE SPJ2.nomer_detali = P.nomer_detali<br />
AND SPJ2.nomer_postavshika != 'S1'<br />
); <br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
-----------------<br />
кружевное бельё<br />
(1 row)<br />
<br />
=== Билет 29 ===<br />
Написать запрос SELECT: выдать названия деталей, которые входят только и только в состав изделия с названием 'Штуцер 01-03'.<br />
<br />
Текст запроса:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT nazvanie<br />
FROM spasoi_ekz.p P, spasoi_ekz.spj SPJ<br />
WHERE P.nomer_detali = SPJ.nomer_detali <br />
AND NOT EXISTS (<br />
SELECT SPJ.nomer_izdelia<br />
FROM spasoi_ekz.spj SPJ JOIN spasoi_ekz.j J<br />
ON J.nomer_izdelia = SPJ.nomer_izdelia<br />
WHERE J.nazvanie != LOWER('Штуцер 01-03')<br />
AND SPJ.nomer_detali = P.nomer_detali<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
nazvanie<br />
------------------<br />
штуцерная деталь<br />
(1 row)<br />
<br />
=== Билет 30 ===<br />
Написать запрос SELECT: выдать имена поставщиков, которые поставляют, по крайней мере, все те детали, которые поставляет поставщик с номером 'S2'.<br />
<br />
Текст запроса:<br />
<syntaxhighlight lang="sql"><br />
SELECT DISTINCT imya<br />
FROM spasoi_ekz.s S<br />
WHERE NOT EXISTS (<br />
SELECT nomer_detali<br />
FROM spasoi_ekz.spj SPJY<br />
WHERE nomer_postavshika = 'S2'<br />
AND NOT EXISTS (<br />
SELECT *<br />
FROM spasoi_ekz.spj<br />
WHERE nomer_postavshika = S.nomer_postavshika<br />
AND nomer_detali = SPJY.nomer_detali<br />
)<br />
);<br />
</syntaxhighlight><br />
<br />
Результат:<br />
<br />
imya<br />
------------<br />
Оша<br />
Бран Старк<br />
(2 rows)<br />
[[Категория:Структурное проектирование АСОИ (10 семестр)]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%BA%D0%BE%D1%80%D0%BF%D0%BE%D1%80%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D1%85_%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC_(10_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80)&diff=3155
Категория:Архитектура корпоративных информационных систем (10 семестр)
2013-04-06T18:25:24Z
<p>81.9.52.28: /* Литература */</p>
<hr />
<div><p>{{Предмет | name=Архитектура корпоративных информационных систем | prepod=[[Нестеров Ю.Г.]] | lections=17 | seminars=нет | labs=4 | dzs=1 | rks=? | signif=желательно | what=зачёт}}</p><br />
<br />
Архитектура корпоративных информационных систем.<br />
__TOC__<br />
== Лекции ==<br />
<br />
17 лекций. Отношение к посещаемости либеральное.<br />
<br />
== Домашнее задание ==<br />
<br />
Написать исследовательскую работу объёмом не более 30 страниц на указанную тему. Список тем [http://yadi.sk/d/l72llmEl2e7Zc тут].<br />
<br />
Если тема не нравится, то можно поменять на другую - это надо согласовать с Нестеровым по почте.<br />
<br />
== Лабораторные работы ==<br />
<br />
4 лабораторных.<br />
<br />
== Зачёт ==<br />
<br />
Если посетил более 75% лекций и хорошо написал ДЗ, то автомат.<br />
<br />
== Литература ==<br />
<br />
* [http://old.intuit.ru/department/itmngt/entarc/ курс на ИНТУИТе] - лекции читаются по нему;<br />
<br />
[[Категория:10 семестр]]<br />
[[Категория:Предметы]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%A1%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80_%E2%84%966_-_%D0%A1%D0%B8%D0%BD%D1%82%D0%B5%D0%B7_%D1%85%D0%BE%D1%80%D0%BE%D1%88%D0%B5%D0%B9_%D0%91%D0%94&diff=2576
ТОРА (9) - Семинар №6 - Синтез хорошей БД
2013-01-18T16:24:16Z
<p>81.9.52.28: /* Вторая задача */</p>
<hr />
<div>{{Tabli4ka warning undone summary|text=&nbsp;&nbsp;&nbsp;- окончания [[#Первая задача | первой задачи]] второго ДЗ.}}<br />
{{Backward|l=ТОРА (9) - Семинар №5 - Синтез хорошей БД}}<br />
Разбираем задачи из ДЗ прошлого семинара.<br />
__TOC__<br />
== ДЗ 1 ==<br />
<br />
Продолжаем задачу из прошлого семинара.<br />
<br />
Строим схему отношений:<br />
<br />
[[Файл:9sTORAs6pic1.png|400px]]<br />
<br />
Перерисовываем её с синтетическими ключами:<br />
<br />
[[Файл:9sTORAs6pic2.png|400px]]<br />
<br />
Для генерации синтетических ключей используются ''объекты последовательности''.<br />
<br />
Например:<br />
<syntaxhighlight lang="sql"><br />
CREATE SEQUENCE имя_объекта_последовательности;<br />
...<br />
INSERT INTO имя_таблицы VALUES(имя_объекта_последовательности.NEXTVAL ...);<br />
</syntaxhighlight><br />
<br />
== ДЗ 2 ==<br />
<br />
=== Первая задача ===<br />
<br />
Из [[ТОРА (9) - Семинар №5 - Синтез хорошей БД#Первая задача | 5 семинара]].<br />
<br />
<u>Задание:</u><br />
<br />
Задана предметная область [[ТОРА (9) - Семинар №4 - Синтез хорошей БД#Синтез хорошей схемы БД | про пилотов]], но ФЗ другие:<br />
<br />
{{Формула|f=F = (B\rightarrow D, D\rightarrow B, AB\rightarrow D, AD\rightarrow B, BC\rightarrow A, BC\rightarrow D, CD\rightarrow A, CD\rightarrow B,}}<br />
{{Формула|f=ABC\rightarrow D, ACD\rightarrow B, BCD\rightarrow A)}}<br />
<br />
Синтезировать БД с помощью алгоритма.<br />
<br />
1)<br />
<br />
:{{Формула|f=УНП = (B\rightarrow D, D\rightarrow B, AB\rightarrow D, BC\rightarrow AD, CD\rightarrow AB, AD\rightarrow B, ABC\rightarrow D, ACD\rightarrow B, BCD\rightarrow A)}}<br />
<br />
<br />
3) сначала этот пункт:<br />
<br />
:{{Формула|f=A^+ = A}}<br />
:{{Формула|f=B^+ = BD}}<br />
:{{Формула|f=C^+ = C}}<br />
:{{Формула|f=D^+ = DB}}<br />
:{{Формула|f=(BC)^+ = BCAD}}<br />
<br />
:{{Формула|f=УНП = (B\rightarrow D, D\rightarrow B, CD\rightarrow AB, BC\rightarrow AD)}}<br />
<br />
2)<br />
<br />
:как-то куда-то делся этот пункт.<br />
<br />
4)<br />
<br />
:{{Формула|f=B\rightarrow D}}<br />
:{{Формула|f=D\rightarrow B}}<br />
:{{Формула|f=K_1 = BD}}<br />
<br />
:{{Формула|f=BC\rightarrow AD}}<br />
:{{Формула|f=CD\rightarrow AB}}<br />
:{{Формула|f=K_2 = ABCD}}<br />
<br />
5)<br />
<br />
:[[Файл:9sTORAs6pic3.png|200px]]<br />
<br />
6)<br />
<br />
:{{Формула|f=K_2}}:<br />
::{{Формула|f=BC\rightarrow D}}<br />
::{{Формула|f=СD\rightarrow B}}<br />
::вторую вычеркнули<br />
<br />
:{{Формула|f=K_1}}<br />
::вторую вычеркнули<br />
<br />
7)<br />
<br />
:[[Файл:9sTORAs6pic4.png|200px]]<br />
<br />
и дальше по алгоритму.<br />
<br />
=== Вторая задача ===<br />
<br />
Всё также из [[ТОРА (9) - Семинар №5 - Синтез хорошей БД#Вторая задача | 5 семинара]].<br />
<br />
{{Формула|f=U = A, B, C, D, E, K, L, N, O, P, R, S, T, V, X}}<br />
<br />
{{Формула|f=F = A\rightarrow CNO, B\rightarrow PRS, ADE\rightarrow X, K\rightarrow DEL, L\rightarrow T, X\rightarrow VT, ET\rightarrow V, D\rightarrow XBE}}<br />
<br />
Синтезируем схему БД:<br />
<br />
1)<br />
<br />
:{{Формула|f=УНП = (A\rightarrow CNO, B\rightarrow PRS, ADE\rightarrow CNOXVTBPRS, K\rightarrow DELXBTVPRS,}}<br />
:{{Формула|f=L\rightarrow T, X\rightarrow VT, ET\rightarrow V, D\rightarrow XBEPRSVT)}}<br />
<br />
2)<br />
<br />
:так как нет ФЗ, включающей в себя все атрибуты, то добавляем её сами:<br />
:{{Формула|f=УНП = (A\rightarrow CNO, B\rightarrow PRS, ADE\rightarrow CNOXVTBPRS, K\rightarrow DELXBTVPRS,}}<br />
:{{Формула|f=L\rightarrow T, X\rightarrow VT, ET\rightarrow V, D\rightarrow XBEPRSVT, ABCDEKLNOPRSTVX\rightarrow\varnothing)}}<br />
<br />
3)<br />
<br />
:смотрим замыкания:<br />
::{{Формула|f=A^+ = ACNO}}<br />
::{{Формула|f=E^+ = E}}<br />
::{{Формула|f=(AD)^+ = ADCNOXBEPRSVT}}<br />
::{{Формула|f=T^+ = T}}<br />
:получили {{Формула|f=УНП = (A\rightarrow CNO, B\rightarrow PRS, AD\rightarrow CNOXBEPRSVTE, K\rightarrow DELXBTVPRS,}}<br />
:{{Формула|f=L\rightarrow T, X\rightarrow VT, ET\rightarrow V, D\rightarrow XBEPRSVT, ABCDEKLNOPRSTVX\rightarrow\varnothing)}}<br />
<br />
{{Forward|l=ТОРА (9) - Семинар №7 - Синтез хорошей БД}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)|С]]<br />
[[Категория:Конспекты лекций и семинаров]]<br />
[[Категория:Незаконченные конспекты]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%9615_-_%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B8&diff=2574
ТОРА (9) - Лекция №15 - Пример оценки
2013-01-18T10:18:56Z
<p>81.9.52.28: /* Пример оценки физического плана */</p>
<hr />
<div>{{Tabli4ka warning undone summary|text=&nbsp;&nbsp;&nbsp;- описаний формул. А также в некоторых формулах должны быть ошибки;<br>&nbsp;&nbsp;&nbsp;- графического представления оптимального плана.}}<br />
{{Backward|l=ТОРА_(9)_-_Лекция_№14_-_Оценки_(продолжение)}}<br />
Оригинал всего раздела, посвящённого оптимизации SQL-запросов, от самого [[Григорьев Ю.А. | Григорьева]] можно загрузить [http://yadi.sk/d/VjjMs6ww1HH2D здесь].<br />
__TOC__<br />
== Оптимизация SQL-запросов ==<br />
<br />
=== Методы соединения таблиц ===<br />
<br />
==== Алгоритмы для поиска физического плана ====<br />
<br />
===== Пример оценки физического плана =====<br />
<br />
Исходные данные:<br />
<br />
1) количество записей в таблице {{Формула|f=T(R_1)}} = 10000, количество записей в таблице {{Формула|f=T(R_2)}} = 100000;<br />
<br />
2) количество записей в одном блоке таблицы {{Формула|f=L(R_1) = L(R_2)}} = 100, количество записей в соединении {{Формула|f=L_{JOIN} }} = 1000;<br />
<br />
3) количество записей в блоке индекса код_пользователя {{Формула|f=L} = 200, количество записей в блоке индекса номер_счёта {{Формула|f=L} = 200;<br />
<br />
::<span style="color:blue"><u>Примечание:</u> ''записи исходных таблиц могут читаться в сортированном виде по своим индексированным атрибутам. Записи в таблице {{Формула|f=R_1}} сгруппированы по атрибуту код_пользователя (кластеризованный индекс), а в таблице {{Формула|f=R_2}} не сгруппированы.''</span><br />
<br />
4) мощность атрибутов:<br />
* {{Формула|f=R_1}}, <code>код_пользователя</code> 5000;<br />
* {{Формула|f=R_1}}, <code>номер_счёта</code> 10000;<br />
* {{Формула|f=R_2}}, <code>номер_счёта</code> 100000<br />
* {{Формула|f=R_2}}, <code>остаток</code> - неизвестно.<br />
<br />
5) тут почему-то пусто<br />
<br />
6) {{Формула|f=b}} = 10, {{Формула|f=C_{COMP} = C_{MOVE} = C_{filter} = 0.01}} мс, {{Формула|f=C_B = 10}} мс.<br />
<br />
Для построение оптимального физического плана используется алгоритм динамического программирования (из [[ТОРА (9) - Лекция №14 - Оценки (продолжение)#Алгоритмы для поиска физического плана | предыдущей лекции]]).<br />
<br />
Алгоритм:<br />
<br />
1) {{Формула|f=AccessPlan}}<br />
<br />
:а) {{Формула|f=R_1}} - таблица пользователи;<br />
::{{Формула|f=j = 1}}, чтение всей таблицы<br />
::{{Формула|f=C_1 = C_{CPU1} + C_{I/O1} = T(R_1)\cdot C_{filter} + B(R_1)\cdot C_B = 10000\cdot 0.01 + \frac{10000}{100}\cdot 10 = 1100}} мс<br />
::{{Формула|f=j = 2}} - индекс по атрибуту <code>код_пользователя</code><br />
::{{Формула|f=C_2 = C_{CPU2} + C_{I/O2} = \frac{T(R_1)\cdot K}{I(R_1, a)}\cdot C_{filter} + \frac{B(Index(a))\cdot k}{I(R_1, a)} \cdot C_b + \frac{B(R_2)\cdot k}{I(R_1, a)} =}}<br />
:::{{Формула|f==\frac{10000\cdot 1}{5000}\cdot 0.01 + \frac{(10000/200)\cdot 1}{5000}\cdot 10 + \frac{10000/100\cdot 1}{5000}\cdot 10 = 0.02 + 0.3 = 0.32}} мс<br />
::{{Формула|f=С = min(С_1, С_2) = 0.32}} мс<br />
::{{Формула|f=С_{I/O} = C_{I/O2} = 0.3}} мс<br />
::{{Формула|f=T(Q_1) = T(R_2)\cdot P_{код\_ пользователя = 3} = T(R_2)\cdot \frac{k}{I(R_1, a)} = 10000 \cdot 1/5000 = 2}}<br />
::{{Формула|f=B(Q_1) = \lceil\frac{T(Q_1)}{L(R_1)\cdot 10}\rceil = \lceil\frac{2}{100\cdot 10}\rceil = 1}}<br />
::{{Формула|f=str[1] = \{\{Q_1\}, \varnothing, \varnothing, 0.32, 0.3, \{2, 1, \{2\}, 2\}\} }}<br />
<br />
:б) {{Формула|f=R_2}} - таблица счёт.<br />
::{{Формула|f=j = 1}}<br />
::{{Формула|f=C_1 = 100000\cdot 0.01 + \frac{100000}{100}\cdot 10 = 11000}} мс<br />
::{{Формула|f=j = 2}}<br />
::{{Формула|f=C = C_1 = 11000}} мс<br />
::{{Формула|f=C_{I/O} = C_{I/O1} = 10000}} мс<br />
::{{Формула|f=T(Q_2) = T(R_2)\cdot P_{R_2.остаток > 1500} = 100000\cdot 1/3 = 33000}}, вероятность принята равной {{Формула|f=1/3}}, так как по условию эта мощность неизвестна<br />
::{{Формула|f=B(Q_2) = \lceil\frac{T(Q_2)}{L(R_2)\cdot 10}\rceil = \lceil\frac{33000}{100\cdot 10}\rceil = 33}}<br />
::{{Формула|f=str[2] = \{\{Q_2\}, \varnothing, \varnothing, 11000, 10000, \{33000, 33, \{33000\}, 1\}\} }}<br />
<br />
2) {{Формула|f=JoinPlan}}<br />
:{{Формула|f=m_1 = 1}}, {{Формула|f=m_2 = 2}} - номера экземпляров структур, таких, что {{Формула|f=str[m_1].W = Q_1}} и {{Формула|f=str[m_2].W = Q_2}}<br />
<br />
:а)<br />
::{{Формула|f=i = 1}}, [[ТОРА_(9)_-_Лекция_№12_-_Оценки_(продолжение)#Метод ложных циклов (NLJ) | NLJ]]<br />
::{{Формула|f=C_1 = C_{CPU1} + C_{I/O1} = T(Q_1)\cdot T(Q_2)\cdot C_{COMP} + \lfloor\frac{B(Q_1)}{b}\rfloor\cdot C_{I/O}(Q_2) = 2\cdot 33000\cdot 0.01 + \lfloor\frac{1}{10}\rfloor\cdot 10000 = 660}} мс<br />
::{{Формула|f=i = 2}}, [[ТОРА_(9)_-_Лекция_№12_-_Оценки_(продолжение)#Метод сортировки слияния (SMJ) | SMJ]]<br />
::таблица {{Формула|f=Q_2}} уже отсортирована по номер_счёта, так как имеется индекс по номеру счёта<br />
::{{Формула|f=С_2 = С_{CPU2} + C_{I/O2} = C^{SORT}_{CPU}(Q_1) + С^{JOIN}_{CPU}(Q_1, Q_2) + C^{SORT}_{I/O}(Q_1) + C^{JOIN}_{I/O}(Q_1, Q_2) =}}<br />
:::{{Формула|f== 2\cdot \log_2\frac{2}{\lfloor 1/10\rfloor}\cdot (0.01 + 0.01) + (\log_{10}1 - 1)\cdot 2\cdot (10\cdot 0.01 + 0.01) + ((\frac{33000}{33000} + 2\cdot 2 +}}<br />
:::{{Формула|f=+ 33000\cdot(1 - \frac{2}{33000}))\cdot 0.01 + (2\cdot 1\cdot \log_{10}\cdot 1)\cdot 10 + (1 + 0)\cdot 10 = 340}} мс<br />
::{{Формула|f=C = min(C_1, C_2) = 340}}<br />
::{{Формула|f=C = str[1].Z + str[2].Z + C = 0.32 + 11000 + 340 = 11340.32}} мс<br />
::{{Формула|f=C_{I/O} = str[1].ZIO + str[2].ZIO + C_{I/O2} = 0.3 + 10000 + 10 = 10010.3}} мс<br />
::{{Формула|f=T(Q_1\bowtie Q_2) = \frac{T(Q_1)\cdot T(Q_2)}{max(I(Q_1, a), I(Q_2, a))} = \frac{2\cdot 33000}{max(2, 33000)} =2}}<br />
::{{Формула|f=B(Q_1\bowtie Q_2) = \lceil\frac{2}{1000}\rceil= 1}}<br />
::{{Формула|f=I(Q_1\bowtie Q_2, a) = min(I(Q_1, a), I(Q_2, a)) = min(2, 33000) = 2}}<br />
::{{Формула|f=str[3] = \{\{Q_1, Q_2\}, \{Q_1\}, \{Q_2\}, 11340, 10010, \{2, 1, \{2\}, 2\}\} }}<br />
<br />
:б)<br />
::структура остаётся такая же<br />
<br />
3) {{Формула|f=OptPlanReturn}} - вывод оптимального плана и представление этого плана в графическом виде.<br />
<br />
:1) {{Формула|f=(Q_1, Q_2) = Q_1\bowtie Q_2}}<br />
:2) {{Формула|f=Q_1 = (IndexScan() + Filter())}}<br />
:3) {{Формула|f=Q_2 = (TableScan() + Filter())}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]<br />
[[Категория:Незаконченные конспекты]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%9615_-_%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B8&diff=2573
ТОРА (9) - Лекция №15 - Пример оценки
2013-01-18T09:54:28Z
<p>81.9.52.28: /* Пример оценки физического плана */</p>
<hr />
<div>{{Tabli4ka warning undone summary|text=&nbsp;&nbsp;&nbsp;- описаний формул. А также в некоторых формулах должны быть ошибки;<br>&nbsp;&nbsp;&nbsp;- графического представления оптимального плана.}}<br />
{{Backward|l=ТОРА_(9)_-_Лекция_№14_-_Оценки_(продолжение)}}<br />
Оригинал всего раздела, посвящённого оптимизации SQL-запросов, от самого [[Григорьев Ю.А. | Григорьева]] можно загрузить [http://yadi.sk/d/VjjMs6ww1HH2D здесь].<br />
__TOC__<br />
== Оптимизация SQL-запросов ==<br />
<br />
=== Методы соединения таблиц ===<br />
<br />
==== Алгоритмы для поиска физического плана ====<br />
<br />
===== Пример оценки физического плана =====<br />
<br />
Исходные данные:<br />
<br />
1) количество записей в таблице {{Формула|f=T(R_1)}} = 10000, количество записей в таблице {{Формула|f=T(R_2)}} = 100000;<br />
<br />
2) количество записей в одном блоке таблицы {{Формула|f=L(R_1) = L(R_2)}} = 100, количество записей в соединении {{Формула|f=L_{JOIN} }} = 1000;<br />
<br />
3) количество записей в блоке индекса код_пользователя {{Формула|f=L} = 200, количество записей в блоке индекса номер_счёта {{Формула|f=L} = 200;<br />
<br />
::<span style="color:blue"><u>Примечание:</u> ''записи исходных таблиц могут читаться в сортированном виде по своим индексированным атрибутам. Записи в таблице {{Формула|f=R_1}} сгруппированы по атрибуту код_пользователя (кластеризованный индекс), а в таблице {{Формула|f=R_2}} не сгруппированы.''</span><br />
<br />
4) мощность атрибутов:<br />
* {{Формула|f=R_1}}, <code>код_пользователя</code> 5000;<br />
* {{Формула|f=R_1}}, <code>номер_счёта</code> 10000;<br />
* {{Формула|f=R_2}}, <code>номер_счёта</code> 100000<br />
* {{Формула|f=R_2}}, <code>остаток</code> - неизвестно.<br />
<br />
5) тут почему-то пусто<br />
<br />
6) {{Формула|f=b}} = 10, {{Формула|f=C_{COMP} = C_{MOVE} = C_{filter} = 0.01}} мс, {{Формула|f=C_B = 10}} мс.<br />
<br />
Для построение оптимального физического плана используется алгоритм динамического программирования (из [[ТОРА (9) - Лекция №14 - Оценки (продолжение)#Алгоритмы для поиска физического плана | предыдущей лекции]]).<br />
<br />
Алгоритм:<br />
<br />
1) {{Формула|f=AccessPlan}}<br />
<br />
:а) {{Формула|f=R_1}} - таблица пользователи;<br />
::{{Формула|f=j = 1}}, чтение всей таблицы<br />
::{{Формула|f=C_1 = C_{CPU1} + C_{I/O1} = T(R_1)\cdot C_{filter} + B(R_1)\cdot C_B = 10000\cdot 0.01 + \frac{10000}{100}\cdot 10 = 1100}} мс<br />
::{{Формула|f=j = 2}} - индекс по атрибуту <code>код_пользователя</code><br />
::{{Формула|f=C_2 = C_{CPU2} + C_{I/O2} = \frac{T(R_1)\cdot K}{I(R_1, a)}\cdot C_{filter} + \frac{B(Index(a))\cdot k}{I(R_1, a)} \cdot C_b + \frac{B(R_2)\cdot k}{I(R_1, a)} =}}<br />
:::{{Формула|f==\frac{10000\cdot 1}{5000}\cdot 0.01 + \frac{(10000/200)\cdot 1}{5000}\cdot 10 + \frac{10000/100\cdot 1}{5000}\cdot 10 = 0.02 + 0.3 = 0.32}} мс<br />
::{{Формула|f=С = min(С_1, С_2) = 0.32}} мс<br />
::{{Формула|f=С_{I/O} = C_{I/O2} = 0.3}} мс<br />
::{{Формула|f=T(Q_1) = T(R_2)\cdot P_{код\_ пользователя = 3} = T(R_2)\cdot \frac{k}{I(R_1, a)} = 10000 \cdot 1/5000 = 2}}<br />
::{{Формула|f=B(Q_1) = \lceil\frac{T(Q_1)}{L(R_1)\cdot 10}\rceil = \lceil\frac{2}{100\cdot 10}\rceil = 1}}<br />
::{{Формула|f=str[1] = \{\{Q_1\}, \varnothing, \varnothing, 0.32, 0.3, \{2, 1, \{2\}, 2\}\} }}<br />
<br />
:б) {{Формула|f=R_2}} - таблица счёт.<br />
::{{Формула|f=j = 1}}<br />
::{{Формула|f=C_1 = 100000\cdot 0.01 + \frac{100000}{100}\cdot 10 = 11000}} мс<br />
::{{Формула|f=j = 2}}<br />
::{{Формула|f=C = C_1 = 11000}} мс<br />
::{{Формула|f=C_{I/O} = C_{I/O1} = 10000}} мс<br />
::{{Формула|f=T(Q_2) = T(R_2)\cdot P_{R_2.остаток > 1500} = 100000\cdot 1/3 = 33000}}, вероятность принята равной {{Формула|f=1/3}}, так как по условию эта мощность неизвестна<br />
::{{Формула|f=B(Q_2) = \lceil\frac{T(Q_2)}{L(R_2)\cdot 10}\rceil = \lceil\frac{33000}{100\cdot 10}\rceil = 33}}<br />
::{{Формула|f=str[2] = \{\{Q_2\}, \varnothing, \varnothing, 11000, 10000, \{33000, 33, \{33000\}, 1\}\} }}<br />
<br />
2) {{Формула|f=JoinPlan}}<br />
:{{Формула|f=m_1 = 1}}, {{Формула|f=m_2 = 2}} - номера экземпляров структур, таких, что {{Формула|f=str[m_1].W = Q_1}} и {{Формула|f=str[m_2].W = Q_2}}<br />
<br />
:а)<br />
::{{Формула|f=i = 1}}, [[ТОРА_(9)_-_Лекция_№12_-_Оценки_(продолжение)#Метод ложных циклов (NLJ) | NLJ]]<br />
::{{Формула|f=C_1 = C_{CPU1} + C_{I/O1} = T(Q_1)\cdot T(Q_2)\cdot C_{COMP} + \lfloor\frac{B(Q_1)}{b}\rfloor\cdot C_{I/O(Q_2)} = 2\cdot 33000\cdot 0.01 + \lfloor\frac{1}{10}\rfloor\cdot 10000 = 660}} мс<br />
::{{Формула|f=i = 2}}, [[ТОРА_(9)_-_Лекция_№12_-_Оценки_(продолжение)#Метод сортировки слияния (SMJ) | SMJ]]<br />
::таблица {{Формула|f=Q_2}} уже отсортирована по номер_счёта, так как имеется индекс по номеру счёта<br />
::{{Формула|f=С_2 = С_{CPU2} + C_{I/O2} = C^{SORT}_{CPU}(Q_1) + С^{JOIN}_{CPU}(Q_1, Q_2) + C^{SORT}_{I/O}(Q_1) + C^{JOIN}_{I/O}(Q_1, Q_2) =}}<br />
:::{{Формула|f== 2\cdot \log_2\frac{2}{\lfloor 1/10\rfloor}\cdot (0.01 + 0.01) + (\log_{10}1 - 1)\cdot 2\cdot (10\cdot 0.01 + 0.01) + ((\frac{33000}{33000} + 2\cdot 2 +}}<br />
:::{{Формула|f=+ 33000\cdot(1 - \frac{2}{33000}))\cdot 0.01 + (2\cdot 1\cdot \log_{10}\cdot 1)\cdot 10 + (1 + 0)\cdot 10 = 340}} мс<br />
::{{Формула|f=C = min(C_1, C_2) = 340}}<br />
::{{Формула|f=C = str[1].Z + str[2].Z + C = 0.32 + 11000 + 340 = 11340.32}} мс<br />
::{{Формула|f=C_{I/O} = str[1].ZIO + str[2].ZIO + C_{I/O2} = 0.3 + 10000 + 10 = 10010.3}} мс<br />
::{{Формула|f=T(Q_1\bowtie Q_2) = \frac{T(Q_1)\cdot T(Q_2)}{max(I(Q_1, a), I(Q_2, a))} = \frac{2\cdot 33000}{max(2, 33000)} =2}}<br />
::{{Формула|f=B(Q_1\bowtie Q_2) = \lceil\frac{2}{1000}\rceil= 1}}<br />
::{{Формула|f=I(Q_1\bowtie Q_2, a) = min(I(Q_1, a), I(Q_2, a)) = min(2, 33000) = 2}}<br />
::{{Формула|f=str[3] = \{\{Q_1, Q_2\}, \{Q_1\}, \{Q_2\}, 11340, 10010, \{2, 1, \{2\}, 2\}\} }}<br />
<br />
:б)<br />
::структура остаётся такая же<br />
<br />
3) {{Формула|f=OptPlanReturn}} - вывод оптимального плана и представление этого плана в графическом виде.<br />
<br />
:1) {{Формула|f=(Q_1, Q_2) = Q_1\bowtie Q_2}}<br />
:2) {{Формула|f=Q_1 = (IndexScan() + Filter())}}<br />
:3) {{Формула|f=Q_2 = (TableScan() + Filter())}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]<br />
[[Категория:Незаконченные конспекты]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%967_-_%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_(%D0%BF%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5)&diff=2557
ТОРА (9) - Лекция №7 - Алгоритм (продолжение)
2013-01-15T21:44:42Z
<p>81.9.52.28: /* Пример 1 */</p>
<hr />
<div>{{Backward|l=ТОРА (9) - Лекция №6 - Алгоритм построения хорошей БД}}<br />
<br />
== Алгоритм синтеза "хорошей" БД ==<br />
<br />
=== Пример ===<br />
<br />
7) редуцирование атрибутов справа ФЗ, расположенной по иерархии выше<br />
<br />
: вычёркиваем в графе {{Формула|f=A}}<br />
<br />
: [[Файл:9sTORAl7pic1.png|link=9sTORAl7pic1.svg]]<br />
<br />
8)<br />
<br />
: нет ФЗ с пустой правой частью, потому шаг пропускаем.<br />
<br />
9)<br />
<br />
: {{Формула|f=\rho = (AB, BCD) = (R_1, R_2)}}<br />
<br />
10)<br />
<br />
:проверяем<br />
<br />
:* соединение без потерь<br />
<br />
:{{Формула|f=F = (A\rightarrow B, B\rightarrow A, AC\rightarrow D, BC\rightarrow D)}}<br />
<br />
:{| class="wikitable"<br />
! !! {{Формула|f=A}} !! {{Формула|f=B}} !! {{Формула|f=C}} !! {{Формула|f=D}}<br />
|- align="center"<br />
! {{Формула|f=AB}}<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}} || {{Формула|f=b_1}}<br />
|-<br />
! {{Формула|f=BCD}}<br />
| {{Формула|f=b_2}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|}<br />
<br />
:{| class="wikitable"<br />
! !! {{Формула|f=A}} !! {{Формула|f=B}} !! {{Формула|f=C}} !! {{Формула|f=D}}<br />
|- align="center"<br />
! {{Формула|f=AB}}<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}} || {{Формула|f=b_1}}<br />
|-<br />
! {{Формула|f=BCD}}<br />
| bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|}<br />
<br />
:Значит, {{Формула|f=\rho}} обладает сохранением без потерь.<br />
<br />
:* сохранение ФЗ<br />
<br />
:1-4)<br />
<br />
:: {{Формула|f=H = \varnothing}}, {{Формула|f=УНП = (A\rightarrow B, B\rightarrow A, AC\rightarrow BD, BC\rightarrow AD)}}<br />
:: {{Формула|f=H = (AC\rightarrow BD, BC\rightarrow A)}}<br />
<br />
:5)<br />
<br />
:: {{Формула|f=H\neq\varnothing}}<br />
<br />
:6)<br />
<br />
:: выполняется ли {{Формула|f=AC\rightarrow BDE\in(A\rightarrow B, B\rightarrow A, BC\rightarrow D)^+}}?<br />
:: {{Формула|f=(AC)^+ = ACBD}}, {{Формула|f=BD\subset(AC)^+}}<br />
:: выполняется ли {{Формула|f=BC\rightarrow A\in(A\rightarrow B, B\rightarrow A, BC\rightarrow D)^+}}?<br />
:: {{Формула|f=(BC)^+ = BCAD}}, {{Формула|f=A\subset(BC)^+}}<br />
:: значит, {{Формула|f=\rho}} обладает сохранением ФЗ.<br />
<br />
:На практике, частно пренебрегают свойством сохранения ФЗ, если в БД вводятся правильные данные - не надо проверять, противоречат ли эти данные исходной ФЗ.<br />
<br />
Таким образом, {{Формула|f=\rho}} обладает:<br />
* обладает соединением без потерь;<br />
* обладает сохранением ФЗ;<br />
* точно находится в 3НФ.<br />
<br />
Но мы всё равно проверим, находятся ли {{Формула|f=R_1}} и {{Формула|f=R_2}} в [[ТОРА_(9)_-_Лекция_№6_-_Алгоритм_построения_хорошей_БД#Нормальная_форма_Бойса-Кодда | 3НФ Бойса-Кодда]]:<br />
<br />
: {{Формула|f=R_1 = AB}}:<br />
:: {{Формула|f=A\rightarrow B}}, {{Формула|f=B\rightarrow A}}<br />
:: здесь {{Формула|f=A}} - ключ и {{Формула|f=B}} - ключ.<br />
:: значит, находится в НФ.<br />
<br />
: {{Формула|f=R_2 = BCD}}:<br />
:: {{Формула|f=BC\rightarrow D}}<br />
:: {{Формула|f=BC}} - ключ.<br />
:: значит, находится в НФ.<br />
<br />
=== Преимущество и недостатки алгоритма ===<br />
<br />
==== Преимущество ====<br />
<br />
Алгоритм определяет стандартную (математическую) процедуру построения схемы БД.<br />
<br />
==== Недостатки ====<br />
<br />
* очень трудно определить всё множество ФЗ, а алгоритм критичен к набору этих ФЗ. В приципе, надо строить абстрактный экземпляр отношений ([[ТОРА_(9)_-_Семинар_№2_-_Функциональные_зависимости#Задача №2 - Как выявлять ФЗ|семинар №2]]), но надо знать и предметную область;<br />
* при увеличении числа ФЗ возможно увеличение сложности вычисления алгоритма.<br />
<br />
Эти недостатки сдерживают применение алгоритма на практике.<br />
<br />
== Практические приёмы нормализации ==<br />
<br />
Кроме алгоритма есть практические приёмы нормализации схемы отношений.<br />
<br />
=== Нормальные формы ===<br />
<br />
==== 1НФ ====<br />
<br />
Схема отношений находится в 1НФ, если не содержит таблицу или вектор в явном виде. Поэтому, если таблица скрыта в объекте, то схема будет в 1НФ;<br />
<br />
==== 2НФ ====<br />
<br />
Схема отношений находится в 2НФ, если не существует ключа {{Формула|f=X}}, подмножества атрибутов {{Формула|f=Y\subset X}} и непервичного атрибута {{Формула|f=H}}, для которых выполняются условия:<br />
* {{Формула|f=X\rightarrow Y}};<br />
* {{Формула|f=Y\rightarrow H}};<br />
* {{Формула|f=Y\nrightarrow X}}.<br />
<br />
[[Файл:9sTORAl7pic2.png|link=Файл:9sTORAl7pic2.svg]]<br />
<br />
{{Формула|f=A_1\rightarrow A_i ... A_j}}<br />
<br />
{{Формула|f=X = A_1 A_2}}, {{Формула|f=Y = A_1\subset X}}, {{Формула|f=H\in(A_i ... A_j)}}:<br />
:1) {{Формула|f=X\rightarrow Y}}, так как {{Формула|f=A_1 A_2\rightarrow A_1}}<br />
:2) {{Формула|f=Y\rightarrow H}}, так как {{Формула|f=A_1\rightarrow A_i ... A_j}}<br />
:3) {{Формула|f=Y\nrightarrow X}}, так как {{Формула|f=A_1^+ = A_1 A_i ... A_j}}, {{Формула|f=X\nsubseteq Y^+}}<br />
<br />
==== 3НФ ====<br />
<br />
Подробнее [[ТОРА (9) - Лекция №5 - Третья нормальная форма#Третья нормальная форма | на лекции №5]].<br />
<br />
[[Файл:9sTORAl7pic3.png|link=Файл:9sTORAl7pic3.svg]]<br />
<br />
{{Формула|f=A_2\rightarrow A_i ... A_j}}<br />
<br />
{{Формула|f=X = A_1}}, {{Формула|f=Y = A_2}}, {{Формула|f=H\in(A_i ... A_j)}}:<br />
:1) {{Формула|f=X\rightarrow Y}}, так как {{Формула|f=A_1\rightarrow A_2}}<br />
:2) {{Формула|f=Y\rightarrow H}}, так как {{Формула|f=A_2\rightarrow A_i ... A_j}}<br />
:3) {{Формула|f=Y\nrightarrow X}}, так как {{Формула|f=A_2^+ = A_2 A_i ... A_j}}, {{Формула|f=X = A_1\notin Y^+}}<br />
<br />
=== Пример 1 ===<br />
<br />
{{Формула|f=R}} - схема отношения "Сотрудники".<br />
{| class="wikitable"<br />
|- align="center"<br />
! {{Формула|f=A_1}}<br />
| табельный номер<br />
|- align="center"<br />
! {{Формула|f=A_5}}<br />
| номер заказа<br />
|- align="center"<br />
! {{Формула|f=A_2}}<br />
| ФИО<br />
|- align="center"<br />
! {{Формула|f=A_3}}<br />
| должность<br />
|- align="center"<br />
! {{Формула|f=A_4}}<br />
| оклад<br />
|}<br />
<br />
ФЗ: <br />
:{{Формула|f=A_1 A_5\rightarrow A_2 A_3 A_4}}<br />
:{{Формула|f=A_1\rightarrow A_2 A_3 A_4}}<br />
:{{Формула|f=A_3\rightarrow A_4}}<br />
<br />
Покажем, что эта схема не находится в 2НФ:<br />
<br />
Можно найти ключ {{Формула|f=X = A_1 A_5}}, {{Формула|f=Y = A_1\subset X}}, {{Формула|f=H\notin Y}}, {{Формула|f=H\in(A_2, A_3, A_4)}}:<br />
:1) {{Формула|f=X\rightarrow Y}}<br />
:2) {{Формула|f=Y\rightarrow H}}<br />
:3) {{Формула|f=Y\nrightarrow X}}<br />
<br />
[[Файл:9sTORAl7pic4.png|link=Файл:9sTORAl7pic4.svg]]<br />
<br />
{{Формула|f=R_1}} тоже не находится во 2НФ, потому что {{Формула|f=X = A_1}}, {{Формула|f=Y = A_3}}, {{Формула|f=H = A_4}}:<br />
:1) {{Формула|f=X\rightarrow Y}}<br />
:2) {{Формула|f=Y\rightarrow H}}<br />
:3) {{Формула|f=Y\nrightarrow X}}<br />
<br />
[[Файл:9sTORAl7pic5.png|link=Файл:9sTORAl7pic5.svg]]<br />
<br />
Предположим, вдруг оказалось, что сотрудник может занимать несколько должностей, и ещё теперь в таблице надо хранить сведения о заказе. В этом случае схема преобразуется к следующему виду:<br />
<br />
[[Файл:9sTORAl7pic6.png|link=Файл:9sTORAl7pic6.svg]]<br />
<br />
Но анализ показывает, что в этом случае таблицы {{Формула|f=R_1}} и {{Формула|f=R_2}} не находятся в 2НФ:<br />
<br />
{{Формула|f=R_1}}:<br />
:{{Формула|f=A_1\rightarrow A_2}}, {{Формула|f=X = A_1 A_3}}, {{Формула|f=Y = A_1\subset X}}, {{Формула|f=H = A_2}}<br />
:1) {{Формула|f=X\rightarrow Y}}, так как {{Формула|f=A_1 A_3\rightarrow A_1}}<br />
:2) {{Формула|f=Y\rightarrow H}}, так как {{Формула|f=A_1\rightarrow A_2}}<br />
:3) {{Формула|f=Y\nrightarrow X}}, так как {{Формула|f=Y^+ = A_1 A_2}}, {{Формула|f=X\nsubseteq Y^+}}<br />
<br />
{{Формула|f=R_2}}:<br />
:{{Формула|f=A_5\rightarrow A_6}}, {{Формула|f=X = A_1 A_3 A_5}}, {{Формула|f=Y = A_5\subset X}}, {{Формула|f=H = A_6}}<br />
:1) {{Формула|f=X\rightarrow Y}}, так как {{Формула|f=A_1 A_3 A_5\rightarrow A_5}}<br />
:2) {{Формула|f=Y\rightarrow H}}, так как {{Формула|f=A_5\rightarrow A_6}}<br />
:3) {{Формула|f=Y\nrightarrow X}}, так как {{Формула|f=Y^+ = A_5 A_6}}, {{Формула|f=X = A_1 A_3 A_5\nsubseteq Y^+}}<br />
<br />
{{Forward|l=ТОРА (9) - Лекция №8 - Алгоритм (продолжение)}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%964_-_%D0%A5%D0%BE%D1%80%D0%BE%D1%88%D0%B0%D1%8F_%D1%81%D1%85%D0%B5%D0%BC%D0%B0_%D0%91%D0%94_-_%D0%A1%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A4%D0%97&diff=2544
ТОРА (9) - Лекция №4 - Хорошая схема БД - Сохранение ФЗ
2013-01-14T22:34:42Z
<p>81.9.52.28: /* Доказательство */</p>
<hr />
<div>Продолжение [[ТОРА_(9)_-_Лекция_№3_-_Хорошая_схема_БД_-_Соединение_без_потерь | предыдущей лекции]].<br />
<br />
== Свойства "хорошей" схемы БД ==<br />
<br />
=== Соединение без потерь ===<br />
<br />
==== Теорема о свойстве соединения без потерь ====<br />
<br />
Пусть {{Формула|f=\rho=(R_1, R_2)}} и {{Формула|f=F}} - множество ФЗ.<br />
<br />
{{Формула|f=\rho}} обладает свойством соединения без потерь тогда и только тогда, когда выполняется хотя бы одно из:<br />
* {{Формула|f=R_1\bigcap R_2\rightarrow R_1 - R_2}} (1)<br />
* {{Формула|f=R_1\bigcap R_2\rightarrow R_2 - R_1}} (2)<br />
<br />
===== Доказательство =====<br />
<br />
1)<br />
<br />
{| class="wikitable"<br />
! rowspan="2" | !! colspan="3" | {{Формула|f=R_1 - R_2}} !! colspan="3" | {{Формула|f=R_1\bigcap R_2}} || colspan="3" | {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
! {{Формула|f=A_1}} !! ... !! {{Формула|f=A_k}} !! {{Формула|f=A_{k+1} }} !! ... !! {{Формула|f=A_m}} !! {{Формула|f=A_{m+1} }} !! ... !! {{Формула|f=A_n}}<br />
|- align="center"<br />
| {{Формула|f=R_1}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=b_1}} || ... || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=R_2}} || {{Формула|f=b_2}} || ... || {{Формула|f=b_2}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}}<br />
|}<br />
<br />
{| class="wikitable"<br />
! rowspan="2" | !! colspan="3" | {{Формула|f=R_1 - R_2}} !! colspan="3" | {{Формула|f=R_1\bigcap R_2}} || colspan="3" | {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
! {{Формула|f=A_1}} !! ... !! {{Формула|f=A_k}} !! {{Формула|f=A_{k+1} }} !! ... !! {{Формула|f=A_m}} !! {{Формула|f=A_{m+1} }} !! ... !! {{Формула|f=A_n}}<br />
|- align="center"<br />
| {{Формула|f=R_1}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=b_1}} || ... || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=R_2}} || bgcolor="lime" | {{Формула|f=a}} || ... || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}}<br />
|} <br />
<br />
:Получили строку, сплошь состоящую из {{Формула|f=a}}.<br />
<br />
2)<br />
<br />
:Теперь докажем обратное, что если {{Формула|f=\rho}} обладает соединением без потерь, то имеет место одна из ФЗ: (1) или (2).<br />
<br />
:{{Формула|f=r=\Pi_{R_1}(r)\bowtie\Pi_{R_2}(r)}} (3)<br />
<br />
:{{Формула|f=r}} - это {{Формула|f=R_1\bigcup R_2}} (экземпляр универсальной схемы отношений)<br />
<br />
{| class="wikitable"<br />
! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcap R_2}} !! {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
| {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| ... || ... || ...<br />
|- align="center"<br />
| {{Формула|f=a_n}} || {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
<br />
{|<br />
| valign="top" |<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcap R_2}}<br />
|- align="center"<br />
| rowspan="4" | {{Формула|f=\Pi_{R_1}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}}<br />
|- align="center"<br />
| ... || ...<br />
|- align="center"<br />
| {{Формула|f=a_n}} || {{Формула|f=b_n}}<br />
|}<br />
|<br />
| valign="top" |<br />
|<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1\bigcap R_2}} !! {{Формула|f=R_2 - R_1}} <br />
|- align="center"<br />
| rowspan="4" | {{Формула|f=\Pi_{R_2}(r)}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| ... || ...<br />
|- align="center"<br />
| {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
|}<br />
<br />
:Если выполняется равенство (3), то возможны два варианта:<br />
:1) {{Формула|f=b_i\neq b_j}}, {{Формула|f=i\neq j}};<br><br />
:2) некоторые {{Формула|f=b_i}} совпадают, {{Формула|f=b_1 = b_2}}.<br />
<br />
:Тогда для выполнения равенства (3) необходимо, чтобы выполнялось одно из двух:<br />
:* {{Формула|f=a_1 = a_2}};<br />
:* {{Формула|f=c_1 = c_2}}.<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcap R_2}} !! {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
| rowspan="6" | {{Формула|f=\Pi_{R_1}(r)\bowtie\Pi_{R_2}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_1}} || {{Формула|f=b_1(=b_2)}} || {{Формула|f=c_2}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2(=b_1)}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| {{Формула|f=a_3}} || {{Формула|f=b_3}} || {{Формула|f=c_3}}<br />
|- align="center"<br />
| ... || ... || ...<br />
|- align="center"<br />
| {{Формула|f=N+2}} || {{Формула|f=a_n}} || {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
<br />
:2 и 3 кортежи - лишние. Чтобы они не были лишними, они должны совпадать с одним из других кортежей, чтобы их можно было вычеркнуть.<br />
<br />
:Предположим, {{Формула|f=a_1 = a_2}}, тогда что-то там насовпадало и 2 и 3 кортежи можно вычеркнуть.<br />
<br />
:Аналогичные рассуждения можно провести для случая, когда {{Формула|f=c_1 = c_2}}, но тогда получаем:<br />
:* для варианта {{Формула|f=b_i\neq b_j}} имеют место обе ФЗ : (1) и (2);<br />
:* для варианта с некоторыми совпадающими {{Формула|f=b_i}} работает либо (1), либо (2).<br />
<br />
:Всё, теорема доказана.<br />
<br />
===== Следствие из теоремы =====<br />
<br />
Пусть {{Формула|f=R_1}} и {{Формула|f=R_2}} - это сущности БД и они связаны между собой. Тогда схема БД обладает соединением без потерь, если общий атрибут {{Формула|f=R_1}} и {{Формула|f=R_2}} содержит ключ одной из этих схем отношений.<br />
<br />
{{Формула|f=R_1\bigcap R_2 = A}}<br />
<br />
{{Формула|f=R_1 - R_2 = B}}<br />
<br />
{{Формула|f=R_1\bigcap R_2\rightarrow R_1 - R_2}}, потому что {{Формула|f=A\rightarrow B}}, так как является ключом.<br />
<br />
== Свойство сохранения ФЗ ==<br />
<br />
Пусть дана схема БД {{Формула|f=\rho=(R_1 ... R_n)}} и {{Формула|f=F}} - множество ФЗ.<br />
<br />
Проекцией {{Формула|f=F}} на {{Формула|f=R_i}} называется такое множество ФЗ, принадлежащее {{Формула|f=F^+}}, что {{Формула|f=XY\subseteq R_i}}, {{Формула|f=\Pi_{R_i}(F)}}<br />
<br />
Схема {{Формула|f=\rho}} обладает свойство сохранения ФЗ, если:<br />
<br />
{{Формула|f=(\bigcup_{i=1}^n\Pi_{R_i}(F))^+ = F^+}} - ФЗ могут быть декомпозированны по схеме отношений (тогда проверку надо будет выполнять только в рамках отдельных таблиц при включении новой записи).<br />
<br />
=== Пример схемы БД без свойства сохранения ФЗ ===<br />
<br />
{{Формула|f=R=(A,B,C)}} - универсальная схема отношений.<br />
<br />
{{Формула|f=F=(A\rightarrow B, B\rightarrow C)}}<br />
<br />
{{Формула|f=\rho=(AB, AC)=(R_1, R_2)}}<br />
<br />
Надо доказать, что {{Формула|f=\rho}} не обладает свойством сохранения ФЗ.<br />
<br />
Первая проекция: {{Формула|f=\Pi_{R_1}(F) = F_1 = (A\rightarrow A, B\rightarrow B, AB\rightarrow A, AB\rightarrow B, AB\rightarrow AB, A\rightarrow B, A\rightarrow AB)}}<br />
<br />
Вторая проекция: {{Формула|f=\Pi_{R_2}(F) = F_2 = (A\rightarrow A, C\rightarrow C, AC\rightarrow A, AC\rightarrow C, AC\rightarrow AC, A\rightarrow C, A\rightarrow AC)}}<br />
<br />
{{Формула|f=B\rightarrow C\in F^+}} по определению.<br />
<br />
{{Формула|f=B\rightarrow C\notin (F_1\bigcup F_2)^+}} - не работает, так что эта БД не обладает свойством сохранения ФЗ.<br />
<br />
{{Формула|f=B^+ = B}}, {{Формула|f=C\notin B^+}}<br />
<br />
=== Пример схемы БД со свойством сохранения ФЗ ===<br />
<br />
{{Формула|f=R=(A,B,C)}} - универсальная схема отношений.<br />
<br />
{{Формула|f=F=(A\rightarrow B, B\rightarrow C)}}<br />
<br />
{{Формула|f=\rho=(AB, BC)=(R_1, R_2)}}<br />
<br />
Надо доказать, что {{Формула|f=\rho}} обладает свойством сохранения ФЗ.<br />
<br />
Первая проекция: {{Формула|f=\Pi_{R_1}(F) = F_1 = (}}тривиальные ФЗ, {{Формула|f=A\rightarrow B, A\rightarrow AB)}}<br />
<br />
Вторая проекция: {{Формула|f=\Pi_{R_2}(F) = F_2 = (}}тривиальные ФЗ, {{Формула|f=B\rightarrow C, B\rightarrow BC)}}<br />
<br />
{{Формула|f=(F_1\bigcup F_2)^+ = (}}тривиальные ФЗ, {{Формула|f=A\rightarrow B, A\rightarrow AB, B\rightarrow C, B\rightarrow BC, A\rightarrow C, A\rightarrow AC)}}, а это и есть по определению само {{Формула|f=F^+}}, что и доказывает, что данная схема БД обладает свойством сохранения ФЗ.<br />
<br />
=== Алгоритм проверки схемы БД на обладание свойством сохранения ФЗ ===<br />
<br />
{{Формула|f=\rho = (R_1 ... R_n)}}<br />
<br />
Алгоритм:<br />
# построить условно-неизбыточное покрытие (УНП), взять {{Формула|f=H = \varnothing}};<br />
# каждую ФЗ из УНП заменить на совокупность ФЗ с одним атрибутом в правой части, то есть заменить {{Формула|f=X\rightarrow A_1}} ... {{Формула|f=X\rightarrow A_k}} на {{Формула|f=Y = A_1 ... A_k}}. Обозначить полученную ФЗ как {{Формула|f=G}};<br />
# выбрать очередную ФЗ из {{Формула|f=G}}. Найти такую схему отношения {{Формула|f=R_i}}, для которой справедливо включение {{Формула|f=XA\subseteq R_i}}. Если такой схемы отношений не существует, то поместить ФЗ {{Формула|f=X\rightarrow A}} в множество {{Формула|f=H}};<br />
# если все ФЗ из {{Формула|f=G}} рассмотрены, то перейти к следующему пункту, иначе к предыдущему;<br />
# если {{Формула|f=H}} пусто, то завершить алгоритм. <u>{{Формула|f=\rho}} обладает свойством сохранения ФЗ</u>. Иначе перейти к следующему пункту;<br />
# просмотреть все ФЗ из {{Формула|f=H}}. Если какая-либо ФЗ {{Формула|f=X\rightarrow A \in H}} не выводится из множества {{Формула|f=G - H}}, то завершить алгоритм. <u>{{Формула|f=\rho}} не обладает свойством сохранения ФЗ</u>. Иначе завершить алгоритм, и тогда <u>{{Формула|f=\rho}} обладает свойством сохранения ФЗ</u>.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%964_-_%D0%A5%D0%BE%D1%80%D0%BE%D1%88%D0%B0%D1%8F_%D1%81%D1%85%D0%B5%D0%BC%D0%B0_%D0%91%D0%94_-_%D0%A1%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A4%D0%97&diff=2543
ТОРА (9) - Лекция №4 - Хорошая схема БД - Сохранение ФЗ
2013-01-14T22:14:08Z
<p>81.9.52.28: /* Доказательство */</p>
<hr />
<div>Продолжение [[ТОРА_(9)_-_Лекция_№3_-_Хорошая_схема_БД_-_Соединение_без_потерь | предыдущей лекции]].<br />
<br />
== Свойства "хорошей" схемы БД ==<br />
<br />
=== Соединение без потерь ===<br />
<br />
==== Теорема о свойстве соединения без потерь ====<br />
<br />
Пусть {{Формула|f=\rho=(R_1, R_2)}} и {{Формула|f=F}} - множество ФЗ.<br />
<br />
{{Формула|f=\rho}} обладает свойством соединения без потерь тогда и только тогда, когда выполняется хотя бы одно из:<br />
* {{Формула|f=R_1\bigcap R_2\rightarrow R_1 - R_2}} (1)<br />
* {{Формула|f=R_1\bigcap R_2\rightarrow R_2 - R_1}} (2)<br />
<br />
===== Доказательство =====<br />
<br />
1)<br />
<br />
{| class="wikitable"<br />
! rowspan="2" | !! colspan="3" | {{Формула|f=R_1 - R_2}} !! colspan="3" | {{Формула|f=R_1\bigcap R_2}} || colspan="3" | {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
! {{Формула|f=A_1}} !! ... !! {{Формула|f=A_k}} !! {{Формула|f=A_{k+1} }} !! ... !! {{Формула|f=A_m}} !! {{Формула|f=A_{m+1} }} !! ... !! {{Формула|f=A_n}}<br />
|- align="center"<br />
| {{Формула|f=R_1}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=b_1}} || ... || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=R_2}} || {{Формула|f=b_2}} || ... || {{Формула|f=b_2}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}}<br />
|}<br />
<br />
{| class="wikitable"<br />
! rowspan="2" | !! colspan="3" | {{Формула|f=R_1 - R_2}} !! colspan="3" | {{Формула|f=R_1\bigcap R_2}} || colspan="3" | {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
! {{Формула|f=A_1}} !! ... !! {{Формула|f=A_k}} !! {{Формула|f=A_{k+1} }} !! ... !! {{Формула|f=A_m}} !! {{Формула|f=A_{m+1} }} !! ... !! {{Формула|f=A_n}}<br />
|- align="center"<br />
| {{Формула|f=R_1}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=b_1}} || ... || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=R_2}} || bgcolor="lime" | {{Формула|f=a}} || ... || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}} || {{Формула|f=a}} || ... || {{Формула|f=a}}<br />
|} <br />
<br />
:Получили строку, сплошь состоящую из {{Формула|f=a}}.<br />
<br />
2)<br />
<br />
:Теперь докажем обратное, что если {{Формула|f=\rho}} обладает соединением без потерь, то имеет место одна из ФЗ: (1) или (2).<br />
<br />
:{{Формула|f=r=\Pi_{R_1}(r)\bowtie\Pi_{R_2}(r)}} (3)<br />
<br />
:{{Формула|f=r}} - это {{Формула|f=R_1\bigcup R_2}} (экземпляр универсальной схемы отношений)<br />
<br />
{| class="wikitable"<br />
! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcap R_2}} !! {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
| {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| ... || ... || ...<br />
|- align="center"<br />
| {{Формула|f=a_n}} || {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
<br />
{|<br />
| valign="top" |<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcap R_2}}<br />
|- align="center"<br />
| rowspan="4" | {{Формула|f=\Pi_{R_1}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}}<br />
|- align="center"<br />
| ... || ...<br />
|- align="center"<br />
| {{Формула|f=a_n}} || {{Формула|f=b_n}}<br />
|}<br />
|<br />
| valign="top" |<br />
|<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1\bigcap R_2}} !! {{Формула|f=R_2 - R_1}} <br />
|- align="center"<br />
| rowspan="4" | {{Формула|f=\Pi_{R_2}(r)}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| ... || ...<br />
|- align="center"<br />
| {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
|}<br />
<br />
:Если выполняется равенство (3), то возможны два варианта:<br />
:1) {{Формула|f=b_i\neq b_j}}, {{Формула|f=i\neq j}};<br><br />
:2) некоторые {{Формула|f=b_i}} совпадают, {{Формула|f=b_1 = b_2}}.<br />
<br />
:Тогда для выполнения равенства (3) необходимо, чтобы выполнялось одно из двух:<br />
:* {{Формула|f=a_1 = a_2}};<br />
:* {{Формула|f=c_1 = c_2}}.<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=R_1 - R_2}} !! {{Формула|f=R_1\bigcup R_2}} !! {{Формула|f=R_2 - R_1}}<br />
|- align="center"<br />
| rowspan="6" | {{Формула|f=\Pi_{R_1}(r)\bowtie\Pi_{R_2}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_1}} || {{Формула|f=b_1(=b_2)}} || {{Формула|f=c_2}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2(=b_1)}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_2}} || {{Формула|f=c_2}}<br />
|- align="center"<br />
| {{Формула|f=a_3}} || {{Формула|f=b_3}} || {{Формула|f=c_3}}<br />
|- align="center"<br />
| ... || ... || ...<br />
|- align="center"<br />
| {{Формула|f=N+2}} || {{Формула|f=a_n}} || {{Формула|f=b_n}} || {{Формула|f=c_n}}<br />
|}<br />
<br />
:2 и 3 кортежи - лишние. Чтобы они не были лишними, они должны совпадать с одним из других кортежей, чтобы их можно было вычеркнуть.<br />
<br />
:Предположим, {{Формула|f=a_1 = a_2}}, тогда что-то там насовпадало и 2 и 3 кортежи можно вычеркнуть.<br />
<br />
:Аналогичные рассуждения можно провести для случая, когда {{Формула|f=c_1 = c_2}}, но тогда получаем:<br />
:* для варианта {{Формула|f=b_i\neq b_j}} имеют место обе ФЗ : (1) и (2);<br />
:* для варианта с некоторыми совпадающими {{Формула|f=b_i}} работает либо (1), либо (2).<br />
<br />
:Всё, теорема доказана.<br />
<br />
===== Следствие из теоремы =====<br />
<br />
Пусть {{Формула|f=R_1}} и {{Формула|f=R_2}} - это сущности БД и они связаны между собой. Тогда схема БД обладает соединением без потерь, если общий атрибут {{Формула|f=R_1}} и {{Формула|f=R_2}} содержит ключ одной из этих схем отношений.<br />
<br />
{{Формула|f=R_1\bigcap R_2 = A}}<br />
<br />
{{Формула|f=R_1 - R_2 = B}}<br />
<br />
{{Формула|f=R_1\bigcap R_2\rightarrow R_1 - R_2}}, потому что {{Формула|f=A\rightarrow B}}, так как является ключом.<br />
<br />
== Свойство сохранения ФЗ ==<br />
<br />
Пусть дана схема БД {{Формула|f=\rho=(R_1 ... R_n)}} и {{Формула|f=F}} - множество ФЗ.<br />
<br />
Проекцией {{Формула|f=F}} на {{Формула|f=R_i}} называется такое множество ФЗ, принадлежащее {{Формула|f=F^+}}, что {{Формула|f=XY\subseteq R_i}}, {{Формула|f=\Pi_{R_i}(F)}}<br />
<br />
Схема {{Формула|f=\rho}} обладает свойство сохранения ФЗ, если:<br />
<br />
{{Формула|f=(\bigcup_{i=1}^n\Pi_{R_i}(F))^+ = F^+}} - ФЗ могут быть декомпозированны по схеме отношений (тогда проверку надо будет выполнять только в рамках отдельных таблиц при включении новой записи).<br />
<br />
=== Пример схемы БД без свойства сохранения ФЗ ===<br />
<br />
{{Формула|f=R=(A,B,C)}} - универсальная схема отношений.<br />
<br />
{{Формула|f=F=(A\rightarrow B, B\rightarrow C)}}<br />
<br />
{{Формула|f=\rho=(AB, AC)=(R_1, R_2)}}<br />
<br />
Надо доказать, что {{Формула|f=\rho}} не обладает свойством сохранения ФЗ.<br />
<br />
Первая проекция: {{Формула|f=\Pi_{R_1}(F) = F_1 = (A\rightarrow A, B\rightarrow B, AB\rightarrow A, AB\rightarrow B, AB\rightarrow AB, A\rightarrow B, A\rightarrow AB)}}<br />
<br />
Вторая проекция: {{Формула|f=\Pi_{R_2}(F) = F_2 = (A\rightarrow A, C\rightarrow C, AC\rightarrow A, AC\rightarrow C, AC\rightarrow AC, A\rightarrow C, A\rightarrow AC)}}<br />
<br />
{{Формула|f=B\rightarrow C\in F^+}} по определению.<br />
<br />
{{Формула|f=B\rightarrow C\notin (F_1\bigcup F_2)^+}} - не работает, так что эта БД не обладает свойством сохранения ФЗ.<br />
<br />
{{Формула|f=B^+ = B}}, {{Формула|f=C\notin B^+}}<br />
<br />
=== Пример схемы БД со свойством сохранения ФЗ ===<br />
<br />
{{Формула|f=R=(A,B,C)}} - универсальная схема отношений.<br />
<br />
{{Формула|f=F=(A\rightarrow B, B\rightarrow C)}}<br />
<br />
{{Формула|f=\rho=(AB, BC)=(R_1, R_2)}}<br />
<br />
Надо доказать, что {{Формула|f=\rho}} обладает свойством сохранения ФЗ.<br />
<br />
Первая проекция: {{Формула|f=\Pi_{R_1}(F) = F_1 = (}}тривиальные ФЗ, {{Формула|f=A\rightarrow B, A\rightarrow AB)}}<br />
<br />
Вторая проекция: {{Формула|f=\Pi_{R_2}(F) = F_2 = (}}тривиальные ФЗ, {{Формула|f=B\rightarrow C, B\rightarrow BC)}}<br />
<br />
{{Формула|f=(F_1\bigcup F_2)^+ = (}}тривиальные ФЗ, {{Формула|f=A\rightarrow B, A\rightarrow AB, B\rightarrow C, B\rightarrow BC, A\rightarrow C, A\rightarrow AC)}}, а это и есть по определению само {{Формула|f=F^+}}, что и доказывает, что данная схема БД обладает свойством сохранения ФЗ.<br />
<br />
=== Алгоритм проверки схемы БД на обладание свойством сохранения ФЗ ===<br />
<br />
{{Формула|f=\rho = (R_1 ... R_n)}}<br />
<br />
Алгоритм:<br />
# построить условно-неизбыточное покрытие (УНП), взять {{Формула|f=H = \varnothing}};<br />
# каждую ФЗ из УНП заменить на совокупность ФЗ с одним атрибутом в правой части, то есть заменить {{Формула|f=X\rightarrow A_1}} ... {{Формула|f=X\rightarrow A_k}} на {{Формула|f=Y = A_1 ... A_k}}. Обозначить полученную ФЗ как {{Формула|f=G}};<br />
# выбрать очередную ФЗ из {{Формула|f=G}}. Найти такую схему отношения {{Формула|f=R_i}}, для которой справедливо включение {{Формула|f=XA\subseteq R_i}}. Если такой схемы отношений не существует, то поместить ФЗ {{Формула|f=X\rightarrow A}} в множество {{Формула|f=H}};<br />
# если все ФЗ из {{Формула|f=G}} рассмотрены, то перейти к следующему пункту, иначе к предыдущему;<br />
# если {{Формула|f=H}} пусто, то завершить алгоритм. <u>{{Формула|f=\rho}} обладает свойством сохранения ФЗ</u>. Иначе перейти к следующему пункту;<br />
# просмотреть все ФЗ из {{Формула|f=H}}. Если какая-либо ФЗ {{Формула|f=X\rightarrow A \in H}} не выводится из множества {{Формула|f=G - H}}, то завершить алгоритм. <u>{{Формула|f=\rho}} не обладает свойством сохранения ФЗ</u>. Иначе завершить алгоритм, и тогда <u>{{Формула|f=\rho}} обладает свойством сохранения ФЗ</u>.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%969_-_%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&diff=2518
ТОРА (9) - Лекция №9 - Оптимизация запросов
2013-01-13T22:15:44Z
<p>81.9.52.28: /* Построение логического плана */</p>
<hr />
<div>Оригинал всего раздела, посвящённого оптимизации SQL-запросов, от самого [[Григорьев Ю.А. | Григорьева]] можно загрузить [http://yadi.sk/d/VjjMs6ww1HH2D здесь].<br />
__TOC__<br />
== Оптимизация SQL-запросов ==<br />
<br />
Запрос, поступающий в СУБД, подвергается оптимизации с целью уменьшения времени его выполнения.<br />
<br />
Шаги оптимизатора:<br />
# строится логический план выполнения запроса (дерево логических операций);<br />
# на основе логического плана строится физический план выполнения запроса (дерево физических операций);<br />
# реализация этого физического плана.<br />
<br />
=== Законы реляционной алгебры ===<br />
<br />
==== Закон коммутативности декартова произведения отношений ====<br />
<br />
{{Формула|f=R_1\times R_2 = R_2\times R_1}}, здесь и далее {{Формула|f=R_1}} и {{Формула|f=R_2}} - экземпляры отношений.<br />
<br />
==== Закон ассоциативности декартова произведения ====<br />
<br />
{{Формула|f=(R_1\times R_2)\times R_3 = R_1\times (R_2\times R_3)}}<br />
<br />
==== Закон каскада проекций ====<br />
<br />
Допустим, {{Формула|f=(a_1 ... a_n)\subseteq (b_1 ... b_n)}}, {{Формула|f={a_i} }}, {{Формула|f={b_i} }} - это атрибуты отношения {{Формула|f=R}}<br />
<br />
тогда {{Формула|f=\Pi_{a_1 ... a_n}(\Pi_{b_1 ... b_n}(R)) = \Pi_{a_1 ... a_n}(R)}}<br />
<br />
==== Закон каскада селекций ====<br />
<br />
Допустим, {{Формула|f=F = f_1\wedge f_2}}<br />
<br />
тогда {{Формула|f=\sigma_F(R) = \sigma_{f_1}(\sigma_{f_2}(R))}}<br />
<br />
==== Закон перестановки проекции и селекции ====<br />
<br />
1)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты только из множества {{Формула|f=a_1 ... a_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \sigma_F(\Pi_{a_1 ... a_n}(R))}}<br />
<br />
2)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты не только из множества {{Формула|f=a_1 ... a_n}}, но и из {{Формула|f=b_1 ... b_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \Pi_{a_1 ... a_n}(\sigma_F(\Pi_{a_1 ... a_n, b_1 ... b_n}(R)))}}<br />
<br />
==== Селекция декартова произведения ====<br />
<br />
Отношение {{Формула|f=f_1}} содержит атрибуты только из отношения {{Формула|f=R_1}}<br />
<br />
тогда {{Формула|f=\sigma_{f_1}(R_1\times R_2) = \sigma_{f_1}(R_1)\times R_2}}<br />
<br />
:Следствие:<br />
:пусть {{Формула|f=F = f_1 \wedge f_2}} и в {{Формула|f=f_1}} входят атрибуты {{Формула|f=R_1}}, а в {{Формула|f=f_2}} входят из {{Формула|f=R_2}},<br />
:тогда {{Формула|f=\sigma_{F}(R_1\times R_2) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
::Доказательство:<br />
::{{Формула|f=\sigma_{f_1 \wedge f_2}(R_1\times R_2) = \sigma_{f_1}(\sigma_{f_2}(R_1\times R_2)) = \sigma_{f_1}(\sigma_{f_2}(R_2\times R_1))=}}<br />
::{{Формула|f== \sigma_{f_1}(R_1\times\sigma_{f_2}(R_2)) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
<br />
==== Закон перестановки селекции и объединения ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1\bigcup R_2) = \sigma_{F}(R_1)\bigcup\sigma_{F}(R_2)}}<br />
<br />
==== Закон перестановки селекции и разности отношений ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1 - R_2) = \sigma_{F}(R_1) - \sigma_{F}(R_2)}}<br />
<br />
==== Закон перестановки проекции и декартова произведения ====<br />
<br />
{{Формула|f=b_1 ... b_n}} - это атрибуты отношения {{Формула|f=R_1}}<br />
<br />
{{Формула|f=c_1 ... c_k}} - это атрибуты отношения {{Формула|f=R_2}}<br />
<br />
{{Формула|f=\Pi_{b_1 ... b_n, c_1 ... c_k}(R_1\times R_2)}} = {{Формула|f=\Pi_{b_1 ... b_n}(R_1)\times \Pi_{c_1 ... c_k}(R_2)}}<br />
<br />
==== Закон перестановки проекции и объединения ====<br />
<br />
{{Формула|f=\Pi_{a_1 ... a_n}(R_1\bigcup R_2) = \Pi_{a_1 ... a_n}(R_1)\bigcup\Pi_{a_1 ... a_n}(R_2)}}<br />
<br />
=== Оптимизация формул реляционной алгебры ===<br />
<br />
Пусть условие {{Формула|f=F = f_1 \wedge ... \wedge f_n}}<br />
<br />
Правила:<br />
# переместить каждую селекцию внутрь декартова произведения, используя законы 1, 4, 6, 7, 8;<br />
# переместить каждую проекцию внутрь декартова произведения, используя законы 1, 3, 5, 9, 10;<br />
# по возможности скомбинировать каждый каскад селекции в одиночную селекцию и каждый каскад проекции в одиночную проекцию. Тогда всё можно будет сделать за один проход.<br />
<br />
После выполнения этих трёх правил выражение {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}} преобразуется к виду:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>{{Формула|f=\times ...\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span>{{Формула|f=))}},<br />
<br />
здесь <span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>, <span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span> и прочие - ''подзапросы''. Суть в том, что сначала выполняются подзапросы, а они имеют намного меньшую размерность, чем исходная таблица, и время выполнения будет меньше, чем по исходной формуле {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}.<br />
<br />
=== Логический план ===<br />
<br />
==== Построение логического плана ====<br />
<br />
Порядок построения:<br />
# запрос преобразуется в формулу реляционной алгебры;<br />
# выполняется преобразование (оптимизация) этой формулы.<br />
<br />
Оператор <code>SELECT</code> (без агрегирования, группирования и удаления дубликатов) может быть представлен так:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}, где<br />
:от {{Формула|f=R_1}} до {{Формула|f=R_n}} - это декартово произведение отношений (таблиц), указанных за ключевым словом <code>FROM</code>;<br />
:{{Формула|f=\sigma_F}} - это селекция кортежей декартова произведения в соответствии с условием, указанным за ключевым словом <code>WHERE</code>;<br />
:{{Формула|f=\Pi_A}} - это проекция селекции на множество атрибутов A, указанных за ключевым словом <code>SELECT</code><br />
<br />
В чём суть такой логической оптимизации? Сначала надо выполнить декартово произведение, потом селекцию, потом проекцию - всё по порядку скобок в этом выражении. Потому что если таблица имеет большой размер, то это выражение будет выполняться очень долго.<br />
<br />
Пример: найти фамилии поставщиков, поставляющих детали с названием "винт".<br />
<br />
{{Формула|f=\rho = (S, P, SP)}}<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT фамилия<br />
FROM S, P, SP<br />
WHERE P.название = 'винт' AND<br />
S.номер_поставки = SP.номер_поставки AND<br />
SP.номер_детали = P.номер_детали;<br />
</syntaxhighlight><br />
<br />
{{Формула|f=\Pi_{фамилия}(\sigma_{P.н="винт" \wedge S.н-п=SP.н-п \wedge SP.н-д=P.н-д}(S\times P\times SP))}}<br />
<br />
[[#Оптимизация формул реляционной алгебры | Полученную]] {{Формула|f=\Pi_A(\sigma_F(\Pi_{A_i}(\sigma_{f_2}(R_1))\times ...\times \Pi_{A_n}(\sigma_{f_n}(R_n))))}} можно представить в графическом виде - это и будет ''логический план выполнения запроса'':<br />
<br />
[[Файл:9sTORAl9pic1.png|400px]]<br />
<br />
Получается, подзапросы можно выполнять параллельно, а это тоже уменьшает время выполнения всего запроса.<br />
<br />
Пример:<br />
<br />
[[Файл:9sTORAl9pic2.png|link=Файл:9sTORAl9pic2.svg]]<br />
<br />
Запрос найти значение остатков больше 1500 на счетах пользователя с кодом 3:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT остаток<br />
FROM R2<br />
WHERE остаток > 1500 AND<br />
номер_счёта IN(<br />
SELECT номер_счёта<br />
FROM R1<br />
WHERE код_пользователя = 3<br />
);<br />
</syntaxhighlight><br />
<br />
Этот запрос преобразуется сервером в неявном виде в формулу реляционной алгебры:<br />
<br />
{{Формула|f=\Pi_{остаток}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3 \wedge R_1.н-c=R_2.н-с})}}<br />
<br />
Теперь оптимизируем:<br />
<br />
{{Формула|f==^4\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3}(R_1\times R_2)))=^6}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2)=^{5, 2} }}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\Pi_{остаток, R_1.н-с, R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2))=^9}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{R_1.н-с}(\sigma_{R_1.к-п=3}(R_1))}}</span>{{Формула|f=\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{R_2.н-с, остаток}(\sigma_{R_2.о>1500}(R_2))}}</span>{{Формула|f=))}}<br />
<br />
Полученное выражение - результат оптимизации. Можно построить логический план выполнения запроса.<br />
<br />
[[Файл:9sTORAl9pic3.png|400px]]<br />
<br />
{{Forward|l=ТОРА (9) - Лекция №10 - Логический и физический план запроса}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%969_-_%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&diff=2517
ТОРА (9) - Лекция №9 - Оптимизация запросов
2013-01-13T21:24:06Z
<p>81.9.52.28: /* Закон перестановки селекции и разности отношений */</p>
<hr />
<div>Оригинал всего раздела, посвящённого оптимизации SQL-запросов, от самого [[Григорьев Ю.А. | Григорьева]] можно загрузить [http://yadi.sk/d/VjjMs6ww1HH2D здесь].<br />
__TOC__<br />
== Оптимизация SQL-запросов ==<br />
<br />
Запрос, поступающий в СУБД, подвергается оптимизации с целью уменьшения времени его выполнения.<br />
<br />
Шаги оптимизатора:<br />
# строится логический план выполнения запроса (дерево логических операций);<br />
# на основе логического плана строится физический план выполнения запроса (дерево физических операций);<br />
# реализация этого физического плана.<br />
<br />
=== Законы реляционной алгебры ===<br />
<br />
==== Закон коммутативности декартова произведения отношений ====<br />
<br />
{{Формула|f=R_1\times R_2 = R_2\times R_1}}, здесь и далее {{Формула|f=R_1}} и {{Формула|f=R_2}} - экземпляры отношений.<br />
<br />
==== Закон ассоциативности декартова произведения ====<br />
<br />
{{Формула|f=(R_1\times R_2)\times R_3 = R_1\times (R_2\times R_3)}}<br />
<br />
==== Закон каскада проекций ====<br />
<br />
Допустим, {{Формула|f=(a_1 ... a_n)\subseteq (b_1 ... b_n)}}, {{Формула|f={a_i} }}, {{Формула|f={b_i} }} - это атрибуты отношения {{Формула|f=R}}<br />
<br />
тогда {{Формула|f=\Pi_{a_1 ... a_n}(\Pi_{b_1 ... b_n}(R)) = \Pi_{a_1 ... a_n}(R)}}<br />
<br />
==== Закон каскада селекций ====<br />
<br />
Допустим, {{Формула|f=F = f_1\wedge f_2}}<br />
<br />
тогда {{Формула|f=\sigma_F(R) = \sigma_{f_1}(\sigma_{f_2}(R))}}<br />
<br />
==== Закон перестановки проекции и селекции ====<br />
<br />
1)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты только из множества {{Формула|f=a_1 ... a_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \sigma_F(\Pi_{a_1 ... a_n}(R))}}<br />
<br />
2)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты не только из множества {{Формула|f=a_1 ... a_n}}, но и из {{Формула|f=b_1 ... b_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \Pi_{a_1 ... a_n}(\sigma_F(\Pi_{a_1 ... a_n, b_1 ... b_n}(R)))}}<br />
<br />
==== Селекция декартова произведения ====<br />
<br />
Отношение {{Формула|f=f_1}} содержит атрибуты только из отношения {{Формула|f=R_1}}<br />
<br />
тогда {{Формула|f=\sigma_{f_1}(R_1\times R_2) = \sigma_{f_1}(R_1)\times R_2}}<br />
<br />
:Следствие:<br />
:пусть {{Формула|f=F = f_1 \wedge f_2}} и в {{Формула|f=f_1}} входят атрибуты {{Формула|f=R_1}}, а в {{Формула|f=f_2}} входят из {{Формула|f=R_2}},<br />
:тогда {{Формула|f=\sigma_{F}(R_1\times R_2) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
::Доказательство:<br />
::{{Формула|f=\sigma_{f_1 \wedge f_2}(R_1\times R_2) = \sigma_{f_1}(\sigma_{f_2}(R_1\times R_2)) = \sigma_{f_1}(\sigma_{f_2}(R_2\times R_1))=}}<br />
::{{Формула|f== \sigma_{f_1}(R_1\times\sigma_{f_2}(R_2)) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
<br />
==== Закон перестановки селекции и объединения ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1\bigcup R_2) = \sigma_{F}(R_1)\bigcup\sigma_{F}(R_2)}}<br />
<br />
==== Закон перестановки селекции и разности отношений ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1 - R_2) = \sigma_{F}(R_1) - \sigma_{F}(R_2)}}<br />
<br />
==== Закон перестановки проекции и декартова произведения ====<br />
<br />
{{Формула|f=b_1 ... b_n}} - это атрибуты отношения {{Формула|f=R_1}}<br />
<br />
{{Формула|f=c_1 ... c_k}} - это атрибуты отношения {{Формула|f=R_2}}<br />
<br />
{{Формула|f=\Pi_{b_1 ... b_n, c_1 ... c_k}(R_1\times R_2)}} = {{Формула|f=\Pi_{b_1 ... b_n}(R_1)\times \Pi_{c_1 ... c_k}(R_2)}}<br />
<br />
==== Закон перестановки проекции и объединения ====<br />
<br />
{{Формула|f=\Pi_{a_1 ... a_n}(R_1\bigcup R_2) = \Pi_{a_1 ... a_n}(R_1)\bigcup\Pi_{a_1 ... a_n}(R_2)}}<br />
<br />
=== Оптимизация формул реляционной алгебры ===<br />
<br />
Пусть условие {{Формула|f=F = f_1 \wedge ... \wedge f_n}}<br />
<br />
Правила:<br />
# переместить каждую селекцию внутрь декартова произведения, используя законы 1, 4, 6, 7, 8;<br />
# переместить каждую проекцию внутрь декартова произведения, используя законы 1, 3, 5, 9, 10;<br />
# по возможности скомбинировать каждый каскад селекции в одиночную селекцию и каждый каскад проекции в одиночную проекцию. Тогда всё можно будет сделать за один проход.<br />
<br />
После выполнения этих трёх правил выражение {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}} преобразуется к виду:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>{{Формула|f=\times ...\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span>{{Формула|f=))}},<br />
<br />
здесь <span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>, <span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span> и прочие - ''подзапросы''. Суть в том, что сначала выполняются подзапросы, а они имеют намного меньшую размерность, чем исходная таблица, и время выполнения будет меньше, чем по исходной формуле {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}.<br />
<br />
=== Логический план ===<br />
<br />
==== Построение логического плана ====<br />
<br />
Порядок построения:<br />
# запрос преобразуется в формулу реляционной алгебры;<br />
# выполняется преобразование (оптимизация) этой формулы.<br />
<br />
Оператор <code>SELECT</code> (без агрегирования, группирования и удаления дубликатов) может быть представлен так:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}, где<br />
:от {{Формула|f=R_1}} до {{Формула|f=R_n}} - это декартово произведение отношений (таблиц), указанных за ключевым словом <code>FROM</code>;<br />
:{{Формула|f=\sigma_F}} - это селекция кортежей декартова произведения в соответствии с условием, указанным за ключевым словом <code>WHERE</code>;<br />
:{{Формула|f=\Pi_A}} - это проекция селекции на множество атрибутов A, указанных за ключевым словом <code>SELECT</code><br />
<br />
В чём суть такой логической оптимизации? Сначала надо выполнить декартово произведение, потом селекцию, потом проекцию - всё по порядку скобок в этом выражении. Потому что если таблица имеет большой размер, то это выражение будет выполняться очень долго.<br />
<br />
Пример: найти фамилии поставщиков, поставляющих детали с названием "винт".<br />
<br />
{{Формула|f=\rho = (S, P, SP)}}<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT фамилия<br />
FROM S, P, SP<br />
WHERE P.название = 'винт' AND<br />
S.номер_поставки = SP.номер_поставки AND<br />
SP.номер_детали = P.номер_детали;<br />
</syntaxhighlight><br />
<br />
{{Формула|f=\Pi_{фамилия}(\sigma_{P.н="винт" \wedge S.н-п=SP.н-п \wedge SP.н-д=P.н-д})}}<br />
<br />
[[#Оптимизация формул реляционной алгебры | Полученную]] {{Формула|f=\Pi_A(\sigma_F(\Pi_{A_i}(\sigma_{f_2}(R_1))\times ...\times \Pi_{A_n}(\sigma_{f_n}(R_n))))}} можно представить в графическом виде - это и будет ''логический план выполнения запроса'':<br />
<br />
[[Файл:9sTORAl9pic1.png|400px]]<br />
<br />
Получается, подзапросы можно выполнять параллельно, а это тоже уменьшает время выполнения всего запроса.<br />
<br />
Пример:<br />
<br />
[[Файл:9sTORAl9pic2.png|link=Файл:9sTORAl9pic2.svg]]<br />
<br />
Запрос найти значение остатков больше 1500 на счетах пользователя с кодом 3:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT остаток<br />
FROM R2<br />
WHERE остаток > 1500 AND<br />
номер_счёта IN(<br />
SELECT номер_счёта<br />
FROM R1<br />
WHERE код_пользователя = 3<br />
);<br />
</syntaxhighlight><br />
<br />
Этот запрос преобразуется сервером в неявном виде в формулу реляционной алгебры:<br />
<br />
{{Формула|f=\Pi_{остаток}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3 \wedge R_1.н-c=R_2.н-с})}}<br />
<br />
Теперь оптимизируем:<br />
<br />
{{Формула|f==^4\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3}(R_1\times R_2)))=^6}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2)=^{5, 2} }}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\Pi_{остаток, R_1.н-с, R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2))=^9}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{R_1.н-с}(\sigma_{R_1.к-п=3}(R_1))}}</span>{{Формула|f=\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{R_2.н-с, остаток}(\sigma_{R_2.о>1500}(R_2))}}</span>{{Формула|f=))}}<br />
<br />
Полученное выражение - результат оптимизации. Можно построить логический план выполнения запроса.<br />
<br />
[[Файл:9sTORAl9pic3.png|400px]]<br />
<br />
{{Forward|l=ТОРА (9) - Лекция №10 - Логический и физический план запроса}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%969_-_%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&diff=2516
ТОРА (9) - Лекция №9 - Оптимизация запросов
2013-01-13T21:23:46Z
<p>81.9.52.28: /* Закон перестановки селекции и объединения */</p>
<hr />
<div>Оригинал всего раздела, посвящённого оптимизации SQL-запросов, от самого [[Григорьев Ю.А. | Григорьева]] можно загрузить [http://yadi.sk/d/VjjMs6ww1HH2D здесь].<br />
__TOC__<br />
== Оптимизация SQL-запросов ==<br />
<br />
Запрос, поступающий в СУБД, подвергается оптимизации с целью уменьшения времени его выполнения.<br />
<br />
Шаги оптимизатора:<br />
# строится логический план выполнения запроса (дерево логических операций);<br />
# на основе логического плана строится физический план выполнения запроса (дерево физических операций);<br />
# реализация этого физического плана.<br />
<br />
=== Законы реляционной алгебры ===<br />
<br />
==== Закон коммутативности декартова произведения отношений ====<br />
<br />
{{Формула|f=R_1\times R_2 = R_2\times R_1}}, здесь и далее {{Формула|f=R_1}} и {{Формула|f=R_2}} - экземпляры отношений.<br />
<br />
==== Закон ассоциативности декартова произведения ====<br />
<br />
{{Формула|f=(R_1\times R_2)\times R_3 = R_1\times (R_2\times R_3)}}<br />
<br />
==== Закон каскада проекций ====<br />
<br />
Допустим, {{Формула|f=(a_1 ... a_n)\subseteq (b_1 ... b_n)}}, {{Формула|f={a_i} }}, {{Формула|f={b_i} }} - это атрибуты отношения {{Формула|f=R}}<br />
<br />
тогда {{Формула|f=\Pi_{a_1 ... a_n}(\Pi_{b_1 ... b_n}(R)) = \Pi_{a_1 ... a_n}(R)}}<br />
<br />
==== Закон каскада селекций ====<br />
<br />
Допустим, {{Формула|f=F = f_1\wedge f_2}}<br />
<br />
тогда {{Формула|f=\sigma_F(R) = \sigma_{f_1}(\sigma_{f_2}(R))}}<br />
<br />
==== Закон перестановки проекции и селекции ====<br />
<br />
1)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты только из множества {{Формула|f=a_1 ... a_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \sigma_F(\Pi_{a_1 ... a_n}(R))}}<br />
<br />
2)<br />
<br />
: Допустим, в условия поиска {{Формула|f=F}} входят атрибуты не только из множества {{Формула|f=a_1 ... a_n}}, но и из {{Формула|f=b_1 ... b_n}}<br />
: тогда {{Формула|f=\Pi_{a_1 ... a_n}(\sigma_F(R)) = \Pi_{a_1 ... a_n}(\sigma_F(\Pi_{a_1 ... a_n, b_1 ... b_n}(R)))}}<br />
<br />
==== Селекция декартова произведения ====<br />
<br />
Отношение {{Формула|f=f_1}} содержит атрибуты только из отношения {{Формула|f=R_1}}<br />
<br />
тогда {{Формула|f=\sigma_{f_1}(R_1\times R_2) = \sigma_{f_1}(R_1)\times R_2}}<br />
<br />
:Следствие:<br />
:пусть {{Формула|f=F = f_1 \wedge f_2}} и в {{Формула|f=f_1}} входят атрибуты {{Формула|f=R_1}}, а в {{Формула|f=f_2}} входят из {{Формула|f=R_2}},<br />
:тогда {{Формула|f=\sigma_{F}(R_1\times R_2) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
::Доказательство:<br />
::{{Формула|f=\sigma_{f_1 \wedge f_2}(R_1\times R_2) = \sigma_{f_1}(\sigma_{f_2}(R_1\times R_2)) = \sigma_{f_1}(\sigma_{f_2}(R_2\times R_1))=}}<br />
::{{Формула|f== \sigma_{f_1}(R_1\times\sigma_{f_2}(R_2)) = \sigma_{f_1}(R_1)\times \sigma_{f_2}(R_2)}}<br />
<br />
==== Закон перестановки селекции и объединения ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1\bigcup R_2) = \sigma_{F}(R_1)\bigcup\sigma_{F}(R_2)}}<br />
<br />
==== Закон перестановки селекции и разности отношений ====<br />
<br />
{{Формула|f=\sigma_{F}(R_1 - R_2) = \sigma_{f_1}(R_1) - \sigma_{f_2}(R_2)}}<br />
<br />
==== Закон перестановки проекции и декартова произведения ====<br />
<br />
{{Формула|f=b_1 ... b_n}} - это атрибуты отношения {{Формула|f=R_1}}<br />
<br />
{{Формула|f=c_1 ... c_k}} - это атрибуты отношения {{Формула|f=R_2}}<br />
<br />
{{Формула|f=\Pi_{b_1 ... b_n, c_1 ... c_k}(R_1\times R_2)}} = {{Формула|f=\Pi_{b_1 ... b_n}(R_1)\times \Pi_{c_1 ... c_k}(R_2)}}<br />
<br />
==== Закон перестановки проекции и объединения ====<br />
<br />
{{Формула|f=\Pi_{a_1 ... a_n}(R_1\bigcup R_2) = \Pi_{a_1 ... a_n}(R_1)\bigcup\Pi_{a_1 ... a_n}(R_2)}}<br />
<br />
=== Оптимизация формул реляционной алгебры ===<br />
<br />
Пусть условие {{Формула|f=F = f_1 \wedge ... \wedge f_n}}<br />
<br />
Правила:<br />
# переместить каждую селекцию внутрь декартова произведения, используя законы 1, 4, 6, 7, 8;<br />
# переместить каждую проекцию внутрь декартова произведения, используя законы 1, 3, 5, 9, 10;<br />
# по возможности скомбинировать каждый каскад селекции в одиночную селекцию и каждый каскад проекции в одиночную проекцию. Тогда всё можно будет сделать за один проход.<br />
<br />
После выполнения этих трёх правил выражение {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}} преобразуется к виду:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>{{Формула|f=\times ...\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span>{{Формула|f=))}},<br />
<br />
здесь <span style="background-color:#32CD32">{{Формула|f=\Pi_{A_i}(\sigma_{f_2}(R_1))}}</span>, <span style="background-color:#00BFFF">{{Формула|f=\Pi_{A_n}(\sigma_{f_n}(R_n))}}</span> и прочие - ''подзапросы''. Суть в том, что сначала выполняются подзапросы, а они имеют намного меньшую размерность, чем исходная таблица, и время выполнения будет меньше, чем по исходной формуле {{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}.<br />
<br />
=== Логический план ===<br />
<br />
==== Построение логического плана ====<br />
<br />
Порядок построения:<br />
# запрос преобразуется в формулу реляционной алгебры;<br />
# выполняется преобразование (оптимизация) этой формулы.<br />
<br />
Оператор <code>SELECT</code> (без агрегирования, группирования и удаления дубликатов) может быть представлен так:<br />
<br />
{{Формула|f=\Pi_A(\sigma_F(R_1\times ...\times R_n))}}, где<br />
:от {{Формула|f=R_1}} до {{Формула|f=R_n}} - это декартово произведение отношений (таблиц), указанных за ключевым словом <code>FROM</code>;<br />
:{{Формула|f=\sigma_F}} - это селекция кортежей декартова произведения в соответствии с условием, указанным за ключевым словом <code>WHERE</code>;<br />
:{{Формула|f=\Pi_A}} - это проекция селекции на множество атрибутов A, указанных за ключевым словом <code>SELECT</code><br />
<br />
В чём суть такой логической оптимизации? Сначала надо выполнить декартово произведение, потом селекцию, потом проекцию - всё по порядку скобок в этом выражении. Потому что если таблица имеет большой размер, то это выражение будет выполняться очень долго.<br />
<br />
Пример: найти фамилии поставщиков, поставляющих детали с названием "винт".<br />
<br />
{{Формула|f=\rho = (S, P, SP)}}<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT фамилия<br />
FROM S, P, SP<br />
WHERE P.название = 'винт' AND<br />
S.номер_поставки = SP.номер_поставки AND<br />
SP.номер_детали = P.номер_детали;<br />
</syntaxhighlight><br />
<br />
{{Формула|f=\Pi_{фамилия}(\sigma_{P.н="винт" \wedge S.н-п=SP.н-п \wedge SP.н-д=P.н-д})}}<br />
<br />
[[#Оптимизация формул реляционной алгебры | Полученную]] {{Формула|f=\Pi_A(\sigma_F(\Pi_{A_i}(\sigma_{f_2}(R_1))\times ...\times \Pi_{A_n}(\sigma_{f_n}(R_n))))}} можно представить в графическом виде - это и будет ''логический план выполнения запроса'':<br />
<br />
[[Файл:9sTORAl9pic1.png|400px]]<br />
<br />
Получается, подзапросы можно выполнять параллельно, а это тоже уменьшает время выполнения всего запроса.<br />
<br />
Пример:<br />
<br />
[[Файл:9sTORAl9pic2.png|link=Файл:9sTORAl9pic2.svg]]<br />
<br />
Запрос найти значение остатков больше 1500 на счетах пользователя с кодом 3:<br />
<br />
<syntaxhighlight lang="sql"><br />
SELECT остаток<br />
FROM R2<br />
WHERE остаток > 1500 AND<br />
номер_счёта IN(<br />
SELECT номер_счёта<br />
FROM R1<br />
WHERE код_пользователя = 3<br />
);<br />
</syntaxhighlight><br />
<br />
Этот запрос преобразуется сервером в неявном виде в формулу реляционной алгебры:<br />
<br />
{{Формула|f=\Pi_{остаток}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3 \wedge R_1.н-c=R_2.н-с})}}<br />
<br />
Теперь оптимизируем:<br />
<br />
{{Формула|f==^4\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_2.о>1500 \wedge R_1.к-п=3}(R_1\times R_2)))=^6}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2)=^{5, 2} }}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(\Pi_{остаток, R_1.н-с, R_2.н-с}(\sigma_{R_1.к-п=3}(R_1)\times\sigma_{R_2.о>1500}(R_2))=^9}}<br />
<br />
{{Формула|f==\Pi_{остаток}(\sigma_{R_1.н-c=R_2.н-с}(}}<span style="background-color:#32CD32">{{Формула|f=\Pi_{R_1.н-с}(\sigma_{R_1.к-п=3}(R_1))}}</span>{{Формула|f=\times}}<span style="background-color:#00BFFF">{{Формула|f=\Pi_{R_2.н-с, остаток}(\sigma_{R_2.о>1500}(R_2))}}</span>{{Формула|f=))}}<br />
<br />
Полученное выражение - результат оптимизации. Можно построить логический план выполнения запроса.<br />
<br />
[[Файл:9sTORAl9pic3.png|400px]]<br />
<br />
{{Forward|l=ТОРА (9) - Лекция №10 - Логический и физический план запроса}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%966_-_%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D1%85%D0%BE%D1%80%D0%BE%D1%88%D0%B5%D0%B9_%D0%91%D0%94&diff=2497
ТОРА (9) - Лекция №6 - Алгоритм построения хорошей БД
2013-01-12T21:12:57Z
<p>81.9.52.28: /* Алгоритм синтеза "хорошей" БД */</p>
<hr />
<div>== Третья нормальная форма ==<br />
<br />
=== Пример аномалий у 3НФ ===<br />
<br />
{{Формула|f=R = (A, B, C, D)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow A, AC\rightarrow D)}}<br />
<br />
Два ключа: {{Формула|f=AC}} и {{Формула|f=BC}}<br />
<br />
{{Формула|f=(AC)^+=ACBD}}, {{Формула|f=(BC)^+=BCAD}}<br />
<br />
{{Формула|f=A^+=AB}}, {{Формула|f=C^+ = C}}, {{Формула|f=B^+ = BA}}<br />
<br />
Покажем, что в этом случае {{Формула|f=R}} находится в 3НФ:<br />
<br />
1)<br />
<br />
:неключевой атрибут {{Формула|f=H}}, {{Формула|f=H = D}}<br />
<br />
2)<br />
<br />
:{{Формула|f=Y\rightarrow H}}, {{Формула|f=H\notin Y}}, {{Формула|f=Y = AC}}<br />
<br />
3)<br />
<br />
:{{Формула|f=X = BC}}, {{Формула|f=X = AC}}<br />
<br />
Нельзя подобрать нужную тройку, потому {{Формула|f=R}} находится в 3НФ. Однако, отношение всё равно обладает аномалиями:<br />
* избыточности: наименование поставщика повторяется для каждой поставляемой делали;<br />
* противоречивости при изменении наименования поставщика надо изменить его во всех записях, куда оно входит;<br />
* включения: нельзя включить информацию о поставщике, если он ничего не поставляет;<br />
* удаления: при удалении детали удаляется информация о поставщике.<br />
<br />
Для устранения этого вводится усиленная 3НФ - Бойса-Кодда.<br />
<br />
=== Нормальная форма Бойса-Кодда ===<br />
<br />
ФЗ {{Формула|f=X\rightarrow Y}} является неприводимой, если для любого подмножества {{Формула|f=Z\subset X}} выполняется {{Формула|f=Z\nrightarrow Y}} или {{Формула|f=Z\rightarrow Y\notin F^+}}<br />
<br />
Пусть есть отношение {{Формула|f=R}} и {{Формула|f=F}} включает в себя нетривиальные неприводимые ФЗ. Тогда отношение {{Формула|f=R}} <u>находится в нормальной форме Бойса-Кодда</u>, если для любого {{Формула|f=X\rightarrow Y\in F}} => {{Формула|f=X}} - ключ.<br />
<br />
Пример:<br />
<br />
{{Формула|f=R_1 = AB}}, {{Формула|f=F_1 = (A\rightarrow B, B\rightarrow A)}}, {{Формула|f=A}} - ключ, {{Формула|f=B}} - ключ.<br />
<br />
или<br />
<br />
{{Формула|f=R_2 = ACD}}, {{Формула|f=F_2 = (AC\rightarrow D)}}, {{Формула|f=AC}} - ключ.<br />
<br />
== Алгоритм синтеза "хорошей" БД ==<br />
<br />
Пусть {{Формула|f=U}} - универсальная схема отношения (множество всех атрибутов предметной области) и {{Формула|f=F}} - множество ФЗ.<br />
<br />
Перед выполнением алгоритма можно привести все ФЗ к одному атрибуту в правой части (по свойству декомпозиции) и удалить лишние ФЗ. Но это не обязательно.<br />
<br />
Алгоритм:<br />
<br />
# построить УНП для {{Формула|f=F}};<br />
# если среди ФЗ в УНП нет ФЗ, включающей все атрибуты из {{Формула|f=U}}, то добавить в УНП тривиальную ФЗ {{Формула|f=U\rightarrow\varnothing}}. Выполнение этого шага почти всегда обеспечивает свойство соединения без потерь будущей схемы БД;<br />
# привести все нетривиальные ФЗ из УНП к неприводимому виду (удалить лишние атрибуты в левых частях ФЗ);<br />
# разбить полученное множество ФЗ УНП на классы эквивалентности. Две зависимости {{Формула|f=X_i\rightarrow Y_i}} и {{Формула|f=X_j\rightarrow Y_j}} будем называть эквивалентными, если {{Формула|f=X_iY_i = X_jY_j}}. Далее введём обозначение {{Формула|f=K_r = X_iY_i}} - множество атрибутов в левой и правой частях ФЗ {{Формула|f=r}}-того класса эквивалентности;<br />
# построить граф иерархии полученных на предыдущем шаге классов эквивалентности (если это возможно). Правило построения: {{Формула|f=j}}-ый узел соединяем снизу с {{Формула|f=i}}-ым узлом, если {{Формула|f=K_j\subset K_i}}. В каждом узле записываются все ФЗ, соответствующего класса эквивалентности;<br />
# из каждого класса эквивалентности в графе иерархии оставить только одну ФЗ. Правила выбора:<br />
## удалить из класса эквивалентности лишние ФЗ;<br />
## если в классе эквивалентности осталось больше одной ФЗ, то выбрать ФЗ с меньшим числом атрибутов в левой части;<br />
## если у оставшихся ФЗ число атрибутов в левой части одинаково, то выбрать ту ФЗ, которая позволит редуцировать (вычеркнуть) атрибуты справа у ФЗ, расположенных выше в графе иерархии;<br />
## если в результате не удалось выбрать ни одной, то выбрать произвольную;<br />
# редуцировать атрибуты справа в оставшихся ФЗ. Для этого просмотреть каждый путь снизу вверх в графе иерархии. Двигаясь по выбранному пути, выполнить следующие действия в каждом узле пути:<br />
## пусть {{Формула|f=X\rightarrow Y}} - это ФЗ, записанная в данном узле. Каждый атрибут, принадлежащий правой части, вычеркнуть в правых частях ФЗ, расположенных в узлах этого пути по иерархии выше;<br />
## для тривиальной ФЗ {{Формула|f=U\rightarrow\varnothing}} атрибуты вычёркиваются слева;<br />
# исключить из рассмотрения ФЗ с пустой правой частью (кроме редуцированной ФЗ {{Формула|f=U\rightarrow\varnothing}}). Исключённые на этом шаге ФЗ являются лишними и выводятся из оставшихся;<br />
# каждую оставшуюся в графе иерархий ФЗ {{Формула|f=V\rightarrow W}} заменить на множество {{Формула|f=VW}}. Получившееся множество схем отношений обозначить как {{Формула|f=\rho}};<br />
# для полученной на предыдущем шаге схемы БД проверить:<br />
## обладает ли она свойством соединия без потерь. Если не обладает, то добавить ключ универсальной схемы {{Формула|f=U}} в эту схему;<br />
## обладает ли {{Формула|f=\rho}} свойством сохранения ФЗ. Если нет, то, использовать зависимости, не вошедшие в проекцию {{Формула|f=X\rightarrow Y\notin\Pi_{R_i}(F)}}, для построения новых схем отношений, то есть добавить в {{Формула|f=\rho}} {{Формула|f=XY}}.<br />
<br />
После выполнения всех шагов полученная схема {{Формула|f=\rho}}:<br />
* обладает свойством соединения без потерь;<br />
* обладает свойством сохранения ФЗ;<br />
* находится в 3НФ или [[#Нормальная форма Бойса-Кодда | НФБК]];<br />
* содержит минимальное число схем отношений.<br />
<br />
=== Пример ===<br />
<br />
{{Формула|f=U = (поставщик, фирма, деталь, количество) = (A, B, C, D)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B, B\rightarrow A, AC\rightarrow D, BC\rightarrow D)}}<br />
<br />
Строим {{Формула|f=\rho}}:<br />
<br />
1)<br />
<br />
:{{Формула|f=УНП = (A\rightarrow B, B\rightarrow A, AC\rightarrow BD, BC\rightarrow AD)}}<br />
<br />
2)<br />
<br />
:пропускаем этот шаг, так как есть ФЗ (даже не одна), включающая все атрибуты из {{Формула|f=U}}<br />
<br />
3)<br />
<br />
:уменьшить число атрибутов не удаётся<br />
<br />
4)<br />
<br />
:1 класс: {{Формула|f=A\rightarrow B}}, {{Формула|f=B\rightarrow A}}, {{Формула|f=K_1 = AB}}<br />
:2 класс: {{Формула|f=AC\rightarrow BD}}, {{Формула|f=BC\rightarrow AD}}, {{Формула|f=K_2 = ABCD}}<br />
<br />
5)<br />
<br />
:[[Файл:9sTORAl6pic1.png|link=Файл:9sTORAl6pic1.svg]]<br />
<br />
6)<br />
<br />
:для {{Формула|f=K_2}}:<br />
<br />
::<u>способ 1</u> - как во [[ТОРА_(9)_-_Семинар_№2_-_Функциональные_зависимости#Выявление лишних ФЗ | втором семинаре]]<br />
:::можно ли вывести {{Формула|f=AC\rightarrow BD\in(BC\rightarrow AD)^+}}?<br />
:::{{Формула|f=(AC)^+=AC}}, {{Формула|f=BD\nsubseteq(AC)^+}}, значит нельзя<br />
:::можно ли вывести {{Формула|f=BC\rightarrow AD\in(AC\rightarrow BD)^+}}?<br />
:::{{Формула|f=(BC)^+=BC}}, {{Формула|f=AD\nsubseteq(BC)^+}}, значит нельзя<br />
<br />
::<u>способ 2</u> - вычеркнуть из правых частей ФЗ рассматриваемых классов эквивалентностей общие атрибуты. Если получаются ФЗ с пустой правой частью, то они являются лишними.<br />
:::{{Формула|f=AC\rightarrow B}}<br />
:::{{Формула|f=BC\rightarrow A}}<br />
:::выше по иерархии ничего нет, выбираем {{Формула|f=BC\rightarrow AD}}<br />
<br />
::нет лишних ФЗ, потому... <br />
<br />
:для {{Формула|f=K_1}}:<br />
<br />
{{Forward|l=ТОРА (9) - Лекция №7 - Алгоритм (продолжение)}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%965_-_%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0&diff=2496
ТОРА (9) - Лекция №5 - Третья нормальная форма
2013-01-12T16:17:18Z
<p>81.9.52.28: /* Третья нормальная форма */</p>
<hr />
<div>== Свойство сохранения ФЗ ==<br />
<br />
=== Алгоритм проверки схемы БД на обладание свойством сохранения ФЗ ===<br />
<br />
==== Пример 1 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, BC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
Смотрим:<br />
<br />
1)<br />
<br />
:{{Формула|f=H=\varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
<br />
2)<br />
<br />
:{{Формула|f=G = (A\rightarrow B, A\rightarrow C, B\rightarrow C)}}<br />
<br />
3)<br />
<br />
:{{Формула|f=A\rightarrow B}}, {{Формула|f=AB\subseteq R_1}}<br />
:{{Формула|f=A\rightarrow C}}, {{Формула|f=AC\nsubseteq R_2}}, {{Формула|f=H=(A\rightarrow C)}}<br />
:{{Формула|f=B\rightarrow C}}, {{Формула|f=BC\subseteq R_2}}<br />
<br />
4) пропускаем, так как не выполнилось условие в 3)<br />
<br />
5) <br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=A\rightarrow C\in(G-H)^+ = (A\rightarrow B, B\rightarrow C)^+}}<br />
:{{Формула|f=A^+=ABC}}, {{Формула|f=C\in A^+}}, значит {{Формула|f=\rho}} <u>обладает сохранением ФЗ</u>.<br />
<br />
==== Пример 2 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, AC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
1-4)<br />
<br />
:{{Формула|f=H = \varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
:{{Формула|f=H = (B\rightarrow C))}}<br />
<br />
5)<br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=B\rightarrow C\in(G - H)^+ = (A\rightarrow BC)^+}}<br />
:{{Формула|f=B^+ = B}}, {{Формула|f=C\notin B^+}}, значит {{Формула|f=\rho}} <u>не обладает сохранением ФЗ</u>.<br />
<br />
== Ключ схемы отношения ==<br />
<br />
Если атрибут {{Формула|f=A_i\in R}} входит в какой-либо ключ схемы отношения {{Формула|f=R}}, то он называется '''первичным'''. А если не входит ни в один, то называется '''непервичным'''.<br />
<br />
Пусть<br />
<br />
:{{Формула|f=R = (A_1 ... A_n)}} - некоторая схема отношения.<br />
:{{Формула|f=F}} - множество ФЗ.<br />
<br />
Тогда<br />
<br />
:{{Формула|f=X\subseteq R}} называется ключом схемы, если выполняются:<br />
:* {{Формула|f=X\rightarrow A_1 ... A_n\in F^+}}<br />
:* {{Формула|f=\forall Z\subset X}}, {{Формула|f=Z\rightarrow A_1 ... A_n\notin F^+}}. {{Формула|f=X}} содержит минимальное число атрибутов, для которых выполняется предыдущее свойство.<br />
<br />
=== Алгоритм построения ключа ===<br />
<br />
Базируется на определении ключа. Позволяет построить только один ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = A_1 ... A_n}}<br />
<br />
2)<br />
<br />
:цикл по атрибутам {{Формула|f=A_j}} в {{Формула|f=X_i}}<br />
<br />
:Если {{Формула|f=(X_i - A_j)^+ = R}}, то {{Формула|f=X_{i+1} = X_i - A_j}}, {{Формула|f=i = i + 1}} и выйти из цикла;<br />
:иначе продолжить цикл<br />
<br />
3)<br />
<br />
:если {{Формула|f=i}} возросло, то перейти к шагу 2);<br />
:иначе {{Формула|f=X = X_i}} - это найденный ключ.<br />
<br />
=== Пример построения ключа ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (AB\rightarrow DC, BC\rightarrow AD)}}<br />
<br />
Надо построить ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(X_0 - A)^+ = (BCD)^+ = BCDA = R}}, значит {{Формула|f=X_1 = BCD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(BD)^+ = BD\neq R}}<br />
:{{Формула|f=(BC)^+ = BCAD = R}}, {{Формула|f=X_2 = BC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=B^+ = B\neq R}}<br />
<br />
3) <br />
<br />
:{{Формула|f=i}}, как видим, не возросло. Значит, {{Формула|f=X = BC}} - ключ. Но не единственный, {{Формула|f=X = AB}} - тоже ключ, просто у нас получился сначала этот.<br />
<br />
Значит, {{Формула|f=A,B,C}} - первичные атрибуты, а {{Формула|f=D}} - непервичный.<br />
<br />
== Третья нормальная форма ==<br />
<br />
Отношение <u>находится в 3НФ</u>, если не существует ключа {{Формула|f=X}}, {{Формула|f=Y\subseteq R}} и непервичного атрибута {{Формула|f=H\notin Y}}.<br />
<br />
А если можно найти такую тройку {{Формула|f=X, Y, H}}, для которой выполняются:<br />
*{{Формула|f=X\rightarrow Y\in F^+}}<br />
*{{Формула|f=Y\rightarrow H\in F^+}}<br />
*{{Формула|f=Y\rightarrow X\notin F^+}}<br />
то схема <u>не находится в 3НФ</u>.<br />
<br />
Если схема отношения находится в 3НФ, то в большинстве случаев эта схема отношения не обладает [[ТОРА (9) - Лекция_№1 - Операции реляционной алгебры#Пример "плохой" схемы БД | аномалиями]]. Но существуют условия, когда схема в 3НФ обладает этими аномалиями. Хотя, встречаются они редко. Вот они:<br />
* схема отношения имеет 2 или больше ключей,<br />
** и любые 2 из них являются составными,<br />
*** и имеют общий атрибут.<br />
<br />
=== Пример 1 ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}} и {{Формула|f=\rho = R}}<br />
<br />
Доказать, что это отношение не находится в 3НФ.<br />
<br />
Доказываем:<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(BCD)^+ = BCD\neq R}}<br />
:{{Формула|f=(ACD)^+ = ACDB = R}}, {{Формула|f=X = ACD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(AD)+^ = ADB\neq R}}<br />
:{{Формула|f=(AC)^+ = ACBD = R}}, {{Формула|f=X_2 = AC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=A^+ = AB\neq R}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}} не возросло, значит {{Формула|f=X = X_2 = AC}} - это ключ. Причём, можно показать, что он единственный.<br />
<br />
Теперь предполагаем тройку:<br />
*{{Формула|f=X = AC}}<br />
*{{Формула|f=Y = A\subseteq R}}<br />
*{{Формула|f=H = B}} - непервичный атрибут, {{Формула|f=B\notin X}}<br />
<br />
Проверям три условия для неё:<br />
<br />
1)<br />
<br />
:{{Формула|f=X\rightarrow Y}}, так как {{Формула|f=AC\rightarrow A}} по 1 аксиоме Армстронга;<br />
<br />
2)<br />
<br />
:{{Формула|f=Y\rightarrow H}}, {{Формула|f=A\rightarrow B}} по условию;<br />
<br />
3)<br />
<br />
:{{Формула|f=Y\nrightarrow X}}, {{Формула|f=A\nrightarrow AC}}<br />
:{{Формула|f=A^+ = AB}}, {{Формула|f=AC\nsubseteq A^+}}<br />
<br />
Таким образом, найдена тройка, для которой выполняются все три условия, а значит отношение <u>не находится в 3НФ</u>.<br />
<br />
=== Пример 2 ===<br />
<br />
Декомпозируем эту схему отношения {{Формула|f=R}} на две схему отношений.<br />
<br />
{{Формула|f=R = (A, B, C, D)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}}<br />
<br />
{{Формула|f=\rho = (AB, ACD) = (R_1, R_2)}}<br />
<br />
Если {{Формула|f=R_1}} и {{Формула|f=R_2}} находятся в 3НФ, то значит всё {{Формула|f=\rho}} будет в 3НФ.<br />
<br />
Сначала покажем 3НФ у {{Формула|f=R_1 = (AB)}}, {{Формула|f=F = (A\rightarrow B)}}:<br />
<br />
:* {{Формула|f=X = A}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::{{Формула|f=Y = B}}, {{Формула|f=A\rightarrow B}}, {{Формула|f=B\nrightarrow A}}<br />
:* невозможно подобрать непервичный атрибут {{Формула|f=H\notin Y}}, потому что непервичным может быть только {{Формула|f=B}}.<br />
<br />
Таким образом, нельзя подобрать необходимую тройку. Значит, {{Формула|f=R_1}} находится в 3НФ.<br />
<br />
Теперь покажем 3НФ у {{Формула|f=R_2 = (ACD)}}, {{Формула|f=F = (AC\rightarrow D)}}:<br />
<br />
:* {{Формула|f=X = AC}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::а) {{Формула|f=A}} - что-то как-то не выполняется;<br />
::б) {{Формула|f=C}} - что-то как-то не выполняется;<br />
::в) {{Формула|f=D}} - что-то как-то не выполняется;<br />
::г) {{Формула|f=AD}} - что-то как-то не выполняется;<br />
::д) {{Формула|f=CD}} - что-то как-то не выполняется.<br />
:* {{Формула|f=H\notin Y}}, {{Формула|f=H = D}}<br />
::а) {{Формула|f=Y = A}}, {{Формула|f=Y\nrightarrow H}}<br />
::б) {{Формула|f=Y = C}}, {{Формула|f=Y\nrightarrow H}}<br />
::в-д) {{Формула|f=H\in Y}}<br />
<br />
Не удалось подобрать нужную тройку, так что {{Формула|f=R_2}} тоже находится в 3НФ.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%961_-_%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B9_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D1%8B&diff=2495
ТОРА (9) - Лекция №1 - Операции реляционной алгебры
2013-01-12T15:29:09Z
<p>81.9.52.28: /* Пример "плохой" схемы БД */</p>
<hr />
<div>== Определения ==<br />
<br />
=== Схема отношения ===<br />
<br />
Это поименованная совокупность атрибутов.<br />
<br />
{{Формула|f=R = (A_1, ..., A_n)}}, где {{Формула|f=A_i}} - некоторый атрибут из домена отношения.<br />
<br />
{{Формула|f=R = (}}идентификатор поставщика, адрес, товар, цена{{Формула|f=)=(A_1, A_2, A_3, A_4)}}.<br />
<br />
Здесь {{Формула|f=(A_1, A_3)}} - ключ, определяющий запись.<br />
<br />
=== Степень схемы отношения ===<br />
<br />
Это количество атрибутов в схеме.<br />
<br />
Для {{Формула|f=R = (A_1, A_2, A_3, A_4)}} степень равна 4.<br />
<br />
=== Экземпляр отношения ===<br />
<br />
Это конкретная таблица с данной схемой отношения.<br />
<br />
{{Формула|f=R = (}}идентификатор поставщика, адрес, товар, цена{{Формула|f=)}}.<br />
<br />
{| class="wikitable"<br />
! Идентификатор !! Адрес !! Товар !! Цена<br />
|- align="center"<br />
| ОАО "Х" || Ленина, 2 || сахар || 40<br />
|- align="center"<br />
| ОАО "У" || Комсомола, 25 || соль || 5<br />
|}<br />
<br />
=== Кортеж ===<br />
<br />
Любая одна строка в таблице экземпляра отношения.<br />
<br />
=== Схема БД ===<br />
<br />
{{Формула|f=A}} - множество всех атрибутов некоторой предметной области (универсальная схема отношения).<br />
<br />
{{Формула|f=R_1, ..., R_n}} - совокупность атрибутов.<br />
<br />
Тогда {{Формула|f=\rho=(R_1, ..., R_n)}} называется схемой БД.<br />
<br />
Пример:<br />
<br />
{{Формула|f=A = (A_1, A_2, A_3, A_4)}}<br />
<br />
и две схемы: {{Формула|f=R_1 = (A_1, A_2)$ и $R_2 = (A_1, A_3, A_4)}}<br />
<br />
Так как {{Формула|f=R_1\bigcup R_2 = A}}, то {{Формула|f=\rho = (R_1, R_2)}}.<br />
<br />
== Примеры схем БД ==<br />
<br />
=== Пример "плохой" схемы БД ===<br />
<br />
Пусть {{Формула|f=A = (}}идентификатор поставщика, адрес, товар, цена{{Формула|f=)}}<br />
<br />
и есть одна схема {{Формула|f=\rho = R_1 = A}}<br />
<br />
Данная схема БД обладает следующими недостатками (аномалиями):<br />
* избыточность. Адрес поставщика повторяется для каждого поставляемого им товара;<br />
* потенциальная противоречивость. Если у поставщика меняется адрес, то его необходимо изменить во всех кортежах, в которые он входит;<br />
* аномалия включения кортежа. В выбранном отношении {{Формула|f=R_1}} пара атрибутов идентификатор-товар является ключом. При включении новой записи, атрибуты ключа не должны быть пустыми, поэтому в БД нельзя включить поставщика, если он в данный момент не поставляет товар;<br />
* аномалия удаления. При удалении всех товаров, поставляемых поставщиком, теряется информация о самом поставщике.<br />
Первопричиной этих недостатков является то, что {{Формула|f=R_1}} не находится в {{Википедия|Третья_нормальная_форма|3НФ}}<br />
<br />
=== Пример "хорошей" схемы БД ===<br />
<br />
Пусть {{Формула|f=A = (}}идентификатор поставщика, адрес, товар, цена{{Формула|f=)}}<br />
<br />
{{Формула|f=R_1 = (}}идентификатор, адрес{{Формула|f=)}}<br />
<br />
{{Формула|f=R_2 = (}}товар, цена{{Формула|f=)}}<br />
<br />
Схема {{Формула|f=\rho = (R_1, R_2)}} находится в 3НФ и не обладает перечисленными выше недостатками.<br />
<br />
== Основные операции реляционной алгебры ==<br />
<br />
=== Объединение отношений ===<br />
<br />
{{Формула|f=R=R_1\bigcup R_2}}<br />
<br />
Объединение отношений - это отношение, каждый кортеж которого принадлежит либо {{Формула|f=R_1}}, либо {{Формула|f=R_2}}.<br />
{|<br />
|<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_1}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 4<br />
|}<br />
| <br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_2}} <br />
| 5 || 6<br />
|- align="center"<br />
| 1 || 2<br />
|}<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="3" | {{Формула|f=R}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 4<br />
|- align="center"<br />
| 5 || 6<br />
|}<br />
<br />
Дублирование кортежей не допускается.<br />
<br />
=== Пересечение отношений ===<br />
<br />
{{Формула|f=R = R_1\bigcap R_2}}<br />
<br />
Пересечение отношений - это отношение, каждый кортеж которого принадлежит и {{Формула|f=R_1}}, и {{Формула|f=R_2}}<br />
<br />
{|<br />
|<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_1}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 4<br />
|}<br />
| <br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_2}} <br />
| 5 || 6<br />
|- align="center"<br />
| 1 || 2<br />
|}<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! {{Формула|f=R}} <br />
| 1 || 2<br />
|}<br />
<br />
=== Разность отношений ===<br />
<br />
{{Формула|f=R = R_1 - R_2}}<br />
<br />
Разность отношений - это отношение, кортежи которого принадлежат {{Формула|f=R_1}} и не принадлежат {{Формула|f=R_2}}<br />
<br />
{|<br />
|<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_1}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 4<br />
|}<br />
| <br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R_2}} <br />
| 5 || 6<br />
|- align="center"<br />
| 1 || 2<br />
|}<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! {{Формула|f=R}} <br />
| 3 || 4<br />
|}<br />
<br />
=== Декартово произведение ===<br />
<br />
{{Формула|f=R, S}} - две схемы отношения со степенями {{Формула|f=k_1}} и {{Формула|f=k_2}}<br />
<br />
{{Формула|f=t = R \times S}}<br />
<br />
Декартово произведение - это отношение {{Формула|f=t}} со степенью {{Формула|f=k_1 + k_2}}, кортежи которого получаются {{Википедия|Конкатенация|конкатенацией}} кортежей из отношений {{Формула|f=R}} и {{Формула|f=S}}.<br />
<br />
{|<br />
|<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 4<br />
|}<br />
| <br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_3}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=S}} <br />
| 5 || 6<br />
|- align="center"<br />
| 7 || 8<br />
|}<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=R.A_2}} !! {{Формула|f=A_2}} !! {{Формула|f=S.A_1}} !! {{Формула|f=A_3}}<br />
|- align="center"<br />
! rowspan="4" | {{Формула|f=t}} <br />
| 1 || 2 || 5 || 6<br />
|- align="center"<br />
| 1 || 2 || 7 || 8<br />
|- align="center"<br />
| 3 || 4 || 5 || 6<br />
|- align="center"<br />
| 3 || 4 || 7 || 8<br />
|}<br />
<br />
=== Проекция ===<br />
<br />
{{Формула|f=t=\Pi_{A_{i1} ... A_{ik} }(R) }}<br />
<br />
Проекция - это отношение, каждый кортеж которого состоит из значений атрибутов {{Формула|f=A_{i1} ... A_{ik} }} исходного отношения {{Формула|f=R}}.<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=A_1}} !! {{Формула|f=A_2}} !! {{Формула|f=A_3}} !! {{Формула|f=A_4}}<br />
|- align="center"<br />
! rowspan="4" | {{Формула|f=R}} <br />
| 1 || 2 || 3 || 4<br />
|- align="center"<br />
| 7 || 8 || 9 || 10<br />
|- align="center"<br />
| 3 || 4 || 5 || 6<br />
|- align="center"<br />
| 3 || 4 || 7 || 6<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_4}}<br />
|- align="center"<br />
! rowspan="3" | {{Формула|f=t = \Pi_{A_1, A_4}(R)}} <br />
| 1 || 4<br />
|- align="center"<br />
| 7 || 10<br />
|- align="center"<br />
| 3 || 6<br />
|}<br />
<br />
=== Селекция ===<br />
<br />
{{Формула|f=t = \sigma_F(R)}}<br />
<br />
Селекция - это отношение, каждый кортеж которого принадлежит исходному отношению {{Формула|f=R}} и удовлетворяет логическому условию {{Формула|f=F}}.<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="3" | {{Формула|f=R}} <br />
| 1 || 2<br />
|- align="center"<br />
| 9 || 8<br />
|- align="center"<br />
| 3 || 3<br />
|}<br />
<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=t = \sigma_{A_1\leq A_2}(R)}} <br />
| 1 || 2<br />
|- align="center"<br />
| 3 || 3<br />
|}<br />
<br />
=== Естественное соединение ===<br />
<br />
{{Формула|f=t = R\bowtie S}}<br />
<br />
Определение этой операции следует из способа построения естественного соединения.<br />
<br />
{|<br />
| valign="top" |<br />
{| class="wikitable"<br />
! !!{{Формула|f=A_1}} !! {{Формула|f=A_2}} !! {{Формула|f=A_3}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=R}} <br />
| 1 || 2 || 3<br />
|- align="center"<br />
| 4 || 6 || 7<br />
|}<br />
| valign="top" |<br />
{| class="wikitable" valign="top"<br />
! !! {{Формула|f=A_1}} !! {{Формула|f=A_2}} !! {{Формула|f=A_4}} !! {{Формула|f=A_5}}<br />
|- align="center"<br />
! rowspan="3" | {{Формула|f=S}} <br />
| 1 || 2 || 7 || 8<br />
|- align="center"<br />
| 8 || 9 || 10 || 11<br />
|- align="center"<br />
| 5 || 6 || 9 || 16<br />
|}<br />
|}<br />
<br />
Построение естественного соединения:<br />
<br />
:1) построить декартово произведение {{Формула|f=R\times S}}<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=R.A_1}} !! {{Формула|f=R.A_2}} !! {{Формула|f=A_3}} !! {{Формула|f=S.A_1}} !! {{Формула|f=S.A_2}}!! {{Формула|f=A_4}} !! {{Формула|f=A_5}}<br />
|- align="center"<br />
! rowspan="6" | {{Формула|f=t_1}} <br />
| 1 || 2 || 3 || 1 || 2 || 7 || 8<br />
|- align="center"<br />
| 1 || 2 || 3 || 8 || 9 || 10 || 11<br />
|- align="center"<br />
| 1 || 2 || 3 || 4 || 6 || 9 || 16<br />
|- align="center"<br />
| 4 || 6 || 7 || 1 || 2 || 7 || 8<br />
|- align="center"<br />
| 4 || 6 || 7 || 8 || 9 || 10 || 11<br />
|- align="center"<br />
| 4 || 6 || 7 || 4 || 6 || 9 || 16<br />
|}<br />
<br />
:2) выбрать из этого произведения кортежи по условию {{Формула|f=R.A_{i1} = S.A_{i1} ... R.A_{ik} = S.A_{ik} }}, где {{Формула|f=A_1 = A_k}} - общие атрибуты в схемах отношений {{Формула|f=R}} и {{Формула|f=S}} (предполагается, что эти атрибуты занимают одинаковое положение в отношениях. Хотя не обязательно)<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=R.A_1}} !! {{Формула|f=R.A_2}} !! {{Формула|f=A_3}} !! {{Формула|f=S.A_1}} !! {{Формула|f=S.A_2}}!! {{Формула|f=A_4}} !! {{Формула|f=A_5}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=t_2}} <br />
| 1 || 2 || 3 || 1 || 2 || 7 || 8<br />
|- align="center"<br />
| 4 || 6 || 7 || 4 || 6 || 9 || 16<br />
|}<br />
<br />
:3) удалить из полученного отношения {{Формула|f=S.A_{i1} ... S.A_{ik} }}, потому что они будут дублирующими.<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=R.A_1}} !! {{Формула|f=R.A_2}} !! {{Формула|f=A_3}} !! {{Формула|f=A_4}} !! {{Формула|f=A_5}}<br />
|- align="center"<br />
! rowspan="2" | {{Формула|f=t_3}} <br />
| 1 || 2 || 3 || 7 || 8<br />
|- align="center"<br />
| 4 || 6 || 7 || 9 || 16<br />
|}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%965_-_%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0&diff=2494
ТОРА (9) - Лекция №5 - Третья нормальная форма
2013-01-12T14:30:19Z
<p>81.9.52.28: /* Пример 2 */</p>
<hr />
<div>== Свойство сохранения ФЗ ==<br />
<br />
=== Алгоритм проверки схемы БД на обладание свойством сохранения ФЗ ===<br />
<br />
==== Пример 1 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, BC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
Смотрим:<br />
<br />
1)<br />
<br />
:{{Формула|f=H=\varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
<br />
2)<br />
<br />
:{{Формула|f=G = (A\rightarrow B, A\rightarrow C, B\rightarrow C)}}<br />
<br />
3)<br />
<br />
:{{Формула|f=A\rightarrow B}}, {{Формула|f=AB\subseteq R_1}}<br />
:{{Формула|f=A\rightarrow C}}, {{Формула|f=AC\nsubseteq R_2}}, {{Формула|f=H=(A\rightarrow C)}}<br />
:{{Формула|f=B\rightarrow C}}, {{Формула|f=BC\subseteq R_2}}<br />
<br />
4) пропускаем, так как не выполнилось условие в 3)<br />
<br />
5) <br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=A\rightarrow C\in(G-H)^+ = (A\rightarrow B, B\rightarrow C)^+}}<br />
:{{Формула|f=A^+=ABC}}, {{Формула|f=C\in A^+}}, значит {{Формула|f=\rho}} <u>обладает сохранением ФЗ</u>.<br />
<br />
==== Пример 2 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, AC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
1-4)<br />
<br />
:{{Формула|f=H = \varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
:{{Формула|f=H = (B\rightarrow C))}}<br />
<br />
5)<br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=B\rightarrow C\in(G - H)^+ = (A\rightarrow BC)^+}}<br />
:{{Формула|f=B^+ = B}}, {{Формула|f=C\notin B^+}}, значит {{Формула|f=\rho}} <u>не обладает сохранением ФЗ</u>.<br />
<br />
== Ключ схемы отношения ==<br />
<br />
Если атрибут {{Формула|f=A_i\in R}} входит в какой-либо ключ схемы отношения {{Формула|f=R}}, то он называется '''первичным'''. А если не входит ни в один, то называется '''непервичным'''.<br />
<br />
Пусть<br />
<br />
:{{Формула|f=R = (A_1 ... A_n)}} - некоторая схема отношения.<br />
:{{Формула|f=F}} - множество ФЗ.<br />
<br />
Тогда<br />
<br />
:{{Формула|f=X\subseteq R}} называется ключом схемы, если выполняются:<br />
:* {{Формула|f=X\rightarrow A_1 ... A_n\in F^+}}<br />
:* {{Формула|f=\forall Z\subset X}}, {{Формула|f=Z\rightarrow A_1 ... A_n\notin F^+}}. {{Формула|f=X}} содержит минимальное число атрибутов, для которых выполняется предыдущее свойство.<br />
<br />
=== Алгоритм построения ключа ===<br />
<br />
Базируется на определении ключа. Позволяет построить только один ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = A_1 ... A_n}}<br />
<br />
2)<br />
<br />
:цикл по атрибутам {{Формула|f=A_j}} в {{Формула|f=X_i}}<br />
<br />
:Если {{Формула|f=(X_i - A_j)^+ = R}}, то {{Формула|f=X_{i+1} = X_i - A_j}}, {{Формула|f=i = i + 1}} и выйти из цикла;<br />
:иначе продолжить цикл<br />
<br />
3)<br />
<br />
:если {{Формула|f=i}} возросло, то перейти к шагу 2);<br />
:иначе {{Формула|f=X = X_i}} - это найденный ключ.<br />
<br />
=== Пример построения ключа ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (AB\rightarrow DC, BC\rightarrow AD)}}<br />
<br />
Надо построить ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(X_0 - A)^+ = (BCD)^+ = BCDA = R}}, значит {{Формула|f=X_1 = BCD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(BD)^+ = BD\neq R}}<br />
:{{Формула|f=(BC)^+ = BCAD = R}}, {{Формула|f=X_2 = BC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=B^+ = B\neq R}}<br />
<br />
3) <br />
<br />
:{{Формула|f=i}}, как видим, не возросло. Значит, {{Формула|f=X = BC}} - ключ. Но не единственный, {{Формула|f=X = AB}} - тоже ключ, просто у нас получился сначала этот.<br />
<br />
Значит, {{Формула|f=A,B,C}} - первичные атрибуты, а {{Формула|f=D}} - непервичный.<br />
<br />
== Третья нормальная форма ==<br />
<br />
Отношение <u>находится в 3НФ</u>, если не существует ключа {{Формула|f=X}}, {{Формула|f=Y\subseteq R}} и непервичного атрибута {{Формула|f=H\notin Y}}.<br />
<br />
А если можно найти такую тройку {{Формула|f=X, Y, H}}, для которой выполняются:<br />
*{{Формула|f=X\rightarrow Y\in F^+}}<br />
*{{Формула|f=Y\rightarrow H\in F^+}}<br />
*{{Формула|f=Y\rightarrow X\notin F^+}}<br />
то схема <u>не находится в 3НФ</u>.<br />
<br />
Если схема отношения находится в 3НФ, то в большинстве случаев эта схема отношения не обладает [[ТОРА (9) - Лекция_№1 - Операции реляционной алгебры#Пример "плохой" схемы БД | аномалиями]]. Но существуют условия, когда схема в 3НФ обладаем этими аномалиями. Хотя, встречаются они редко. Вот они:<br />
* схема отношения имеет 2 или больше ключей,<br />
** и любые 2 из них являются составными,<br />
*** и имеют общий атрибут.<br />
<br />
=== Пример 1 ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}} и {{Формула|f=\rho = R}}<br />
<br />
Доказать, что это отношение не находится в 3НФ.<br />
<br />
Доказываем:<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(BCD)^+ = BCD\neq R}}<br />
:{{Формула|f=(ACD)^+ = ACDB = R}}, {{Формула|f=X = ACD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(AD)+^ = ADB\neq R}}<br />
:{{Формула|f=(AC)^+ = ACBD = R}}, {{Формула|f=X_2 = AC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=A^+ = AB\neq R}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}} не возросло, значит {{Формула|f=X = X_2 = AC}} - это ключ. Причём, можно показать, что он единственный.<br />
<br />
Теперь предполагаем тройку:<br />
*{{Формула|f=X = AC}}<br />
*{{Формула|f=Y = A\subseteq R}}<br />
*{{Формула|f=H = B}} - непервичный атрибут, {{Формула|f=B\notin X}}<br />
<br />
Проверям три условия для неё:<br />
<br />
1)<br />
<br />
:{{Формула|f=X\rightarrow Y}}, так как {{Формула|f=AC\rightarrow A}} по 1 аксиоме Армстронга;<br />
<br />
2)<br />
<br />
:{{Формула|f=Y\rightarrow H}}, {{Формула|f=A\rightarrow B}} по условию;<br />
<br />
3)<br />
<br />
:{{Формула|f=Y\nrightarrow X}}, {{Формула|f=A\nrightarrow AC}}<br />
:{{Формула|f=A^+ = AB}}, {{Формула|f=AC\nsubseteq A^+}}<br />
<br />
Таким образом, найдена тройка, для которой выполняются все три условия, а значит отношение <u>не находится в 3НФ</u>.<br />
<br />
=== Пример 2 ===<br />
<br />
Декомпозируем эту схему отношения {{Формула|f=R}} на две схему отношений.<br />
<br />
{{Формула|f=R = (A, B, C, D)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}}<br />
<br />
{{Формула|f=\rho = (AB, ACD) = (R_1, R_2)}}<br />
<br />
Если {{Формула|f=R_1}} и {{Формула|f=R_2}} находятся в 3НФ, то значит всё {{Формула|f=\rho}} будет в 3НФ.<br />
<br />
Сначала покажем 3НФ у {{Формула|f=R_1 = (AB)}}, {{Формула|f=F = (A\rightarrow B)}}:<br />
<br />
:* {{Формула|f=X = A}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::{{Формула|f=Y = B}}, {{Формула|f=A\rightarrow B}}, {{Формула|f=B\nrightarrow A}}<br />
:* невозможно подобрать непервичный атрибут {{Формула|f=H\notin Y}}, потому что непервичным может быть только {{Формула|f=B}}.<br />
<br />
Таким образом, нельзя подобрать необходимую тройку. Значит, {{Формула|f=R_1}} находится в 3НФ.<br />
<br />
Теперь покажем 3НФ у {{Формула|f=R_2 = (ACD)}}, {{Формула|f=F = (AC\rightarrow D)}}:<br />
<br />
:* {{Формула|f=X = AC}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::а) {{Формула|f=A}} - что-то как-то не выполняется;<br />
::б) {{Формула|f=C}} - что-то как-то не выполняется;<br />
::в) {{Формула|f=D}} - что-то как-то не выполняется;<br />
::г) {{Формула|f=AD}} - что-то как-то не выполняется;<br />
::д) {{Формула|f=CD}} - что-то как-то не выполняется.<br />
:* {{Формула|f=H\notin Y}}, {{Формула|f=H = D}}<br />
::а) {{Формула|f=Y = A}}, {{Формула|f=Y\nrightarrow H}}<br />
::б) {{Формула|f=Y = C}}, {{Формула|f=Y\nrightarrow H}}<br />
::в-д) {{Формула|f=H\in Y}}<br />
<br />
Не удалось подобрать нужную тройку, так что {{Формула|f=R_2}} тоже находится в 3НФ.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%965_-_%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0&diff=2493
ТОРА (9) - Лекция №5 - Третья нормальная форма
2013-01-12T14:26:20Z
<p>81.9.52.28: /* Алгоритм построения ключа */</p>
<hr />
<div>== Свойство сохранения ФЗ ==<br />
<br />
=== Алгоритм проверки схемы БД на обладание свойством сохранения ФЗ ===<br />
<br />
==== Пример 1 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, BC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
Смотрим:<br />
<br />
1)<br />
<br />
:{{Формула|f=H=\varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
<br />
2)<br />
<br />
:{{Формула|f=G = (A\rightarrow B, A\rightarrow C, B\rightarrow C)}}<br />
<br />
3)<br />
<br />
:{{Формула|f=A\rightarrow B}}, {{Формула|f=AB\subseteq R_1}}<br />
:{{Формула|f=A\rightarrow C}}, {{Формула|f=AC\nsubseteq R_2}}, {{Формула|f=H=(A\rightarrow C)}}<br />
:{{Формула|f=B\rightarrow C}}, {{Формула|f=BC\subseteq R_2}}<br />
<br />
4) пропускаем, так как не выполнилось условие в 3)<br />
<br />
5) <br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=A\rightarrow C\in(G-H)^+ = (A\rightarrow B, B\rightarrow C)^+}}<br />
:{{Формула|f=A^+=ABC}}, {{Формула|f=C\in A^+}}, значит {{Формула|f=\rho}} <u>обладает сохранением ФЗ</u>.<br />
<br />
==== Пример 2 ====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}, {{Формула|f=\rho = (AB, AC) = (R_1, R_2)}} и {{Формула|f=F = (A\rightarrow B, B\rightarrow C)}}<br />
<br />
Обладает ли {{Формула|f=\rho}} сохранением ФЗ?<br />
<br />
1-4)<br />
<br />
:{{Формула|f=H = \varnothing}}, {{Формула|f=УНП = (A\rightarrow BC, B\rightarrow C)}}<br />
:{{Формула|f=H = (B\rightarrow C))}}<br />
<br />
5)<br />
<br />
:{{Формула|f=H}} не пустое.<br />
<br />
6)<br />
<br />
:выполняется ли {{Формула|f=B\rightarrow C\in(G - H)^+ = (A\rightarrow BC)}}<br />
:{{Формула|f=B^+ = B}}, {{Формула|f=C\notin B^+}}, значит {{Формула|f=\rho}} <u>не обладает сохранением ФЗ</u>.<br />
<br />
== Ключ схемы отношения ==<br />
<br />
Если атрибут {{Формула|f=A_i\in R}} входит в какой-либо ключ схемы отношения {{Формула|f=R}}, то он называется '''первичным'''. А если не входит ни в один, то называется '''непервичным'''.<br />
<br />
Пусть<br />
<br />
:{{Формула|f=R = (A_1 ... A_n)}} - некоторая схема отношения.<br />
:{{Формула|f=F}} - множество ФЗ.<br />
<br />
Тогда<br />
<br />
:{{Формула|f=X\subseteq R}} называется ключом схемы, если выполняются:<br />
:* {{Формула|f=X\rightarrow A_1 ... A_n\in F^+}}<br />
:* {{Формула|f=\forall Z\subset X}}, {{Формула|f=Z\rightarrow A_1 ... A_n\notin F^+}}. {{Формула|f=X}} содержит минимальное число атрибутов, для которых выполняется предыдущее свойство.<br />
<br />
=== Алгоритм построения ключа ===<br />
<br />
Базируется на определении ключа. Позволяет построить только один ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = A_1 ... A_n}}<br />
<br />
2)<br />
<br />
:цикл по атрибутам {{Формула|f=A_j}} в {{Формула|f=X_i}}<br />
<br />
:Если {{Формула|f=(X_i - A_j)^+ = R}}, то {{Формула|f=X_{i+1} = X_i - A_j}}, {{Формула|f=i = i + 1}} и выйти из цикла;<br />
:иначе продолжить цикл<br />
<br />
3)<br />
<br />
:если {{Формула|f=i}} возросло, то перейти к шагу 2);<br />
:иначе {{Формула|f=X = X_i}} - это найденный ключ.<br />
<br />
=== Пример построения ключа ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (AB\rightarrow DC, BC\rightarrow AD)}}<br />
<br />
Надо построить ключ.<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(X_0 - A)^+ = (BCD)^+ = BCDA = R}}, значит {{Формула|f=X_1 = BCD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(BD)^+ = BD\neq R}}<br />
:{{Формула|f=(BC)^+ = BCAD = R}}, {{Формула|f=X_2 = BC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=B^+ = B\neq R}}<br />
<br />
3) <br />
<br />
:{{Формула|f=i}}, как видим, не возросло. Значит, {{Формула|f=X = BC}} - ключ. Но не единственный, {{Формула|f=X = AB}} - тоже ключ, просто у нас получился сначала этот.<br />
<br />
Значит, {{Формула|f=A,B,C}} - первичные атрибуты, а {{Формула|f=D}} - непервичный.<br />
<br />
== Третья нормальная форма ==<br />
<br />
Отношение <u>находится в 3НФ</u>, если не существует ключа {{Формула|f=X}}, {{Формула|f=Y\subseteq R}} и непервичного атрибута {{Формула|f=H\notin Y}}.<br />
<br />
А если можно найти такую тройку {{Формула|f=X, Y, H}}, для которой выполняются:<br />
*{{Формула|f=X\rightarrow Y\in F^+}}<br />
*{{Формула|f=Y\rightarrow H\in F^+}}<br />
*{{Формула|f=Y\rightarrow X\notin F^+}}<br />
то схема <u>не находится в 3НФ</u>.<br />
<br />
Если схема отношения находится в 3НФ, то в большинстве случаев эта схема отношения не обладает [[ТОРА (9) - Лекция_№1 - Операции реляционной алгебры#Пример "плохой" схемы БД | аномалиями]]. Но существуют условия, когда схема в 3НФ обладаем этими аномалиями. Хотя, встречаются они редко. Вот они:<br />
* схема отношения имеет 2 или больше ключей,<br />
** и любые 2 из них являются составными,<br />
*** и имеют общий атрибут.<br />
<br />
=== Пример 1 ===<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D)}}, {{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}} и {{Формула|f=\rho = R}}<br />
<br />
Доказать, что это отношение не находится в 3НФ.<br />
<br />
Доказываем:<br />
<br />
1)<br />
<br />
:{{Формула|f=i = 0}}, {{Формула|f=X_0 = ABCD}}<br />
<br />
2)<br />
<br />
:{{Формула|f=(BCD)^+ = BCD\neq R}}<br />
:{{Формула|f=(ACD)^+ = ACDB = R}}, {{Формула|f=X = ACD}}, {{Формула|f=i = 1}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=(CD)^+ = CD\neq R}}<br />
:{{Формула|f=(AD)+^ = ADB\neq R}}<br />
:{{Формула|f=(AC)^+ = ACBD = R}}, {{Формула|f=X_2 = AC}}, {{Формула|f=i = 2}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}}, как видим, возросло, значит опять 2)<br />
<br />
2)<br />
<br />
:{{Формула|f=C^+ = C\neq R}}<br />
:{{Формула|f=A^+ = AB\neq R}}<br />
<br />
3)<br />
<br />
:{{Формула|f=i}} не возросло, значит {{Формула|f=X = X_2 = AC}} - это ключ. Причём, можно показать, что он единственный.<br />
<br />
Теперь предполагаем тройку:<br />
*{{Формула|f=X = AC}}<br />
*{{Формула|f=Y = A\subseteq R}}<br />
*{{Формула|f=H = B}} - непервичный атрибут, {{Формула|f=B\notin X}}<br />
<br />
Проверям три условия для неё:<br />
<br />
1)<br />
<br />
:{{Формула|f=X\rightarrow Y}}, так как {{Формула|f=AC\rightarrow A}} по 1 аксиоме Армстронга;<br />
<br />
2)<br />
<br />
:{{Формула|f=Y\rightarrow H}}, {{Формула|f=A\rightarrow B}} по условию;<br />
<br />
3)<br />
<br />
:{{Формула|f=Y\nrightarrow X}}, {{Формула|f=A\nrightarrow AC}}<br />
:{{Формула|f=A^+ = AB}}, {{Формула|f=AC\nsubseteq A^+}}<br />
<br />
Таким образом, найдена тройка, для которой выполняются все три условия, а значит отношение <u>не находится в 3НФ</u>.<br />
<br />
=== Пример 2 ===<br />
<br />
Декомпозируем эту схему отношения {{Формула|f=R}} на две схему отношений.<br />
<br />
{{Формула|f=R = (A, B, C, D)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B, AC\rightarrow D)}}<br />
<br />
{{Формула|f=\rho = (AB, ACD) = (R_1, R_2)}}<br />
<br />
Если {{Формула|f=R_1}} и {{Формула|f=R_2}} находятся в 3НФ, то значит всё {{Формула|f=\rho}} будет в 3НФ.<br />
<br />
Сначала покажем 3НФ у {{Формула|f=R_1 = (AB)}}, {{Формула|f=F = (A\rightarrow B)}}:<br />
<br />
:* {{Формула|f=X = A}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::{{Формула|f=Y = B}}, {{Формула|f=A\rightarrow B}}, {{Формула|f=B\nrightarrow A}}<br />
:* невозможно подобрать непервичный атрибут {{Формула|f=H\notin Y}}, потому что непервичным может быть только {{Формула|f=B}}.<br />
<br />
Таким образом, нельзя подобрать необходимую тройку. Значит, {{Формула|f=R_1}} находится в 3НФ.<br />
<br />
Теперь покажем 3НФ у {{Формула|f=R_2 = (ACD)}}, {{Формула|f=F = (AC\rightarrow D)}}:<br />
<br />
:* {{Формула|f=X = AC}} - выберем ключом<br />
:* {{Формула|f=Y}}, {{Формула|f=X\rightarrow Y}}, {{Формула|f=Y\nrightarrow X}}<br />
::а) {{Формула|f=A}} - что-то как-то не выполняется;<br />
::б) {{Формула|f=C}} - что-то как-то не выполняется;<br />
::в) {{Формула|f=D}} - что-то как-то не выполняется;<br />
::г) {{Формула|f=AD}} - что-то как-то не выполняется;<br />
::д) {{Формула|f=CD}} - что-то как-то не выполняется.<br />
:* {{Формула|f=H\notin Y}}, {{Формула|f=H = D}}<br />
::а) {{Формула|f=Y = A}}, {{Формула|f=Y\nrightarrow H}}<br />
::б) {{Формула|f=Y = C}}, {{Формула|f=Y\nrightarrow H}}<br />
::в-д) {{Формула|f=H\in Y}}<br />
<br />
Не удалось подобрать нужную тройку, так что {{Формула|f=R_2}} тоже находится в 3НФ.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%963_-_%D0%A5%D0%BE%D1%80%D0%BE%D1%88%D0%B0%D1%8F_%D1%81%D1%85%D0%B5%D0%BC%D0%B0_%D0%91%D0%94_-_%D0%A1%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D0%B7_%D0%BF%D0%BE%D1%82%D0%B5%D1%80%D1%8C&diff=2489
ТОРА (9) - Лекция №3 - Хорошая схема БД - Соединение без потерь
2013-01-11T21:46:29Z
<p>81.9.52.28: /* Пример */</p>
<hr />
<div>Пусть {{Формула|f=F}} и {{Формула|f=G}} - два множества ФЗ.<br />
<br />
{{Формула|f=G}} называется ''покрытием'' {{Формула|f=F}}, если имеет место равенство {{Формула|f=G^+ = F^+}}<br />
<br />
Существуют различные виды покрытий. Но мы рассмотрим только один - ''условно-неизбыточное покрытие''.<br />
<br />
== Алгоритм построения условно-неизбыточного покрытия ==<br />
<br />
1) если в множестве ФЗ {{Формула|f=F}} встречаются ФЗ с одинаковой левой частью {{Формула|f=X}}, то следует объединить эти ФЗ в одну ФЗ. Это следует из леммы объединения. Получившееся множество ФЗ обозначим {{Формула|f=G}};<br />
<br />
2) для каждой ФЗ {{Формула|f=X\rightarrow Y}} из {{Формула|f=G}} заменить её на {{Формула|f=X\rightarrow X^+ - X}};<br />
<br />
После выполнения 1) и 2) получаем замыкание {{Формула|f=G^+ = F^+}}<br />
<br />
=== Доказательство ===<br />
<br />
1)<br />
<br />
:Докажем, что если ФЗ {{Формула|f=X\rightarrow Y\in F}} (из этого следует, что {{Формула|f=Y \subseteq X^+}} (1) по определению замыкания множества аттрибутов), то эта ФЗ принадежит {{Формула|f=G^+}}<br />
<br />
:По построению G имеет место ФЗ: {{Формула|f=X\rightarrow X^+ - X}} (2)<br />
<br />
:Пополним эту ФЗ: {{Формула|f=X\rightarrow (X^+ - X)\bigcup X = X^+}} (3)<br />
<br />
:Теперь по первой аксиоме Армстронга из (1) имеем {{Формула|f=X^+\rightarrow Y}} (4)<br />
<br />
:Значит, {{Формула|f=X\rightarrow Y \in G^+}}, по третьей аксиоме Армстронга, исходя из (3) и (4).<br />
<br />
2)<br />
<br />
:Докажем обратное, что если {{Формула|f=X\rightarrow Y \in G}},то {{Формула|f=X\rightarrow Y \in F^+}}<br />
<br />
:По построению G имеем: {{Формула|f=Y = X^+ - X}} (5)<br />
<br />
:Для F имеем:<br />
:{{Формула|f=X\rightarrow X^+}} (по определению) (6)<br />
<br />
:{{Формула|f=X^+\rightarrow X^+ - X}} (1 аксиома Армстронга, так как {{Формула|f=X^+ - X\subseteq X^+}}) (7)<br />
<br />
:{{Формула|f=X\rightarrow X^+ - X = Y}} (3 аксимома Армстронга из (6)и (7), и по равенству (5))<br />
<br />
:В итоге получили {{Формула|f=X\rightarrow Y \in F^+}} Теорема доказана.<br />
<br />
=== Пример ===<br />
<br />
УСО: {{Формула|f=R = (A, B, C)}}<br />
<br />
Множество ФЗ: {{Формула|f=F = (A\rightarrow B, B\rightarrow A, C\rightarrow A, A\rightarrow C, B\rightarrow C)}}<br />
<br />
1)<br />
<br />
:{{Формула|f=G = (A\rightarrow BC, B\rightarrow AC, C\rightarrow A)}}<br />
<br />
2)<br />
<br />
:{{Формула|f=A^+ = ABC}}, {{Формула|f=A^+ - A = BC}}<br />
<br />
:{{Формула|f=B^+ = BAC}}, {{Формула|f=B^+ - B = AC}}<br />
<br />
:{{Формула|f=C^+ = CAB}}, {{Формула|f=C^+ - C = AB}}<br />
<br />
<br />
Тогда {{Формула|f=G = (A\rightarrow BC, B\rightarrow AC, C\rightarrow AB)}} будет являться УНП.<br />
<br />
== Свойства "хорошей" схемы БД ==<br />
<br />
"Хорошая", но не оптимальная. Должна обладать следующими свойствами:<br />
* соединение без потерь;<br />
* сохранение ФЗ;<br />
* каждая схема отношений в этой БД находится в 3НФ. Наличие этого свойства обеспечивает отсутствие в схемах отношений следующих аномалий:<br />
** избыточность;<br />
** потенциальная противоречивсть;<br />
** аномалия обновления;<br />
** аномалия удаления.<br />
<br />
=== Соединение без потерь ===<br />
<br />
Чтобы схема БД обладала свойством соединения без потерь, необходимо, чтобы хотя бы одна из таблиц содержала ключ универсальной схемы отношений.<br />
<br />
Пусть {{Формула|f=\rho = (R_1 ... R_n)}} - схема БД. Она будет обладать свойством соединения без потерь, если для любого экземпляра отношения {{Формула|f=r}} из {{Формула|f=R}} справедливо равенство: {{Формула|f=r = \Pi_{R_1}(r) \bowtie \Pi_{R_2}(r) \bowtie ... \bowtie \Pi_{R_n}(r)}}, где {{Формула|f=\Pi_{R_i}(r)}} - это проекция экземпляра отношения {{Формула|f=r}} на множество атрибутов {{Формула|f=R_i}}<br />
<br />
==== Пример БД, не обладающей свойством соединения без потерь ====<br />
<br />
{{Формула|f=R = (A, B, C)}}<br />
<br />
{{Формула|f=\rho = (AB, BC) = (R_1, R_2)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B)}}<br />
<br />
Достаточно привести пример экземпляра {{Формула|f=r}}, для которого равенство не выполняется:<br />
<br />
{| class="wikitable"<br />
! !! A !! B !! C<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=r}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|}<br />
<br />
{|<br />
| valign="top" |<br />
{| class="wikitable"<br />
! !! A !! B<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=\Pi_{R_1}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}}<br />
|}<br />
|<br />
| valign="top" |<br />
|<br />
{| class="wikitable"<br />
! !! В !! С<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=\Pi_{R_2}(r)}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|}<br />
|}<br />
<br />
Полученное соединение не будет равняться {{Формула|f=r}}:<br />
<br />
{| class="wikitable"<br />
! !! A !! B !! C<br />
|- align="center"<br />
| rowspan="4" | {{Формула|f=\Pi_{R_1}(r) \bowtie \Pi_{R_2}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|- align="center" bgcolor="#FFB6C1"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|}<br />
<br />
Этот пример показывает, что при неправильном построении БД запросы могут выдавать неправильный результат.<br />
<br />
==== Пример БД, обладающей свойством соединения без потерь ====<br />
<br />
{{Формула|f=R = (A, B, C)}}<br />
<br />
{{Формула|f=\rho = (AB, AC) = (R_1, R_2)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B)}}<br />
<br />
Возьмём тот же экземпляр:<br />
<br />
{| class="wikitable"<br />
! !! A !! B !! C<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=r}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|}<br />
<br />
{|<br />
| valign="top" | <br />
{| class="wikitable"<br />
! !! A !! B<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=\Pi_{R_1}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}}<br />
|}<br />
|<br />
| valign="top" |<br />
|<br />
{| class="wikitable"<br />
! !! A !! С<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=\Pi_{R_2}(r)}} || {{Формула|f=a_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=c_2}}<br />
|}<br />
|}<br />
<br />
Полученное соединение будет равняться {{Формула|f=r}}:<br />
<br />
{| class="wikitable"<br />
! !! A !! B !! C<br />
|- align="center"<br />
| rowspan="2" | {{Формула|f=\Pi_{R_1}(r) \bowtie \Pi_{R_2}(r)}} || {{Формула|f=a_1}} || {{Формула|f=b_1}} || {{Формула|f=c_1}}<br />
|- align="center"<br />
| {{Формула|f=a_2}} || {{Формула|f=b_1}} || {{Формула|f=c_2}}<br />
|}<br />
<br />
Но это не доказательство, а только один пример, просто чтобы показать, в чём разница.<br />
<br />
==== Алгоритм проверки схемы БД на свойство соединения без потерь ====<br />
<br />
{{Формула|f=\rho = (R_1 ... R_n)}}<br />
<br />
{{Формула|f=R = (A_1 ... A_n)}}<br />
<br />
1) построить таблицу T:<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=A_1}} || {{Формула|f=A_2}} || ... || {{Формула|f=A_k}}<br />
|- align="center"<br />
! {{Формула|f=R_1}}<br />
| || || ||<br />
|- align="center"<br />
! {{Формула|f=R_2}}<br />
| || || ||<br />
|- align="center"<br />
! ...<br />
| || || ||<br />
|- align="center"<br />
! {{Формула|f=R_n}}<br />
| || || ||<br />
|}<br />
<br />
И заполнить таблицу T по правилу: если {{Формула|f=A_j \in R_i}}, то {{Формула|f=T_{ij}=a}}, иначе {{Формула|f=T_{ij}=b_i}}<br />
<br />
2) изменить таблицу T - циклически просматривать ФЗ из {{Формула|f=F}} в любом порядке, и для очередной ФЗ {{Формула|f=X\rightarrow Y \in F}} выполнить следующие действия:<br />
* найти в таблице T строки, совпадающие по атрибутам {{Формула|f=X}} (по левой части);<br />
* если хотя бы в одной такой строке значение атрибута {{Формула|f=A_m \in Y = a}}, то во всех найденных строках присвоить {{Формула|f=A_m = a}}, иначе присвоить {{Формула|f=A_m = b_i}} (}}i}} - номер одной из найденных строк, {{Формула|f=b_i}} должно быть одинаково во всех указанных строках);<br />
* выполнить предыдущие два пункта для всех атрибутов {{Формула|f=A_l \in Y}};<br />
* выполнить предыдущие три пункта для всех ФЗ из {{Формула|f=F}}, циклически их просматривая.<br />
<br />
3) алгоритм останавливается, если при очередном просмотре ФЗ из {{Формула|f=F}}:<br />
* не произошло никаких изменений в таблице T;<br />
* какая-нибудь строка в T не стала состоять сплошь из символов {{Формула|f=a}} (наличие такой строки и говорит о выполнении свойства соединения без потерь).<br />
<br />
===== Пример =====<br />
<br />
Пусть {{Формула|f=R = (A, B, C)}}<br />
<br />
{{Формула|f=\rho = (AB, AC) = (R_1, R_2)}}<br />
<br />
{{Формула|f=F = (A\rightarrow B)}}<br />
<br />
Доказать, что {{Формула|f=\rho}} обладает свойством соединения без потерь.<br />
<br />
1)<br />
<br />
{| class="wikitable"<br />
! !! A || B || C<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
! AC<br />
| {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=a}}<br />
|}<br />
<br />
2)<br />
<br />
{|<br />
| valign="top" |<br />
{| class="wikitable"<br />
! !! A || B || C<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
! AC<br />
| {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=a}}<br />
|}<br />
|<br />
| valign="top" |<br />
|<br />
{| class="wikitable"<br />
! !! A || B || C<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
! AC<br />
| {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}}<br />
|}<br />
|}<br />
<br />
Получили строку, сплошь состоящую из {{Формула|f=a}}. Значит {{Формула|f=\rho}} обладает свойством соединения без потерь.<br />
<br />
===== Другой пример =====<br />
<br />
Пусть {{Формула|f=R = (A, B, C, D, E, F, P, S)}}<br />
<br />
{{Формула|f=\rho = (AB, ACDPS, BCPS, DEF) = (R_1, R_2, R_3, R_4)}}<br />
<br />
{{Формула|f=F = (B\rightarrow C, D\rightarrow EF, B\rightarrow PS, A\rightarrow CDPS, AP\rightarrow S)}}<br />
<br />
Доказать, что {{Формула|f=\rho}} обладает свойством соединения без потерь.<br />
<br />
1)<br />
<br />
{| class="wikitable"<br />
! !! A || B || C || D || E || F || P || S<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_1}} || {{Формула|f=b_1}} || {{Формула|f=b_1}} || {{Формула|f=b_1}} || {{Формула|f=b_1}} || {{Формула|f=b_1}}<br />
|- align="center"<br />
! ACDPS<br />
| {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=b_2}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! BCPS<br />
| {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! DEF<br />
| {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_4}} || {{Формула|f=b_4}}<br />
|}<br />
<br />
2)<br />
<br />
первый просмотр:<br />
<br />
{| class="wikitable"<br />
! !! A || B || C || D || E || F || P || S<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=b_1}} || {{Формула|f=b_1}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}}<br />
|- align="center"<br />
! ACDPS<br />
| {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=a}} || {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! BCPS<br />
| {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! DEF<br />
| {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_4}} || {{Формула|f=b_4}}<br />
|}<br />
<br />
второй просмотр:<br />
<br />
{| class="wikitable"<br />
! !! A || B || C || D || E || F || P || S<br />
|- align="center"<br />
! AB<br />
| {{Формула|f=a}} || {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="#32CD32" | {{Формула|f=a}} || bgcolor="#32CD32" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}}<br />
|- align="center"<br />
! ACDPS<br />
| {{Формула|f=a}} || {{Формула|f=b_2}} || {{Формула|f=a}} || {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || bgcolor="lime" | {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! BCPS<br />
| {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=b_3}} || {{Формула|f=a}} || {{Формула|f=a}}<br />
|- align="center"<br />
! DEF<br />
| {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=b_4}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=a}} || {{Формула|f=b_4}} || {{Формула|f=b_4}}<br />
|}<br />
<br />
Вот и получили строку, сплошь состоящую из {{Формула|f=a}}. Значит {{Формула|f=\rho}} обладает свойством соединения без потерь.<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28
https://iu5bmstu.ru/index.php?title=%D0%A2%D0%9E%D0%A0%D0%90_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%962_-_%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8&diff=2486
ТОРА (9) - Лекция №2 - Функциональные зависимости
2013-01-10T10:26:20Z
<p>81.9.52.28: /* Дополнение */</p>
<hr />
<div>Функциональные зависимости, замыкание множества функциональных зависимостей, атрибутов.<br />
<br />
== Функциональные зависимости ==<br />
<br />
Пусть {{Формула|f=R=(A_1 ... A_n)}} является функциональной схемой отношения и {{Формула|f=X}}, {{Формула|f=Y}} - некоторые подмножества атрибутов этой схемы. Говорят, что {{Формула|f=X}} функционально определяет {{Формула|f=Y}} ({{Формула|f=X\rightarrow Y}}), если в любом экземпляре отношения со схемой {{Формула|f=R}} не существует двух кортежей, совпадающих по подмножеству {{Формула|f=X}} и не совпадающих по подмножеству {{Формула|f=Y}}<br />
<br />
Иначе говоря, если два кортежа совпадают по {{Формула|f=x}}, то они должны совпадать и по {{Формула|f=y}}<br />
<br />
Например, {{Формула|f=R=(A_1, A_2, A_3, A_4)}}, есть зависимости:<br />
* {{Формула|f=A_1\rightarrow A_2}} (1)<br />
* {{Формула|f=A_1A_3\rightarrow A_4}} (2)<br />
<br />
Предположим, что имеет место один экземпляр отношения со схемой {{Формула|f=R}}<br />
<br />
{| class="wikitable"<br />
! !! {{Формула|f=A_1}} !! {{Формула|f=A_2}} !! {{Формула|f=A_3}} !! {{Формула|f=A_4}}<br />
|- align="center"<br />
| rowspan="3" | {{Формула|f=R}} || фирма X || улица Ленина, д.1 || сахар || 40<br />
|- align="center"<br />
| фирма X || улица Ленина, д.1 || карамель || 50<br />
|- align="center"<br />
| фирма X || улица Ленина, д.1 || пастила || 90<br />
|}<br />
<br />
Вторая ФЗ (2) имеет место быть, так как нет двух кортежей, совпадающих по этой паре. А первая ФЗ (1) не имеет место быть.<br />
<br />
== Замыкание множества функциональных зависимостей ==<br />
<br />
Пусть {{Формула|f=R}} - универсальная схема отношения, а {{Формула|f=F}} - исходное множество функциональной зависимости на этой схеме. Замыканием {{Формула|f=F}} называется всё множество функциональной зависимости, которое логически следует из {{Формула|f=F}} - обозначается как {{Формула|f=F^+}}<br />
<br />
Функциональная зависимость логически следует из {{Формула|f=F}}, если её можно вывести (получить) с помощью аксиом Армстронга.<br />
<br />
=== Аксиомы Армстронга ===<br />
<br />
Или правила вывода функциональной зависимости. Существуют различные интерпретации аксиом, но все эквивалентны. Потому приведём только один вариант.<br />
<br />
Аксиомы Армстронга являются надёжными и полными.<br />
<br />
'''Надёжность''' - если ФЗ выводится с помощью аксиом Армстронга, то она справедлива во всех экземплярах отношения, где справедливы исходные ФЗ {{Формула|f=F}}<br />
<br />
'''Полнота''' - если имеет место какая-либо ФЗ, то она обязательно может быть выведена с помощью аксиом Армстронга.<br />
<br />
==== Рефлексивность ====<br />
<br />
Если {{Формула|f=Y \subseteq X \subseteq R}}<br />
<br />
то {{Формула|f=X\rightarrow Y}}. Тривиальная аксиома.<br />
<br />
==== Дополнение ====<br />
<br />
Если {{Формула|f=X\rightarrow Y}},<br />
<br />
{{Формула|f=Z \subseteq R}} ({{Формула|f=Z}} может быть пустым),<br />
<br />
тогда {{Формула|f=X\bigcup Y\rightarrow Y\bigcup Z}} или {{Формула|f=XZ\rightarrow YZ}}<br />
<br />
==== Транзитивность ====<br />
<br />
Если {{Формула|f=X\rightarrow Y}}<br />
<br />
а {{Формула|f=Y\rightarrow Z}}<br />
<br />
то {{Формула|f=X\rightarrow Z}}<br />
<br />
=== Пример построения множества ФЗ ===<br />
<br />
Пусть задана УСО (универсальная схема отношения) {{Формула|f=R=(A, B, C)}} и зависимости {{Формула|f=F=(A\rightarrow B, B\rightarrow C)}}<br />
<br />
# {{Формула|f=A\rightarrow A}}, {{Формула|f=B\rightarrow B}}, {{Формула|f=C\rightarrow C}}, {{Формула|f=AB\rightarrow A}}, {{Формула|f=AB\rightarrow B}}, {{Формула|f=AC\rightarrow A}}, {{Формула|f=AC\rightarrow C}}, {{Формула|f=BC\rightarrow B}}, {{Формула|f=BC\rightarrow C}}, {{Формула|f=ABC\rightarrow A}}, {{Формула|f=ABC\rightarrow C}}, {{Формула|f=AB\rightarrow AB}}, {{Формула|f=AC\rightarrow AC}}, {{Формула|f=BC\rightarrow BC}}, {{Формула|f=ABC\rightarrow AB}}, {{Формула|f=ABC\rightarrow AC}}, {{Формула|f=ABC\rightarrow BC}}, {{Формула|f=ABC\rightarrow ABC}}<br><br><br />
# {{Формула|f=A\rightarrow AB}} (1ФЗ и пополняем A), {{Формула|f=AC\rightarrow BC}}, {{Формула|f=B\rightarrow BC}} (2 ФЗ и пополняем B), {{Формула|f=AB\rightarrow AC}}, {{Формула|f=AC\rightarrow ABC}}, {{Формула|f=AB\rightarrow ABC}}, {{Формула|f=AB\rightarrow BC}}, {{Формула|f=A\rightarrow AC}}<br><br><br />
# {{Формула|f=A\rightarrow C}} (1 и 2 ФЗ), {{Формула|f=A\rightarrow ABC}}<br />
<br />
Всё, замыкание ({{Формула|f=F^+}}) построено. Все перечисленные зависимости образуют замыкание.<br />
<br />
=== Лемма ===<br />
<br />
Справедливы следующие правила. Для их доказательства необходимо пополнить ФЗ так, чтобы можно было использовать аксиомы.<br />
<br />
==== Правило объединения ====<br />
<br />
Если {{Формула|f=X\rightarrow Y}} и {{Формула|f=X\rightarrow Z}}, то {{Формула|f=X\rightarrow YZ}}<br />
<br />
Доказательство:<br />
# {{Формула|f=X\rightarrow XY}} (1 ФЗ и пополняем X);<br />
# {{Формула|f=XY\rightarrow YZ}} (2 ФЗ и пополняем Y);<br />
# {{Формула|f=X\rightarrow YZ}} (по аксиоме транзитивности).<br />
<br />
==== Правило декомпозиции ====<br />
<br />
Если {{Формула|f=X\rightarrow Y}}, а {{Формула|f=Z \subseteq Y}}, то {{Формула|f=X\rightarrow Z}}<br />
<br />
Доказательство:<br />
# {{Формула|f=X\rightarrow Y}} (по условию);<br />
# {{Формула|f=Y\rightarrow Z}} (по аксиоме рефлексивности);<br />
# {{Формула|f=X\rightarrow Z}} (по аксиоме транзитивности).<br />
<br />
==== Правило псевдотранзитивности ====<br />
<br />
Если {{Формула|f=X\rightarrow Y}} и {{Формула|f=WY\rightarrow Z}}, то {{Формула|f=WX\rightarrow Z}}<br />
<br />
Доказательство:<br />
# {{Формула|f=WX\rightarrow WY}} (1 ФЗ и пополняем W);<br />
# {{Формула|f=WY\rightarrow Z}} (по условию);<br />
# {{Формула|f=WX\rightarrow Z}} (по аксиоме транзитивности).<br />
<br />
== Замыкание множества атрибутов ==<br />
<br />
Замыкание {{Формула|f=F^+}} может включать в себя очень большое количество ФЗ. Например:<br />
<br />
$F=(X\rightarrow A_1, X\rightarrow A_2 ... X\rightarrow A_n)$<br />
<br />
{{Формула|f=X\rightarrow Y \subseteq F^+}}<br />
<br />
{{Формула|f=Y \subseteq (A_1, A_2 ... A_n)}} и таких подмножеств может быть {{Формула|f=2^n}}<br />
<br />
Поэтому "в лоб" замыкание {{Формула|f=F^+}} никто не строит. Но необходимо найти какой-то метод, который достаточно просто позволял бы выяснять, принадлежит ли произвольная ФЗ {{Формула|f=X\rightarrow Y}} к {{Формула|f=F^+}}<br />
<br />
Для этого применяется ''замыкание множества атрибутов''. Пусть {{Формула|f=R}} - универсальная схема отношения, а {{Формула|f=X}} - некоторое подмножество атрибутов. Тогда замыканием множества атрибутов {{Формула|f=X^+}} называется совокупность атрибутов {{Формула|f=A_{i1}, A_{i2} ... A_{ik} }} таких, что {{Формула|f=X\rightarrow A_{i1}, X\rightarrow A_{i2} ... X\rightarrow A_{ik} }}<br />
<br />
=== Алгоритм построения ===<br />
<br />
Алгоритм является итерационной процедурой.<br />
<br />
# полагаем {{Формула|f=i = 0}} и {{Формула|f=X_0^+=X}}, а {{Формула|f=X_i^+}} - замыкание множества атрибутов на i-том шаге;<br />
# {{Формула|f=X _{i+1} ^+ = X _i ^+ \bigcup V}}, где V - такое множество атрибутов в F, и {{Формула|f=Y\rightarrow Z}}, {{Формула|f=Y \subseteq X _i ^+}}, {{Формула|f=V \subseteq Z}};<br />
# если {{Формула|f=X_{i+1}^+ = X_i^+}}, то {{Формула|f=X^+ = X_i^+}}, иначе {{Формула|f=i = i + 1}} и возвращаемся в пункт 2.<br />
<br />
==== Пример построения ====<br />
<br />
Пусть {{Формула|f=R=(A, B, C, D, E, G)}}<br />
<br />
{{Формула|f=F=(AB\rightarrow C, C\rightarrow A, BC\rightarrow D, ACD\rightarrow B, D\rightarrow EG, BE\rightarrow C, CG\rightarrow BD, CE\rightarrow AG)}}<br />
<br />
{{Формула|f=X = BD}}<br />
<br />
Надо построить {{Формула|f=X^+}}:<br />
<br />
1) {{Формула|f=i = 0}}, {{Формула|f=X _0 ^+ = BD}}<br />
<br />
2) <br />
<br />
{| class="wikitable"<br />
! {{Формула|f=i}} !! {{Формула|f=Y\rightarrow Z}}, для которых {{Формула|f=Y \subseteq X_i^+}} !! {{Формула|f=V\subseteq Z}} !! {{Формула|f=X_{i+1}^+ = X_i^+\bigcup V}}<br />
|- align="center"<br />
| 0 || {{Формула|f=D\rightarrow EG}} || {{Формула|f=EG}} || {{Формула|f=BDEG}}<br />
|- align="center"<br />
| 1 || {{Формула|f=BE\rightarrow C}} || {{Формула|f=C}} || {{Формула|f=BDEGC}}<br />
|- align="center"<br />
| 2 || {{Формула|f=C\rightarrow A}}<br>{{Формула|f=BC\rightarrow D}}<br>{{Формула|f=CG\rightarrow BD}}<br>{{Формула|f=CE\rightarrow AG}} || {{Формула|f=A}} || {{Формула|f=BDEGCA}}<br />
|- align="center"<br />
| 3 || {{Формула|f=AB\rightarrow C}}<br>{{Формула|f=ACD\rightarrow B}} || - || {{Формула|f=BDEGCA}}<br />
|}<br />
<br />
Получили, что {{Формула|f=X_4^+ = X_3^+}}, а значит {{Формула|f=X^+ = X_3^+ = BDEGCA}}<br />
<br />
Это означает, что имеют место следующие ФЗ: $BD\rightarrow B$, {{Формула|f=BD\rightarrow D}}, {{Формула|f=BD\rightarrow E}}, {{Формула|f=BD\rightarrow G}}, {{Формула|f=BD\rightarrow C}}, {{Формула|f=BD\rightarrow A}}, и все они {{Формула|f=\subseteq F^+}}<br />
<br />
Короче, чтобы проверить {{Формула|f=X\rightarrow Y \subseteq F^+}}, необходимо построить {{Формула|f=X^+}}<br />
<br />
[[Категория:Теоретические основы реляционной алгебры (9 семестр)]]<br />
[[Категория:Конспекты лекций и семинаров]]</div>
81.9.52.28