-- 1) Trovare nome ed eta' delle madri di persone che guadagnano piu` di 20.

select m.nome, m.eta
from persone m, maternita t, persone f
where f.nome=t.figlio and m.nome=t.madre and
      f.reddito>20
;

-- 2) Trovare le nonne da parte di madre delle persone maggiorenni

select n.madre
from maternita n, maternita m, persone f
where n.figlio = m.madre and m.figlio = f.nome and f.eta >= 18
;

-- 3) Delle persone con entrambi i genitori memorizzati, restituire nome, padre e madre

select m.figlio, p.padre, m.madre
from maternita m, paternita p
where m.figlio = p.figlio
;

-- 3bis) Delle persone (solo figli) restituire nome ed eventuali padre e madre

select m.figlio, p.padre, m.madre
from maternita m full outer join paternita p on
     m.figlio = p.figlio
;

--oppure se, come per MySQL 5, il DBMS non mette a disposizione 
--il full outer join

select m.figlio, p.padre, m.madre          -- prendiamo il figlio da m
from maternita m left join paternita p on  -- (non vogliamo null su figlio)
     m.figlio = p.figlio
UNION
select p.figlio, p.padre, m.madre          -- prendiamo il figlio da p
from maternita m right join paternita p on -- (non vogliamo null su figlio)
     m.figlio = p.figlio

;

-- 3tris) Delle persone (tutte) restituire nome ed eventuali padre e madre

select pp.nome, p.padre, m.madre
from persone pp left outer join paternita p on pp.nome = p.figlio
                left outer join maternita m on pp.nome = m.figlio
;

-- 4) Trovare i figli (in comune) di Franco e Maria 

select m.figlio
from maternita m, paternita p
where m.figlio = p.figlio 
      and p.padre = 'Franco' and m.madre = 'Maria' 
;

-- 5) Trovare i fratelli da parte di madre di 'Maria'

select m2.figlio
from maternita m1, maternita m2
where m1.madre = m2.madre and 
      m1.figlio = 'Maria' and 
      m2.figlio <> 'Maria' -- nota per evitare di restituire 'Maria' stessa
;

-- 6) Trovare le coppie di fratelli da parte di madre

select m1.figlio, m2.figlio
from maternita m1, maternita m2
where m1.madre = m2.madre and 
      m1.figlio < m2.figlio -- nota per evitare ripetizioni permutate
;

-- 7) Per ciascun padre trovare l'eta media dei figli

select t.padre, avg(f.eta) as etamediafigli
from paternita t, persone f
where t.figlio = f.nome
group by t.padre
;

-- 8) Per ciascun padre, restituire nome, eta e l'eta media dei figli

select p.nome, p.eta, avg(f.eta) as etamediafigli
from persone p, paternita t, persone f
where t.padre = p.nome and t.figlio = f.nome
group by p.nome, p.eta
;

-- 9) Per ciascun padre, restituire nome, eta e numero figli

select p.nome, p.eta, count(*) as numfigli
from persone p, paternita t
where t.padre = p.nome
group by p.nome, p.eta
;

-- 10) Restituire nome ed eta dei padri con due o piu figli maggiorenni

select p.nome, p.eta
from persone p, paternita t, persone f
where t.padre = p.nome and t.figlio = f.nome and 
      f.eta >=18
group by p.nome, p.eta
having count(t.figlio) >= 2
;

select p.nome, p.eta
from persone p, paternita t1, persone f1, paternita t2, persone f2
where t1.padre = p.nome and t1.figlio = f1.nome and 
      t2.padre = p.nome and t2.figlio = f2.nome and 
	  t1.figlio <> t2.figlio and  
      f1.eta >=18 and
      f2.eta >=18
;

-- 11) Restituire nome dei padri i cui figli hanno tutti piu di 30 anni

select padre     -- i padri
from paternita
except           -- meno
select t.padre   -- i padri che hanno un figlio con eta minore o uguale a 30
from paternita t, persone f
where t.figlio = f.nome and 
      f.eta <= 30
;

select padre         -- i padri
from paternita
where padre not in ( -- MySQL non supporta except 
select t.padre       -- i padri che hanno un figlio con eta minore o uguale a 30
from paternita t, persone f
where t.figlio = f.nome and 
      f.eta <= 30
)
;
--PS. Assumimamo non ci siano valori null su eta
       