Estas são cláusulas SQL ANSI, um padrão da linguagem SQL seguido pela maior parte dos SGBDs (sistema de gerenciamento de banco de dados). Essa especificação é relativa a uma padronização de nome de cláusulas. Isso significa que o mesmo nome pode ser usado tanto no SQL Server, quanto no PostgreSQL, MySQL e assim por diante. Algumas cláusulas que seguem o mesmo padrão, são o INSERT, UPDATE e DELETE, por exemplo.
Para entender como elas funcionam, veremos como elas funcionam na prática. Para isso, os scripts abaixo precisam ser executados para que os dois exemplos a seguir possam trazer os mesmos resultados mostrados neste artigo. Os scripts foram implementados para o SQL SERVER.
Após executar os scripts, vamos aos exemplos:
Primeiro exemplo
Vamos relacionar do banco, os alunos que fazem apenas o curso de SQL SERVER 2012.
SELECT P.nu_matricula, P.no_pessoa, C.nu_curso, C.no_curso FROM tb_pessoa P, tb_aula A, tb_conteudo_programatico CP, tb_curso C WHERE A.co_pessoa = P.co_seq_pessoa AND A.co_conteudoprogramatico = CP.co_seq_conteudoprogramatico AND CP.co_curso = C.co_seq_curso AND NOT EXISTS (SELECT NULL FROM tb_curso C2, tb_conteudo_programatico CP2, tb_aula A2 WHERE C2.nu_curso = 'JV01' AND CP2.co_curso = C2.co_seq_curso AND A2.co_conteudoprogramatico = CP2.co_seq_conteudoprogramatico AND A2.co_pessoa = A.co_pessoa) GROUP BY P.nu_matricula, P.no_pessoa, C.nu_curso, C.no_curso ORDER BY C.no_curso, P.no_pessoa;
Com esta query, teremos o seguinte resultado:
Veja que aqui temos 6 alunos do curso de SQL SERVER 2012. Ao total, na nossa base são 9 alunos (faça um select em TB_AULA para conferir). No exemplo queremos que apenas os alunos que fazem SQL SERVER sejam mostrados.
A abordagem realizada para permitir isso foi a utilização da cláusula NOT EXISTS e a igualdade com CO_PESSOA. Ambos estão abreviados para destacarmos este artifício. O contrário de NOT EXISTS é a cláusula EXISTS. Veremos um exemplo de como ela funciona logo mais.
Para entendermos melhor o que o NOT EXISTS faz (e a mesma analogia servirá para EXISTS), vamos executar apenas o SELECT que está entre os parênteses. Faremos apenas pequenas adaptações, como substituir o NULL do select por A2.* e C2.* e retirar a última linha de igual com CO_PESSOA, uma vez que esta linha se trata de um JOIN com uma tabela que não está dentro do parênteses. Com A2.* e C2.*, veremos o que nos interessa que são as informações referentes aos alunos e do curso apenas:
SELECT * FROM tb_curso C2, tb_conteudo_programatico CP2, tb_aula A2 WHERE C2.nu_curso = 'JV01' AND CP2.co_curso = C2.co_seq_curso AND A2.co_conteudoprogramatico = p2.co_seq_conteudoprogramatico;
Repare no resultado:
Com isso, fica mais fácil entender que os alunos 9, 6 e 5 serão excluídos do resultado, mas para isso, não podemos esquecer do NOT EXISTS e da coluna CO_PESSOA. Apenas para conferir os nomes dos alunos e seu respectivo CO_SEQ_PESSOA:
SELECT * FROM tb_pessoa WHERE co_seq_pessoa IN ( 9, 6, 5 );
Resultado:
Dado este aprendizado, vamos partir para o segundo exemplo.
Segundo exemplo
Agora vamos mostrar o total dos alunos, apenas do curso de JAVA usando a cláusula EXISTS.
SELECT C.nu_curso, C.no_curso, Count(DISTINCT A.co_pessoa) total_alunos FROM tb_pessoa P, tb_aula A, tb_conteudo_programatico CP, tb_curso C WHERE A.co_pessoa = P.co_seq_pessoa AND A.co_conteudoprogramatico = P.co_seq_conteudoprogramatico AND CP.co_curso = C.co_seq_curso AND EXISTS (SELECT NULL FROM tb_curso C2, tb_conteudo_programatico CP2, tb_aula A2 WHERE C2.nu_curso = 'JV01' AND CP2.co_curso = C2.co_seq_curso AND A2.co_conteudoprogramatico = p2.co_seq_conteudoprogramatico AND A2.co_pessoa = A.co_pessoa AND C2.co_seq_curso = C.co_seq_curso) GROUP BY C.nu_curso, C.no_curso ORDER BY C.no_curso;
Veja o resultado:
Conforme mencionado, estes scripts SQL podem ser usados tranquilamente em outros SGBDs, por se tratar de SQL ANSI. Evidentemente que, para mostrar estes mesmos resultados, você terá que ter tabelas e dados iguais.
Bons estudos.