Решение 3.13.2
Консоль
SELECT class, SUM ( sunk)
FROM ( SELECT class, COUNT ( *) AS sunk
FROM Ships a JOIN
Outcomes b ON a.name = b.ship AND
a.class <> b.ship
WHERE result = 'sunk'
GROUP BY class
UNION ALL
SELECT class, '1'
FROM Classes a JOIN
Outcomes b ON a.class = b.ship
WHERE result = 'sunk'
UNION ALL
SELECT class, '0'
FROM classes
) t
-- где классы с числом кораблей больше 2:
WHERE class IN ( SELECT t1.class
FROM ( SELECT a.class
FROM Classes a LEFT JOIN
Ships b ON a.class = b.class
) t1 LEFT JOIN ( SELECT DISTINCT ship
FROM Outcomes
WHERE ship NOT IN ( SELECT name
FROM Ships
)
) t2 ON t1.class = t2.ship
GROUP BY t1.class
HAVING COUNT ( *) > 2
)
GROUP BY class
HAVING SUM ( sunk) > 0 ;
Решение 3.13.3
Консоль
SELECT a.class AS cls, a.num_sunks AS sunk
FROM ( SELECT c.class, COUNT ( o.ship) AS num_sunks
FROM Outcomes o LEFT JOIN
Ships s ON o.ship = s.name LEFT JOIN
Classes c ON s.class = c.class
WHERE o.result = 'sunk'
GROUP BY c.class) a,
( SELECT c1.class
FROM Ships s1, Classes c1
WHERE s1.class = c1.class
GROUP BY c1.class
HAVING COUNT ( name) >= 3
) B
WHERE a.class = b.class;
Решение 3.13.4
Консоль
SELECT class, COUNT ( result) AS sunk
FROM ( SELECT class, result, name
FROM Ships LEFT JOIN
Outcomes ON ship=name AND
class IS NOT NULL AND
result = 'sunk'
) T
GROUP BY class
HAVING COUNT ( class) > 2 AND
COUNT ( result) > 0 ;
Проанализируйте тонкости вышеприведенных решений, самым красивым из которых, безусловно, является 3.13.4. Всего лишь одно соединение, для которого сразу подсчитывается как количество потопленных, так и общее число кораблей в классе. У этих решений имеется общая ошибка, о которой шла речь выше: не учтены головные корабли, которые присутствуют в таблице Outcomes и отсутствуют в таблице Ships.
ПиР
Решить задачу на SQL-EX.RU