Olá Alfredo, vamos pegar a diferença entre as duas alternativas que você ficou em dúvida. E para facilitar os teste vou trocar a coluna da tabela por uma string fixa. Vamos para a que o exercício marca como correta primeiro:
select concat(substr('alura',1,length('alura')-2),'XX') from dual;
A nossa query vai ser resolvida a partir dos parenteses mais internos então primeiro ela irá pegar o comprimento da palavra alura e diminuir 2 o que resulta em 3
select concat(substr('alura',1,3),'XX') from dual;
Agora a query vai pegar da palavra 'alura' apenas do primeiro até o terceiro carácter o que resulta em:
select concat('alu,'XX') from dual;
Por fim no final da palavra vai concatenar 'XX' o que gera como resultado final:
aluXX
Repare que nessa abordagem pouco importa o conteúdo da string ele sempre vai remover os 2 últimos caracteres e concatenar XX
Agora vamos analisar a query que você apresentou:
select replace('alura', substr('alura', length('alura') -1), 'XX') from dual;
Primeiramente ela vai pegar o comprimento da palavra alura e subtrair 1 o que resulta em 4
select replace('alura', substr('alura', 4), 'XX') from dual;
Agora a query vai pegar a partir da 4 posição do texto todos os caracteres o que resulta em 'ra'
select replace('alura', 'ra', 'XX') from dual;
Finalmente ele irá substituir da palavra 'alura' todas as ocorrências da sequência de caracteres 'ra' o que resulta em:
'aluXX'
O que nesse caso gera o mesmo resultado, o pulo do gato é quando as últimas duas letras da palavra repete no meio da palavra vamos roda a mesma query agora para a palavra: assassinas
Query escolhida:
select replace('assassinas', substr('assassinas', length('assassinas') -1), 'XX') from dual;
Vai gerar como saída:
XXsXXinXX
A query marcada como correta:
select concat(substr('assassinas',1,length('assassinas')-2),'XX') from dual;
Vai gerar como saída:
assassinXX
Portanto a única query que resolve para qualquer caso é a query marcada como correta no exercício.
Espero que tenha ficado mais claro.
Abraços e bons estudos.