04:27

# Exercise #39 page 3

Solution 3.4.3

It's said but true, the following query was accepted by the system until the last days:

Console
Execute
`SELECT s.nameFROM Ships s JOIN  Outcomes o ON s.name = o.ship JOIN  Battles b ON o.battle = b.nameGROUP BY s.name HAVING COUNT(s.name) = 2 AND  (MIN(result) = 'damaged' OR  MAX(result) = 'damaged' )UNION SELECT o.shipFROM Classes c JOIN  Outcomes o ON c.class = o.ship JOIN  Battles b ON o.battle = b.name WHERE o.ship NOT IN (SELECT name  FROM Ships ) GROUP BY o.ship HAVING COUNT(o.ship) = 2 AND  (MIN(result) = 'damaged' OR  MAX(result) = 'damaged' );`

Firstly, the queries, which perform joining the ships taken part in battles (Outcomes table) with the Ships table and Classes table accordingly, are being united. By the way, the predicate

`o.ship NOT IN (SELECT name FROM Ships)`
in the second query is apparently unwanted, because UNION will exclude all possible duplicates.

These joins are not just surplus, they are wrong, as the description of the database says that in the Outcomes table can be ships that are absent from Ships table. That is, if not the leading ship is found, which is absent from the Ships table and which satisfies the task terms, then it will not get into the resulting set of the aforecited query.

Secondly, the predicate

`HAVING COUNT (o.ship) = 2`
confines possible variants with only two ship battles. And why can't the ship take part in more than two battles? It was not obligatory sunk after it had been damaged. And he could participate in battles and before damage (for example, with result "ok"). Then, if in the following and the last battle of a ship she has been damaged, the query 3.4.3 will deduce this ship though it and does not respond conditions of the task.

Thirdly, I don't quite understand the condition:

`(MIN(result) = 'damaged' OR MAX(result) = 'damaged')`

 Pages 1 2 3 4