Exercise #51 |
||||||||
Find the names of the ships having the largest amount of guns among all the ships with the same displacement (taking into account Outcomes table). Solution 3.8.1. It is not quite optimal, and what is more, it contains an error.
In the FROM clause of the above solution two subqueries are joined. The first one determines names, number of guns and displacement of all the ships from the database. These ships are collected from two tables - Ships and Outcomes (leading ships). In so doing, an incorrect and redundant check for duplicates is performed:
Why incorrect? Because it retains duplicates all the same, tallying up a lead ship as many times as it takes part in battles. And redundant is it, because the UNION clause will remove duplicates anyway. It proved quite useful in this case, the query, though being not optimal, yielding the result as expected against the algorythm. The second subquery in the join statement determines the maximun number of guns for each displacement value of the available ships, and here, like we did before, these values are calculated separately for the ships from Ships and for the lead ships from Outcomes, followed by unioning. Joining is performed across matching numbers of guns and displacements in the rows of the subqueries. Logic of building up the solution is quite correct, but the implementation is not. To prove it, one usually resorts to a counterinstance. Putting it in other words, we will present an instance of data for which the query yields a wrong result. Well, let there be ships with 40 000 tons displacement and maximum number of guns 16 only in the Ships table, and the lead ship with 40 000 tons displacement and maximum number of guns 17 only in the Outcomes. Then the second join subquery will produce two rows:
|