Como juntar em três tabelas no mysql

Filippo perri

Eu tenho três mesas:

grupo

id_group (PK) | name

registry_in_group

id_group (PK-FK) | id_registry (PK-FK)

registro

id_registry (PK) | name | surname | dob (DATE)

Tenho que selecionar nomes de grupos que contenham apenas registros com idade superior a 18 anos.

Esta é a minha consulta:

SELECT g.name 
FROM group as g
JOIN registry_in_group as aig 
    ON g.id_group = aig.id_group
JOIN registry as a 
    ON aig.id_registry = a.id_registry 
    AND TIMESTAMPDIFF(YEAR, a.dob, CURDATE()) >= 18

Mas esse retorno também registro menor 18. Por quê?

GMB

O problema com sua consulta é que ela encontra os grupos que têm pelo menos um registro com mais de 18 anos, enquanto você deseja garantir que todos os registros no grupo cumpram essa condição.

Você pode usar uma subconsulta correlacionada com uma not existscondição para filtrar os grupos para os quais nenhum registro é menor que 18:

select g.*
from groups g
where not exists (
    select 1
    from registry_in_group rig
    inner join registry r 
        on  r.id_registry = rig.id_registry 
        and timestampdiff(year, r.dob, curdate()) < 18
    where rig.id_group = g.id_group
)

Outra opção, baseada em sua consulta, é usar a agregação com uma havingcláusula para filtrar os grupos que contêm um registro com menos de 18 anos:

select g.name 
from groups g
inner join registry_in_group rig 
    on g.id_group = rig.id_group
inner join registry r
    on rig.id_registry = r.id_registry 
group by g.id_group, g.name
having sum( timestampdiff(year, r.dob, curdate()) < 18 ) = 0

NB: conforme comentado por Strawberry, groupé uma palavra reservada em todos os RDBMS; Usei em groupsvez disso, para evitar confusão.

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados