![]() |
MC 536 - Álgebra Relacional x SQL : conexão prática |
![]() |
SQL foi fortemente influenciada pelos trabalhos de Codd sobre Álgebra Relacional (AR)
e Cálculo Relacional de Tuplas (CRT). Embora elas sejam
equivalentes no que diz respeito ao poder de expressar consultas, SQL é
mais poderosa devido principalmente aos seus recursos de contagem, ordenação (cláusula order by )
e agrupamento (cláusula group by ). A AR e o CRT
podem ambas serem vistas como formas compactas de expressar consultas em SQL.
O domínio de uma delas pode ser de grande ajuda no raciocínio lógico por trás das soluções
de consultas complexas.
É o que faremos através de alguns exemplos da AR vistos em aula.
É importante ressaltar, no entanto, uma diferença conceitual importante entre
a AR e SQL: SQL não trata tabelas como conjuntos matemáticos, permitindo a
ocorrência de linhas duplicadas. Uma forma de evitar isto é sempre especificar
a chave primária ao criar uma tabela. Infelizmente isto não é suficiente, pois tabelas
intermediárias produzidas ao se executar um comando SQL podem conter linhas
duplicadas se certos cuidados não forem tomados: o exemplo mais simples desse efeito é
a operação de projeção (Π) que elimina duplicatas na AR mas a sua tradução natural para SQL
não o faz, sendo necessário colocar o qualificado distinct na cláusula select,
como veremos nos exemplos. A seguir, como operações da AR são traduzidas para SQL:
Exemplo: "Para cada funcionário apresente o seu número e os nomes dos seus dependentes"
AR: Π numf, nomed Dependentes
SQL: select numf,nomed from Dependntes
Obs: não há repetição porque por convenção, o par numf, nomed é Chave Primária de Dependentes
"Dê uma lista dos funcionários que possuem dependentes"
Π numf Dependentes
select numf from Dependentes
problema: o funcionário 02 aparecerá duas vezes! É preciso incluir:
select distinct numf from Dependentes
Π numf, nomed, par σ(par='filha')Dependentes
select numf, nomed, par
from Dependentes
where par= 'filha'
Πp(D) ∩ Πf(D) select p from D intersect select f from D ou select distinct p from D where p in (select f from D)"Dê uma lista das pessoas que não têm filhos".
Πf(D) - Πp(D)
select f from D
except
select p from D
ou,
select distinct f from D
where f not in
(select p frm D)
Exemplos:
select ...
from Funcionarios, Dependentes
ou,
select ....
from D as D1, D as D2, D as D3 as é opcional
Observe também nesse exemplo os operadores de renomeação (alias na terminologia do SQL): as D1, as D2, etc.
Usualmente o produto cartesiano será utilizado junto com uma seleção, conforme veremos.
Lembrando que a junção θ e a junção natural (mais precisamente junção de igualdade) são um subconjunto do produto cartesiano, obtido através de uma operação de seleção envolvendo comparação entre colunas, elas podem ser expressas através de uma expressão de comparação na cláusula where envolvendo as colunas escolhidas. Exemplos:
junção natural: "para cada funcionário que possui dependentes apresente o seu nome, os nomes e parentesco dos dependentes":
Πnomef, nomed, par Funcionarios |X| Dependentes
ou,
Πnomef, nomed, par σ(Funcionários.numf=Dependentes.numf)(Funcionarios x Dependentes)
select nomef, nomed, par
from Funcionarios, Dependentes
where Funcionarios.numf = Dependentes.numf
Outro exemplo: tabela de "pais e filhos", D(p,f):
ΠD1.p,D2.f σ(D1.f=D2.p)(D1 x D2) (Obs: aqui há uma renomeação implícita - qual é ela?)
SQL:
select D1.p, D2.f
from D as D1, D as D2
where D1.f= D2.p
Exemplo de junção theta: "obtenha pares de pessoas sem repetição da tabela "Pais e Filhos",
D( p, f), que são ou foram cônjuges, isto é, possuem um ou mais filhos em comum"
ρD1(p1,f1) D, ρD2(p2,f2) D
Πp1,p2 (σ(p1 < p2 and f1=f2 (D1 x D2))
select distinct D1.p, D2.p
from D as D1, D as D2
where D1.f = D2.f and D1.p < D2.p