Buscar

Cap10

Prévia do material em texto

Capítulo 10 
Um toque de álgebra relacional: 
UNION e outras operações 
Embora o SQL seja basicamente uma linguagem oriunda da lógica de predicados, a operação de 
união é realizada explicitamente pelo operador UNION. Na implementação Oracle, também 
estão disponíveis os operadores de conjuntos INTERSECT e MINUS. Este capítulo aborda as 
construções que dão um toque de álgebra relacional ao SQL. 
10.1 A UNIÃO SE FAZ À FORÇA 
A operação de união permite reunir várias consultas num só resultado. A forma geral do opera-
dor UNION 
select .... 
union 
select ... 
union 
select ... 
determina que as linhas do resultado de cada uma das consultas sejam reunidas no resultado 
final. Um exemplo simples é a consulta que retorna a lista de nomes de professores e alunos, 
em ordem alfabética. 
select nome from aluno 
union 
select nome from professor 
order by 1 
O resultado 
nome 
Barbara Carlito 
Carlos Azambuja 
Carlos Maradona 
Lenira Rocha 
Maria Lucia Silva 
Maria Rita Colatti 
Marina Azambuja 
Olivia Straw 
Oscarito Vianna 
Pedro Amarante 
Ricardo Biondi 
Sacadura Miranda 
Silvia Ferreira 
Zenubio Siqueira 
obtido reúne todos os nomes numa única coluna. Note que a operação de união não pode ser 
emulada através das construções permitidas no SQL vistas até aqui; a única forma de combinar 
2 Capítulo 10: Um toque de álgebra relacional 
 
registros de diferentes tabelas era pelo produto. A combinação “vertical” dos registros é 
exclusividade da operação de união. 
Os operandos da operação de união devem ser compatíveis entre si. Como os dois resultados 
são reunidos num resultado único, é preciso observar que 
• todas as consultas resultem no mesmo número de colunas; 
• cada par de colunas posicionalmente correspondentes tenham tipos compatíveis entre si, de 
modo que se possa obter um tipo comum no resultado. Por exemplo, uma coluna contendo 
números inteiros e outra com números reais podem ser combinadas, resultando num tipo 
comum de número real; porém, uma coluna com números reais não pode ser combinada 
com uma coluna de caracteres; 
• os nomes das colunas do resultado são atribuídos a partir dos nomes das colunas do 
primeiro comando select; 
• a cláusula de ordenação do resultado é inserida no último comando select. 
Vejamos um exemplo que produz uma lista de alunos e professores, indicando o status de cada 
um, como a que é mostrada abaixo. 
registro nome status 
1005 Barbara Carlito Aluno 
3 Carlos Azambuja Professor 
1007 Carlos Maradona Aluno 
17 Lenira Rocha Professor 
1010 Maria Lucia Silva Aluno 
1002 Maria Rita Colatti Aluno 
10 Marina Azambuja Professor 
2 Olivia Straw Professor 
1004 Oscarito Vianna Aluno 
12 Pedro Amarante Professor 
1001 Ricardo Biondi Aluno 
1008 Sacadura Miranda Aluno 
18 Silvia Ferreira Professor 
15 Zenubio Siqueira Professor 
Note que a matrícula dos alunos e o código dos professores foram reunidos numa coluna 
intitulada registro. A consulta 
select matricula as registro, nome, 'Aluno' as status from aluno 
union 
select codprofessor, nome, 'Professor' from professor 
order by 2 
ilustra o estabelecimento dos nomes das colunas do resultado de uma união; prevalecem os 
nomes atribuídos às colunas da primeira consulta. 
∴ 
 
Note que no caso de união, a cláusula order by não pode fazer referência a expressões que 
não estão presentes na lista-alvo do comando select (vide seção 4.11). 
∴ 
Consultas de qualquer tipo podem ser combinadas nas operações de união, desde que sejam 
compatíveis entre si. A união 
select 'Alunos inscritos' as status, count(*) as total 
from aluno a 
where exists ( select * from inscricao i where a.matricula = i.matricula ) 
group by 1 
union 
Error! Style not defined. 3 
 
select 'Professores', count(*) 
from professor 
group by 1 
mostra a contagem de alunos que possuem alguma inscrição e a contagem de professores. 
status total 
Alunos inscritos 5 
Professores 7 
UNION E UNION ALL 
O operador union pode ser expresso com duas variações: UNION e UNION ALL. No primeiro caso, 
os registros repetidos são eliminados e a operação trata o resultado como um conjunto, isto é, 
sem repetições; no segundo caso, todos os registros presentes nas consultas sendo reunidas, 
repetidos ou não, são incluídos no resultado. As tabelas TX e TY, mostradas a seguir com as 
respectivas instâncias, ajudam a clarificar essas variações. 
Com o operador union simples, o resultado não contém linhas repetidas. 
 
