Boa noite!
Testei no ambiente Oracle, dentre as possibilidades de resolver o exercício proposto, as alternativas que mais me chamaram a atenção foram:
1. Utilizando a função nativa do Oracle: MONTHS_BETWEEN
Aqui, a sintaxe é simples e garante ótima precisão, considerando anos bissextos entre as datas calculadas.
SELECT
Nome,
DataNascimento AS "Data de nascimento",
CPF
FROM
TabelaClientes
WHERE
TRUNC(MONTHS_BETWEEN(SYSDATE, DataNascimento) / 12) >= 18;
Explicando o código da cláusula WHERE, a função MONTHS_BETWEEN calcula a diferença, em meses, entre duas datas - no nosso caso SYSDATE (data atual do sistema) e a data de nascimento registrada no BD.
Por isso, para transformar o resultado em anos, foi feita a divisão do retorno da função por 12.
Foi utilizada a função TRUNC no resultado de todo o cálculo, para arredondá-lo para baixo, garantindo que a informação sempre seja um inteiro que represente a idade completa da pessoa, em anos.
Por fim, através de operador de comparação foi aplicado filtro para seleção dos registros de pessoas com idade maior ou igual ao parâmetro de maioridade, que no nosso caso é 18.
2. Uma alternativa mais "purista" e clássica de SQL
SELECT
Nome,
DataNascimento AS "Data de nascimento",
CPF
FROM
TabelaClientes
WHERE
(SYSDATE - DataNascimento)/365.25 >= 18;
Aqui, na cláusula WHERE foi feita uma simples conta de subtração matemática entre a data atual do sistema (SYSDATE) e a data de nascimento registrada no BD.
O resultado, no Oracle, é fornecido em dias, por isso necessária a divisão por 365, para transformar o valor em anos.
O .25 que aparece seguindo 365 é uma forma de compensar (não solucionar, como faz MONTHS_BETWEEN) o impacto, no cálculo, dos anos bissextos entre as datas, que serão mais perceptíveis a longo prazo.