Задавайте вопросы, мы ответим
Вы не зашли.
1. Найдите пары классов, имеющих одинаковые калибр орудий и страну. В результате каждая пара указывается только один раз, т.е. (i,j), но не (j,i), Порядок вывода: класс 1, класс 2, калибр орудия и страна. (SELECT)
2. Добавить отсутствующие в таблице Ships головные корабли из Outcomes. Годом спуска на воду считать средний округленный до целого числа год по кораблям страны добавляемого корабля. Если средний год неизвестен, запись не вносить. (DML)
3. Потопить в следующем сражении суда, которые в первой своей битве были повреждены и больше не участвовали ни в каких сражениях. Если следующего сражения для такого судна не существует в базе данных, не вносить его в таблицу Outcomes. Замечание: в базе данных нет двух сражений, которые состоялись бы в один день.(DML)
Рассматривается БД кораблей, участвовавших во второй мировой войне. Имеются следующие отношения:
Battles (name, date)
Classes (class, type, country, numGuns, bore, displacement)
Outcomes (ship, battle, result)
Ships (name, class, launched)
Корабли в «классах» построены по одному и тому же проекту, и классу присваивается либо имя первого корабля, построенного по данному проекту, либо названию класса дается имя проекта, которое не совпадает ни с одним из кораблей. Корабль, давший название классу, называется головным.
Отношение Classes содержит имя класса, тип (bb для боевого (линейного) корабля или bc для боевого крейсера), страну, в которой построен корабль, число главных орудий, калибр орудий (диаметр ствола орудия в дюймах) и водоизмещение ( вес в тоннах). В отношении Ships записаны название корабля, имя его класса и год спуска на воду. В отношение Battles включены название и дата битвы, в которой участвовали корабли, а в отношении Outcomes – результат участия данного корабля в битве (потоплен-sunk, поврежден - damaged или невредим - OK). Замечание. В отношение Outcomes могут входить корабли, отсутствующие в отношении Ships.
Неактивен
У меня просто мозг клинит, когда я пытаюсь понять условия запросов. Не могли бы Вы, если не сложно, все по шагам хотя бы описать, но, если не затруднит, то и написать. Спасибо.
Неактивен
Прошу обратить внимание. Мне очень интересно понять структуру данных запросов.
Неактивен
Люди, Вы где? Сильно помощь Ваша нужна...
Неактивен
Люди отдыхают по выходным
1. Первая задача простая, кроме условия, что нужно указывать пару только один раз. Нужно просто придумать какое-то хитрое условие выбора пары. Например, i < j:
select c1.class, c2.class, c1.bore, c1.country from Classes c1, Classes c2 WHERE c1.country = c2.country AND c1.bore = c2.bore AND c1.class < c2.class;
2. Тут неплохо разбить задачку на два этапа: а) найти корабли, которые есть в исходах, но которых нет в таблице классов (LEFT JOIN) б) добавить эти корабли (подзапрос + INSERT). Думаю, справитесь.
3. Это единственное плохо понимаемое условие. Но такие случаи действительно бывают. То есть в первой схватке корабль зацепили, и во второй — тоже зацепили. Тогда он побывал в двух схватках и при этом еще не потонул
Хорошего простого решения тут сходу не вижу. Но можно сделать рекогносцировку и выяснить, что дважды в бою побывал только один корабль
Неактивен
Спасибо. Хорошо, я подумаю. Если не получится, спрошу. Извиняюсь, если потревожил.
Неактивен
1. С этой задачей разобрался. Вы правы, она не сложная.
2. Не понимаю, зачем связывать с таблицей классов на данном этапе? Тут бы просто выборку получить. Сколько не пробую использоваться LEFT JOIN всегда получаю только значения из левой таблицы, соотношения со связанной нет.
3. Тут я вообще молчу. Я в этой задаче только слова понимаю.
Отредактированно pkhell (25.04.2011 21:51:29)
Неактивен
Вы уж не ругайтесь. Я действительно не могу сообразить.
Неактивен
Ну, Вы попробуйте для начала получить список тех кораблей, которые есть
в исходах, но которых нет в таблице классов. Любым способом.
Неактивен
Нашел общие корабли среди Outcomes и Classes. Их оказалось 2. Но вот заставить исключить их из выборки не получается. Пробовал и NOT, и даже (NOT) EXISTS. Как можно создать исключающий запрос?
Неактивен
SELECT ... FROM a LEFT JOIN b ON a.field_a = b.field_b WHERE b.field_b IS NULL.
Левое объединение подставляет NULL в случае, когда в правой таблице нет
данных. Соответственно, можно использовать это в WHERE.
Неактивен
Вы сказали, что нужно вывести корабли из исходников (Outcomes и Ships), которых нет в таблице Classes. Получилось следующее:
Отредактированно pkhell (28.04.2011 21:19:07)
Неактивен
Первая часть — да. А зачем нужна вторая? Вам же надо добавить те корабли,
которые есть в исходах, но нет в списке кораблей? Т.е. только первую часть?
Неактивен
По сути, исходя из задания, нужно из таблицы Outcomes добавить головные корабли в таблицу Ships, то есть те, которые есть в outcomes и нет в Ships. Я так понимаю задание. Таблица Classes нужна только для выборки. Или все не так? Это все по поводу задачи №2.
Неактивен
Получается, что запрос на отсутствующие корабли в таблице ships должен выглядеть следующим образом:
Неактивен
Воо, замечательно. Проблема в том, что мы не можем далее никаким образом
угадать, какой стране принадлежит тот или иной корабль. Кроме некоторых
(которые есть в Classes). Посему предлагаю присоединить еще таблицу Classes
внутренним объединением, таким образом отсеяв корабли, для которых мы мо-
жем сделать хоть что-то:
[silentia] root test > SELECT o.ship, c.country FROM Outcomes o LEFT JOIN Ships s ON o.ship = s.name JOIN Classes c ON c.class = o.ship WHERE s.name IS NULL; +----------+---------+ | ship | country | +----------+---------+ | Bismarck | Germany | +----------+---------+ 1 row in set (0.00 sec)
Ну и задача, как я понимаю, состоит в том, чтобы добавить этот корабль в Ships.
Неактивен
Я все меньше начинаю понимать запрос, с которым мы с Вами работаем. Получается, что из всех кораблей, которые были в выходной запросе, только один имеет страну. Это хорошо. Теперь смотрим в таблицу ships и видим, что с у данной страны нет года спуска на воду. Получается, что, согласно условию, такой корабль добавлять не стоит. Я так понимаю? Мне вот теперь только интересно, зачем в условии написано "корабли", когда запросом INSERT можно за раз добавить только одну строчку? В общем, я пока сделал так:
Отредактированно pkhell (29.04.2011 18:32:17)
Неактивен
Нет, страна есть у каждого корабля, просто у некоторых кораблей мы страну
не знаем (хотя, можем догадываться по названию, например).
Сделать точно так же — подзапросами. Нужно выбрать средний год спуска в
этой стране, а класс Вы знаете, т.к. с табличкой классов объединение уже
было (и, учитывая условие, он совпадает с названием корабля ).
Неактивен
Я правильно понимаю, что добавлять мы имеем право только корабль Bismark? Но почему? Класс знаю я, но надо же сделать так, чтобы автоматически SQL по-классу определял страну и год спуска на воду, ведь иначе не правильно будет. Или я совсем туплю?)))
Неактивен
Представьте, что Вы пришли в зоопарк. Ваша задача — записать на листочке
всех животных, которые живут на полюсах. В качестве помощи в этой нелегкой
задаче, Вам дают справочник птиц. Вы можете, в соответствии со справочником,
найти пингвина, а вот белого медведя Вы найти не можете, потому что он не
птица
Точно так же и у Вас — у Вас есть куча кораблей, которые подходят под условие
«участвовали, но нет в списке», но только один из них есть в справочнике.
Напишите отдельный подзапрос для года спуска — и задача решена.
Неактивен
Подробно объяснили. Попробую реализовать. )
Неактивен
Итак, я поэкспериментировал и пришел к выводу, что получить год спуска у данного корабля нельзя, так как в базе подобное информации нет, либо я не могу ее найти. На данный момент я сделал INSERT на добавление еще и класса, но он, почему-то, не работает, выдает ошибку синтаксиса в Pma:
Неактивен
Итак, запрос на добавление корабля и класса:
Неактивен
Точно так же — SELECT AVG(launched) FROM Ships JOIN Classes USING(class) JOIN ( подзапрос, определяющий страну )
Неактивен
Суть не в том, как написать запрос. Суть в том, что у германских кораблей нет года спуска. )) Мне преподаватель сказал, что надо свой корабль добавить. ))
Неактивен