Removing the "launched" column from grouping isn't enough to correct this mistake.
Console
SELECT MIN(launched)
FROM Ships aa, Classes bb
WHERE bb.class = aa.class
GROUP BY country;
as a result we will get minimal years by every country:
Then rows that satisfies predicate would look like this:
| country
|
x
|
launched
|
| Gt.Britain | 6 | 1916 |
| Japan | 1 | 1913 |
| Japan | 1 | 1916 |
| USA | 1 | 1920 |
|
Thereby we have already lost correct rows for Japan and USA. We should take notice of this row for Japan:
only by the reason that 1916th year concured with minimal year for USA. The following code doesn't have any sense. But it has mistake though. In the main query:
SELECT country, MAX(x), MIN(launched)
…
GROUP BY country
we have grouping by country with determining of two aggregated factors — maximum of ships’ quatities and minimum of years. Using of grouping in this case leads to mistake. Indeed, rows that we need could already be found in table which in the FROM clause (for instance {Gt.Britain, 6, 1916}). We do not need any grouping here, we only need to filter out wrong rows. As a result of grouping only one row will be remained. It have statistic rates for whole group. In this case the maximum and the minimum gain in different rows of the group. This is clearly visible at USA’s ships table. In this one minimal year does not correspond maximum value (x=1). The maximum value (x=3) is reached at 1941th year. That’s why such grouping may return right result only if all “x” values for country are equal.
Everything in this solution is reversed. Nevertheless let’s try to correct it by finding out the reasons of mistakes and delusions.
Correlated subquery is needed for binding of year and country. It can be used in WHERE clause (AND aa.country = s.country):
WHERE launched = ANY(SELECT MIN(launched)
FROM Ships bb, Classes aa
WHERE aa.class = bb.class AND
aa.country = s.country
GROUP BY country
)
That is correct, but don’t take any effect for now, except maybe it excludes wrong row:
For advance we need to calculate minimal year among ones with maximum quantity of ships for each contry. Maximum quantity of ships is primary here. If we would filter only by minimal year we can lose right rows. That’s why we need to count quantity of ships, not a minimal year:
WHERE x >= ALL(SELECT COUNT(launched)
FROM Ships bb, Classes aa
WHERE bb.class = aa.class AND
s.country=aa.country
GROUP BY country, launched
)
Take a note at predicate >= ALL which gives us maximal value of “x”. Let’s rewrite whole query with taking into account all we have said about grouping in the main query.
Solution 3.6.2
Console
SELECT country, x, launched
FROM (SELECT country, COUNT(*) x , launched
FROM Ships b, Classes a
WHERE a.class = b.class
GROUP BY country, launched
) s
WHERE x >= ALL(SELECT COUNT(launched)
FROM Ships bb, Classes aa
WHERE bb.class = aa.class AND
s.country=aa.country
GROUP BY country, launched
);
Is this all? Not at all. If maximum value would be gained in several different years the row for every such year will occur in the result. But we need to output the row with minimal year by the data. As it was noted above, this is the certain case when grouping is valid: all “x” values for country are equal and maximal.