Com o operador union all, o resultado contém todos os registros presentes em seus operandos, 
repetidos ou não. 
10.2 OS OPERADORES MINUS E INTERSECT 
O Oracle disponibiliza ainda dois operadores extras que implementam operações sobre 
conjuntos de registros. Os operadores MINUS e INTERSECT produzem, respectivamente, a 
diferença (−) e a interseção (∩) de seus operandos. 
TX 
a b 
2 3 
5 8 
9 12 
TY 
b c 
3 2 
5 8 
9 12 
a b 
2 3 
3 2 
5 8 
9 12 
select * from tx 
union 
select * from ty 
a b 
2 3 
5 8 
9 12 
3 2 
5 8 
9 12 
select * from tx 
union all 
select * from ty 
4 Capítulo 10: Um toque de álgebra relacional 
 
Nos dois operadores valem as regras apresentadas para a união: 
• mesmo número de colunas nos operandos; 
• colunas posicionalmente correspondentes com tipos compatíveis. 
Para exemplificar, vamos retornar à consulta que produz a lista de alunos que não têm 
reprovações, apresentada no capítulo 9. Com o operador MINUS, esta consulta pode ser expressa 
como 
select a.matricula, a.nome 
from aluno a 
minus 
select a.matricula, a.nome 
from aluno a 
where exists ( select * from inscricao i where a.matricula = i.matricula and i.nota < 5 ) 
order by a.nome 
obtendo-se como resultado 
matricula nome 
1007 Carlos Maradona 
1010 Maria Lucia Silva 
1002 Maria Rita Colatti 
1004 Oscarito Vianna 
1001 Ricardo Biondi 
1008 Sacadura Miranda 
 
∴ 
Para ilustrar o operador de interseção, vamos utilizar novamente as tabelas TX e TY. 
A interseção de duas tabelas resulta nos registros que existem em ambas. 
∴ 
 
Quando da utilização dos operadores acima descritos, é importante observar que: 
• no resultado final, valem os nomes das colunas estabelecidos pela primeira consulta; 
• a ordem final do resultado é estabelecida pela cláusula order by da última consulta; 
R ∩ S 
SR 
R - S 
TX 
a b 
2 3 
5 8 
9 12 
TY 
b c 
3 2 
5 8 
9 12 
a b 
5 8 
9 12 
select * from tx 
intersect 
select * from ty 
Error! Style not defined. 5 
 
• os operadores UNION, INTERSECT e MINUS têm a mesma precedência. Se houver uma 
sequência de consultas operadas por esses operadores, os mesmos são aplicados na ordem 
em que aparecem, exceto se esta precedência for afetada pelo uso de parênteses. 
As regras listadas permitem um curioso exemplo de aplicação desses operadores. A interseção 
de dois conjuntos R e S obedece à seguinte equivalência: 
R ∩ S ≡ R − ( R − S ) 
Isto é, a interseção de R e S é igual a R menos a diferença de R e S. Isto significa que a consulta 
acima pode ser rescrita como 
EXERCÍCIOS 
10.1 Considere duas tabelas R e S, conforme o esquema relacional abaixo. 
R (A, B, C) 
S (A, D, E) 
Escreva consultas SQL que produzam resultados equivalentes a cada uma das seguintes 
expressões algébricas: 
R × S (produto) 
R − S (diferença) 
R ∪ S (união) 
R ∩ S (interseção) 
10.2 Na base de dados de exemplos não há alunos inscritos em mais de duas disciplinas: um 
aluno pode estar inscrito em zero, uma ou duas disciplinas. Escreva uma consulta SQL que 
produza os nomes dos alunos seguidos das disciplinas nas quais estão inscritos, como a seguir. 
Note que não há repetições no resultado e que quando há duas disciplinas para o mesmo aluno, 
essas aparecem em ordem alfabética. 
 
matricula nome disciplina1 disciplina2 
1005 Barbara Carlito Estatística Sociologia 
1007 Carlos Maradona Dir. Constitucional Direito Civil 
1010 Maria Lucia Silva Sociologia Português 
1002 Maria Rita Colatti Compiladores 
1004 Oscarito Vianna 
1001Ricardo Biondi Dir. Constitucional Português 
1008 Sacadura Miranda 
10.3 Escreva uma consulta que conte os registros de cada tabela da base de exemplos e 
produza um resultado da forma 
tabela registros 
aluno 7 
curso 3 
disciplina 7 
inscricao 9 
professor 7 
 
a b 
5 8 
9 12 
select * from tx 
minus 
( select * from tx 
 minus 
 select * from ty )

Continue navegando