Divisão Relacional, parte I

por Marcelino em 23/02/2013
Divisão Relacional, parte I


Prezados,

Com esse artigo, inicio uma série de três posts que abordarão os conceitos em torno da divisão relacional, assunto que aparece com uma bastante frequência em questões de concurso, principalmente nas provas da Cesgranrio. Além de descrever conceitos necessários para o domínio do assunto, apresentaremos um teste de mesa, que pode ser útil, inclusive para o entendimento das cláusulas EXISTS e NOT EXISTS.

Inicialmente, abordaremos alguns conceitos importantes para subsidiar o assunto.


Consultas aninhadas (não-correlacionadas)

Formam um bloco select-from-where dentro da cláusula where de outra consulta, chamada de consulta externa (outer query). Na consulta aninhada, a subconsulta mais interna é analisada primeiro e o seu resultado é utilizado na avaliação da consulta externa ou subconsulta menos interna.

Essas consultas geralmente utilizam operadores de comparação, tais como:
IN ou NOT IN, ANY (SOME) ou ALL - combinadas com os operadores >, >=, <. <=, = e <>

Operadores IN e NOT IN
O operador de comparação IN testa um dado valor com os elementos de um conjunto, produzido pela cláusula select, geralmente de uma subconsulta mais interna. O resultado é TRUE se o valor existir no conjunto.
O operador NOT IN realizar o mesmo teste. Contudo, retorna TRUE caso o valor não exista no conjunto.



Consultas aninhadas correlacionadas
Segundo Navathe, consultas aninhadas são consideradas correlacionadas sempre que uma condição na cláusula where de uma consulta interna fizer referência a algum atributo de alguma relação declarada na consulta externa. A avaliação de uma consulta correlacionada é feita avaliando repetidamente a consulta interna para cada tupla-resultado da consulta externa, por isso, também são conhecidas como consulta repetitiva.

Funções EXISTS e NOT EXISTS
São geralmente usadas em consultas correlacionadas para verificar se o resultado da consulta interna é vazio ou não (true ou false).

Na avaliação da consulta acima, para cada tupla de empregado a consulta interna seleciona tuplas de dependentes que a condição E.SSN=D.ESSN seja verdadeira. A função NOT EXISTS retorna true, se o resultado da seleção de dependentes for vazio (zero dependentes), e false, se a seleção retornar pelo menos um dependente. O resultado final da consulta correlacionada conterá apenas os empregados cujo resultado da função NOT EXISTS seja true, ou seja, aqueles empregados que não possuam dependentes.



A Divisão Relacional
Para Silberschatz, a operação de divisão é usada em consultas em que geralmente se emprega a expressão “para todos”. Navathe, por exemplo, inicia o tópico sobre essa operação com a consulta “Recuperar os nomes dos empregados que trabalhem em todos os projetos em que John Smith trabalha”.
Nessa operação, a projeção resultante apresenta todos os elementos da primeira relação que estejam relacionados com todos os elementos da segunda.
Nomeando os elementos da operação temos:
dividendo: relação R
divisor: relação S
quociente: relação resultante (R÷S)

Em SQL, há várias formas de se obter a operação de divisão. Abaixo, apresentamos algumas delas.


1. Duplo NOT EXISTS
Essa forma de longe é a mais cobrada em provas. Utilizando as relações R e S da figura acima construímos a seguinte sentença.

Entendendo a sentença:
Como temos três SELECTs serão produzidas três projeções (results).

Para fins didáticos, classificaremos as três consultas nos elementos de uma operação de divisão:
dividendo: SELECT * FROM R AS R2 WHERE (R1.B=R2.B) AND (R2.A=S.A)
divisor: SELECT * FROM S WHERE NOT EXISTS
quociente: SELECT DISTINCT B FROM R AS R1 WHERE NOT EXISTS

Como se trata de uma consulta correlacionada com dupla correlação entre a consulta mais interna e as duas mais externas, a avalição, para melhor entendimento, é feita de forma semelhante a dois laços FOR aninhados.

A tabela abaixo apresenta o teste de mesa para a sentença que hora analisamos.

Para cada resposta TRUE do NOT EXISTS da consulta externa, um valor da tupla analisada será impresso no result set. Por fim, a cláusula DISTINCT impede a apresentação de valores repetidos, apresentando como resultado o conjunto (result set) {b1,b4}.


No próximo artigo, apresentaremos outras sentenças SQL que emulam a divisão relacional.

Até lá.
Deixe seu comentário:
Ocorreu um erro na requisição, tente executar a operação novamente.