Я бы решил это с помощью условия exists
, которое фильтрует людей, у которых есть внуки:
select avg(age) avg_age_of_grandpas
from human h
where
gender = 'm'
and exists (
select 1
from parent p1
inner join parent p2 on p2.parentName = p1.childName
where p1.parentName = h.name
)
Условие exists
гарантирует, что у этого человека будет хотя бы один ребенок и один внучатый ребенок. Внешний запрос вычисляет среднее значение таких людей. Учитывая информацию, доступную в структуре вашей таблицы, это кажется мне наиболее логичным подходом. В отличие от join
s, использование exists
позволяет избежать дублирования записей (и получить неверные результаты в среднем), когда у человека более одной строки потомков.
Если вы хотите указать возрастпрародитель в день, когда родился их первый внучат, тогда это немного сложно. Это должно приблизить вас к тому, что вы ожидаете:
select avg(h.age - g.maxGrandChildAge) avg_age_of_grandpas
from human h
inner join (
select
p1.parentName grandParentName,
max(h1.age) maxGrandChildAge
from parent p1
inner join parent p2 on p2.parentName = p1.childName
inner join human h1 on h1.name = p2.childName
) g
on g.grandParentName = h.name