Your two immediate problems:
The derived table
MyTable
(alias name for the subquery) is not visible in another subquery one level below. LATERAL in Postgres 9.3 would allow something of the kind, but the query is backwards anyway.The expression
MAX(taken)
does not evaluate toboolean
, which would make it a validWHERE
clause but, again, the whole approach is incorrect.
Rewrite this. Probably the shortest form to get what (I think) you are after:
SELECT b.years, count(e.taken) AS ct_taken
FROM database.book b
JOIN database.exempl e USING (numb)
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1;
Join table
book
to tableexempl
on the columnnumb
. Since the columns have the same name, I simplified withUSING
. This is optional. Also using table aliases to simplify the syntax. Also optional.Group by
book.years
and count the number rows whereexempl.taken
isNOT NULL
. Ifexempl.taken
is definedNOT NULL
you can simplify tocount(*)
.Order the result by this count (
ORDER BY 2
) and only return one row (LIMIT 1
) with the maximum count. If there are multiple rows with the same maximum, the pick is arbitrary unless you add moreORDER BY
items.
Details in the manual about SELECT
.
Do you really have a schema called database
? That's a most confusing design. Consider fixing that.
If there are multiple years for the biggest count, you get an arbitrary pick from those unless you add more ORDER BY
items.
Without LIMIT
Use row_number()
as mentioned by a_horse, but over the count, not the base column:
SELECT years, ct_taken
FROM (
SELECT b.years, count(e.taken) AS ct_taken
row_number() OVER (ORDER BY count(e.taken) DESC) AS rn
FROM database.book b
JOIN database.exempl e USING (numb)
GROUP BY 1
ORDER BY 2 DESC
) sub
WHERE rn = 1;
This works because you can have window functions over aggregate functions.