Capítulo 2
CONSULTAS A DADOS ARMAZENADOS NO
BANCO DE DADOS USANDO ÁLGEBRA
E CODIFICANDO EM SQL
Laboratório de Banco de Dados Cliente/Servidor 2 -1
2.1 - Construção da Lógica de acesso aos dados do Banco de Dados usando
Álgebra Relacional
Na construção da lógica de acesso aos dados do Banco de Dados, são
utilizados os seguintes operadores da álgebra relacional:
Operadores da álgebra: PC (produto cartesiano) , Seleção, Minus, Union
e Projeção.
Operadores Lógicos: Join, (inner e outer) e Divide.
As operações algébricas descritas acima, resolvem a maioria dos problemas
de obtenção de dados do banco de dados relacional e são usadas isoladamente ou
em conjunto, conforme exemplos a seguir:
a) PC (Produto cartesiano)
É a operação de multiplicação de conjuntos
Representação: R = X * Y
(tabela R conterá o resultado da operação de
multiplicação da tabela X com a tabela Y)
Exemplo: X=( x1, x2, x4)
Y=(y1 , y2 , y3)
R=(x1y1, x1y2, x1y3, x2y1, x2y2, x2y3, x4y1, x4y2, x4y3 )
b) Minus (diferença entre os conjuntos)
Representação:
R = nome da tabela 1 (nome atrib) - nome da tabela 2 (nome atrib)
Exemplo: Considere as tabelas:
DEPTO(DN DNOME CHEFE) EMPREGADO(MATRIC NOME CODDEPTO)
D1 Financ 02 01 ZE D2
D2 Contab 04 02 MARIA D1
03 ZEFA D2
04 JOAO D1
Laboratório de Banco de Dados Cliente/Servidor 2 -2
O usuário deseja saber quais os empregados que não são chefes.
R = Empregado (matric) - Depto (chefe)
O minus tem como resultado as linhas da tabela Empregado que não estão
contidas (atributo definido para o minus) na tabela DEPARTAMENTO.
R (MATRIC NOME CODDEPTO)
01 ZE D2
03 ZEFA D1
c) Seleção
Seleciona as linhas de uma tabela de acordo as condições estabelecidas.
Representação: R = nome da tabela (condição )
Nas especificações das condições valem todos os operadores tradicionais
( > < = not and or ……………..)
Exemplo:
Considere a tabela: EMPREGADO (MATRIC NOME SALARIO)
10 ZE 1000
30 JOAO 2000
34 MARIA 800
40 ZEFA 1200
O usuário deseja saber quais os empregados com salário maior que 1000.
R = EMPREGADO ( SALARIO > 1000)
R (MATRIC NOME SALARIO)
30 JOAO 2000
40 ZEFA 1200
Laboratório de Banco de Dados Cliente/Servidor 2 -3
d) Projeção
A projeção tem como resultado os atributos de uma tabela (definidos para
a projeção) sem redundância.
Elimina a redundância no resultado.
Representação: R = nome da tabela( nome dos atributos).
Exemplo: VENDA (PN CN QUANT)
P1 C1 20
P2 C1 10
P1 C4 5
P1 C2 6
O usuário quer saber quais os códigos dos produtos que já tiveram pelo
menos uma venda realizada.
R = VENDA (PN)
R (PN)
P1
P2
e) UNION
Apresenta como resultado da operação, uma tabela contendo os
resultados de N operações algébricas distintas aplicadas em tabelas.
Representação:
R = nome tabela (nome dos atributos) U nome tabela (nome dos atributos) U...
Laboratório de Banco de Dados Cliente/Servidor 2 -4
f) JOIN (INNER)
É uma operação de juntar 2 ou mais tabelas com base em um atributo
comum entre elas.
Para essa operação usamos o operador PC e o operador Seleção.
O JOIN não é um operador explícito, não existe na álgebra é apenas lógico.
O Join tem como resposta as linhas das tabelas que possuem um atributo
comum entre elas, e apresenta todos os atributos das tabelas envolvidas.
Representação: PC + Seleção
Exemplo: Departamentos com seus empregados.
DEPTO ( DN, DNOME ) EMPREGADO ( MATRIC, NOME, CODDEPTO )
D1 CPD 01 ZE D2
D2 Contab 02 JOAO D1
D3 Financ 03 MARIA D1
04 ZEFA -
Resposta: R = (Depto * Empregado) D.DN = E.CODDEPTO
D E
R ( DN, DNOME, MATRIC, NOME, CODDEPTO )
D1 CPD 02 JOAO D1
D1 CPD 03 MARIA D1
D2 Contab 01 ZE D2
Laboratório de Banco de Dados Cliente/Servidor 2 -5
g) JOIN (OUTER FULL, OUTER LEFT , OUTER RIGHT)
É uma operação de juntar 2 ou mais tabelas com base em um atributo
comum entre elas, porém diferentemente do Join as linhas da tabela que não
possuem correspondentes na outra tabela também aparecem na resposta e os
atributos inexistentes estarão com nulos.
Exemplo usando outer join left:
Departamento e seus empregados, com os Departamentos sem empregados
também.
Resposta: R = (Departamento * Empregado) D.DN = E.CODDEPTO (+)
D E
R ( DN DNOME MATRIC NOME CODDEPTO)
D1 CPD 02 JOAO D1
D1 CPD 03 MARIA D1
D2 Contab 01 ZE D2
D3 Financ - - -
Exemplo usando outer join right:
Departamento e seus empregados, com os empregados sem departamento
também.
Resposta: R = (Departamento * Empregado) D.DN (+) = E.CODDEPTO
D E
R (DN, DNOME, MATRIC, NOME, CODDEPTO)
D1 CPD 02 JOAO D1
D1 CPD 03 MARIA D1
D2 Contab 01 ZE D2
- - 04 ZEFA -
Laboratório de Banco de Dados Cliente/Servidor 2 -6
Exemplo usando outer join full:
Departamento e seus empregados, com os empregados sem departamento
e departamento sem empregados.
Resposta: R=(Departamento * Empregado) D.DN(+) = E.CODDEPTO(+)
D E
R ( DN DNOME MATRIC NOME CODDEPTO)
D1 CPD 02 JOAO D1
D1 CPD 03 MARIA D1
D2 Contab 01 ZE D2
D3 Financ - - -
- - 04 ZEFA -
h) DIVIDE
Para a Divisão em Álgebra Relacional devemos manter o seguinte
raciocínio:
Conjunto A dividido por B , significa Quais os elementos de A que contem
todos Y de B, teremos então a expressão:
A(x) - ((A(x) * B(y)) – B(x,y)).
A X B X Y
X1 X1 Y1
X2 X1 Y2
X3 X2 Y1
X3 Y2
1. O PC na expressão significa a combinação de todos os elementos de A
com todos de B (visualizando as colunas x de A e y de B).
Resultado de A * B (sem as linhas repetidas):
X1 Y1
X1 Y2
X2 Y1
X2 Y2
X3 Y1
X3 Y2
Laboratório de Banco de Dados Cliente/Servidor 2 -7
2. O minus na expressão mais interna significa: retirar do resultado do PC
o conjunto B, então teremos como resultado as combinações de A(x) e
B(y) que não estão contempladas no conjunto B, isto é, os elementos de
A que não contém todos de B.
Resultado de A(x) * B(y) – B(x,y) :
X2 Y2
X3 Y1
Logo, os elementos de A que não contém todos de B são:
X2
X3
3. O minus mais externo retira do conjunto A os elementos que não contem
todos os elementos de B.
A(x) – (A(x) * B(y) – B(x,y))
Resultado:
X1
Laboratório de Banco de Dados Cliente/Servidor 2 -8
Exercícios:
Considere as seguintes tabelas do Banco de dados em referencia:
Problema 1: Nomes dos Empregados com salario > 1000
Resposta: R= Projeção (Empregado (salario > 1000)) nome
Problema 2: Empregados que não estão trabalhando
Resposta: R= Projeção(Empregado (matric) - Participacao(matric)) nome
Problema 3: Uso de JOIN
Nome dos Empregados que trabalham em algum projeto.
Resposta: R= ((Empregado * Participacao) E.matric = P.matric) nome
E P
Problema 4: Uso do Outer Join
Nome dos empregados e o códigos dos projetos que ele trabalha,
e para aqueles que não estão alocados em algum projeto deverão
aparecer com nulos.
Resposta:
R =( (Empregado * Participacao ) E.matric = P.matric (+)) nome
E P
ou
R= ((Empregado * Participacao) E.matric = P.matric (left outer join)) nome
E P
Problema 5: Código dos projetos que possuem empregados alocados a ele
Resposta: R= Participacao (PN)
Problema 6: Empregado e o projeto que ele não trabalha
Resposta: R= Empregado * Projeto - Participacao
(matric) (pn) (matric,pn)
Problema 7: Matricula dos empregados que trabalham em todos os Projetos
R= Participacao - (Participacao * Projeto - Participacao )
(matric) (matric) (PN) (matric,PN)
Laboratório de Banco de Dados Cliente/Servidor 2 -9
Exercícios propostos:
Considere as seguintes tabelas :
CLIENTE (CN, CNOME)
PRODUTO (PN, PNOME)
VENDA (COD_CLI, COD_PRO, QUANTIDADE)
1. Nome dos Clientes que não compraram nada.
2. Nome dos produtos e a lista de clientes que ainda não o compraram.
3. Uma lista de nome dos clientes com os nomes dos produtos que cada um
já comprou.
4. Nome dos clientes que compraram ‘COLCHOES’.
5. Código dos clientes que compraram o produto de código 1 ou o produto
de código 2.
6. Código dos clientes que compraram o produto de código 1 e o produto
de código 2.
7. Nome dos clientes e dos produtos que ele comprou, na resposta deverão
aparecer também os clientes que não compraram nada.
Laboratório de Banco de Dados Cliente/Servidor 2 -10
2.2- Consultas ao Banco de Dados utilizando SQL
a) SELEÇÃO
Questão: Empregados com salário maior que 3000.
Solução: Selecionar as linhas da tabela EMPREGADO que atendem a
condição acima.
Álgebra: SELEÇÃO
Em SQL: SELECT *
FROM EMPREGADO
WHERE SALARIO > 3000;
b) JUNÇÃO INNER (PC + Seleção)
Questão: Empregados e os projetos que cada um trabalha.
Solução: Juntar as tabelas EMPREGADO e PARTICIPAÇÃO,
resultado acima juntar com a tabela de projetos, do resultado
projetar o nome do empregado e o nome do projeto.
Álgebra: JOIN PC + SELEÇÃO
Em SQL: SELECT NOME, PNOME
FROM EMPREGADO E, PARTICIPACAO P, PROJETO PJ
WHERE E.MATRIC=P.MATRIC AND P.PN=PJ.PN;
c) JUNÇÃO OUTER ( PC + Seleção )
Questão: Empregados e os projetos que cada um trabalha, considere os
Empregados mesmo que eles não tenham nenhum projeto.
Solução: Juntar as tabelas EMPREGADO e PARTICIPAÇÃO,
resultado acima juntar com a tabela de projetos, do resultado
projetar o nome do empregado e o nome do projeto.
Álgebra: JOIN PC + SELEÇÃO
Em SQL: SELECT NOME, PNOME
FROM EMPREGADO E, PARTICIPACAO P, PROJETO PJ
WHERE E.MATRIC = P.MATRIC (+) AND P.PN = PJ.PN (+);
Laboratório de Banco de Dados Cliente/Servidor 2 -11
d) MINUS
Questão: Empregados sem projetos (estão de bobeira).
Solução: Retirar do cadastro de empregados aqueles empregados presentes
na tabela participação:
Empregados(matric) – Participação(matric)
Em SQL: SELECT NOME
FROM EMPREGADO E
WHERE NOT EXISTS ( SELECT *
FROM PARTICIPACAO P
WHERE E.MATRIC = P.MATRIC);
e) PROJEÇÃO
Questão: Nome e salário dos empregados da empresa.
Solução: Projetar as colunas nome e salário do cadastro de empregados
(tabela).
Em SQL: SELECT DISTINCT NOME, SALARIO
FROM EMPREGADO;
Questão: Matrícula dos empregados que estão alocados em projetos
Solução: Projetar a coluna Matric da tabela participação.
Em SQL: SELECT DISTINCT MATRIC
FROM PARTICIPACAO;
f) UNION
Questão: Nome e matrícula dos empregados chefes de departamento e/ou
projeto.
Solução: Juntar as tabelas EMPREGADO e DEPARTAMENTO, do resultado
acima fazer uma união com o resultado da junção das tabelas EMPREGADO e
PROJETO, do resultado projetar o nome e a matrícula dos empresários.
Em SQL: SELECT E1.NOME, D.CHEFE, ‘Chefe de Departamento’
FROM EMPREGADO E1, DEPARTAMENTO D
WHERE E1.MATRIC = D.CHEFE
UNION
SELECT E2.NOME, P.CHEFEPROJ , ‘Lider de Projeto’
FROM EMPREGADO E2, PROJETO P
WHERE E2.MATRIC = P.CHFPJ;
Laboratório de Banco de Dados Cliente/Servidor 2 -12
g) DIVIDE
Questão: Nome dos empregados que trabalham em todos os projetos.
Solução: O raciocínio algébrico será:
Álgebra: Empregado ( matric ) – ( (Empregado ( matric ) * Projeto (pn) ) -
participacao (matric, pn ) )
Em SQL:
SELECT DISTINCT E.NOME
FROM EMPREGADO E
WHERE NOT EXISTS
( SELECT *
FROM PROJETO PJ
WHERE NOT EXISTS
( SELECT *
FROM PARTICIPACAO P
WHERE E.MATRIC=P.MATRIC AND
PJ.PN=P.PN ) );
Exercício Proposto:
1) Nome dos empregados que trabalham em todos os projetos, mas não
considere os projetos que estejam sem empregados.
2) Idem ao exercício 1, porém na resposta apareça apenas a matrícula do
empregado.
Laboratório de Banco de Dados Cliente/Servidor 2 -13
h) Uso de funções: COUNT, SUM, AVG, MAX, MIN, ...
SELECT [distinct] nome dos atributos
FROM nome das tabelas
[WHERE condições de seleção]
[GROUP BY nome dos atributos que terão processamento
agrupado na execução de funções]
[HAVING condições de seleção no uso da função]
[ORDER BY nome dos atributos para classificação]
Exemplos:
Contando linhas (COUNT)
- Número de empregados com salário maior que 1500.
SELECT COUNT (*)
FROM EMPREGADO
WHERE SALARIO > 1500;
Buscando Máximos e Mínimos (MAX , MIN)
- Apresentar o maior salário da empresa.
SELECT MAX(SALARIO)
FROM EMPREGADO;
- Relação dos empregados com menor salário da empresa
SELECT NOME
FROM EMPREGADO E1
WHERE E1.SALARIO =
(SELECT MIN (E2.SALARIO)
FROM EMPREGADO E2 );
Laboratório de Banco de Dados Cliente/Servidor 2 -14
Calculando Médias (AVG)
- Média salarial de cada departamento da empresa.
SELECT DEPT, AVG(SALARIO)
FROM EMPREGADO
GROUP BY DEPT;
Totalizando Colunas (SUM)
- Total que cada departamento gasta com salários.
SELECT DEPT, SUM(SALARIO)
FROM EMPREGADO
GROUP BY DEPT;
Agrupando Informações Selecionadas (GROUP BY)
A clausula GROUP BY permite organizar a seleção de dados em grupos
determinados. É usada somente na execução de funções.
Exemplo:
- Relacionar para cada departamento o número de empregados da empresa.
SELECT DEPT, COUNT (*)
FROM EMPREGADO
GROUP BY DEPT;
Agrupando de Forma Condicional (HAVING)
Exemplo:
- Código do departamento que gasta mais de R$ 100.000,00 com empregados
cujo salário e maior que R$ 5.000,00.
SELECT DEPT
FROM EMPREGADO
WHERE SALARIO > 5000
GROUP BY DEPT
HAVING SUM (SALARIO) > 100000;
Laboratório de Banco de Dados Cliente/Servidor 2 -15
i) Criação de Funções:
Exemplo 1:
Função para calcular a média salarial de um departamento.
CREATE OR REPLACE FUNCTION calc_media
(departamento in varchar2)
return INT AS
media int :=0;
BEGIN
SELECT avg(salario) INTO media FROM EMPREGADO
WHERE cod_depart = departamento;
RETURN media;
END;
/
Usando a função em um comando sql no WHERE.
SELECT nome
FROM empregado
WHERE salario > calc_media(cod_depart);
Usando a função no SELECT para apresentar o resultado na resposta
ordenando a resposta por departamento e para cada departamento
ordenado por nome
SELECT nome,salario,
cod_depart,'media salarial do departamento ' as OBS ,
calc_media(cod_depart)
FROM empregado
ORDER BY 3, 1;
Laboratório de Banco de Dados Cliente/Servidor 2 -16
Exemplo 2:
Construir uma função que recebe o status de um cliente e retorna para a
aplicação o status seguinte, em uma escala de promoção.
Essa função deve obter o status a ser retornado consultando uma
tabela de STATUS que contém a sequência de status possíveis que um cliente
pode ter.
CREATE OR REPLACE FUNCTION proximo
(status_cli in varchar2) return varchar2 as
stat varchar2(1);
valor number;
CURSOR c1 is
select * from STATUS;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO stat, valor;
EXIT WHEN c1%NOTFOUND;
IF stat = status_cli THEN
FETCH c1 INTO stat, valor;
RETURN stat;
END IF;
END LOOP;
CLOSE c1;
END;
/
Laboratório de Banco de Dados Cliente/Servidor 2 -17
j) SQL Recursivo
Pesquisa os dados de uma tabela tendo como base dados da mesma tabela e o
loop é indefinido.
Select nome-dos-atributos
From nome-da-tabela
Start with ( condição para iniciar a pesquisa )
Connect by nome-atributo = Prior nome-atributo;
Exemplos:
Considere a tabela abaixo que contém o nome do Empregado e o nome do seu
chefe que por sua vez é um empregado que também possui um chefe, portanto
essa tabela armazena os seguintes dados visualizados através da árvore
abaixo:
B C D
C D E F
H I
Tabela Chefes (nome_empregado, nome_chefe )
A -
B A
C A
D A
C B
D B
E C
F C
H F
I F
Laboratório de Banco de Dados Cliente/Servidor 2 -18
Problema: Nome do chefe com o nome de seus empregados
Select nome_chefe, nome_empregado
From chefes
Start with nome_empregado = ‘A’
Connect by nome_chefe = Prior nome_empregado;
Laboratório de Banco de Dados Cliente/Servidor 2 -19
2.3 – Modos de Operação de SQL
• Interativo
SELECT * FROM EMPREGADO
WHERE SALARIO BETWEEN 1000 AND 2000;
• Embutido
Em uma linguagem de programação qualquer
EXEC SQL
DECLARE AREA-TRABALHO CURSOR FOR
SELECT * FROM TRABALHO
WHERE SALARIO > 1000 AND
DEPTO = ‘CPD’
END-EXEC
EXEC SQL
OPEN AREA-TRABALHO
END-EXEC
EXEC SQL
FETCH AREA-TRABALHO INTO :VAR1, :VAR2
END-EXEC
• Dinâmico (Interativo ou Embutido)
01 COMANDO PICX(256).
EXEC SQL
DECLARE SQLOBJ STATEMENT
END-EXEC
MOVE ‘DELETE FROM EMPREGADO
WHERE SALARIO > ?’
TO COMANDO
EXEC SQL
PREPARE SQLOBJ FROM COMANDO
END-EXEC
EXEC SQL
EXECUTE SQLOBJ USING :MARAJA
END-EXEC
Laboratório de Banco de Dados Cliente/Servidor 2 -20
- Recuperação usando o comando SELECT
01 COMANDO PIC X(256).
EXEC SQL
DECLARE SQLOBJ STATEMENT
END-EXEC
EXEC SQL
DECLARE TRABALHO CURSOR FOR :COMANDO
END-EXEC
EXEC SQL
INCLUDE SQLCA
END EXEC
EXEC SQL
INCLUDE SQLDA
END EXEC
MOVE 100 TO SQLSIZE
MOVE ‘SELECT * FROM EMPREGADO
WHERE SALARIO > ? AND DEPTO = “CPD”
TO COMANDO
EXEC SQL
PREPARE SQLOBJ FROM :COMANDO
END-EXEC
EXEC SQL
DESCRIBE SQLOBJ INTO SQLDA
END-EXEC
Laboratório de Banco de Dados Cliente/Servidor 2 -21
* SQLDA CONTÉM:
* . TOTAL DE ROWS A SER RECUPERADO (SQLN)
* . NOME, TIPO DE DADOS E TAMANHO (SQLVAR(1))
EXEC SQL
INCLUDE SQLCA
END EXEC
EXEC SQL
OPEN TRABALHO USING :VALOR
END-EXEC
ENQUANTO SQLCODE = 0 FAÇA
EXEC SQL
FETCH TRABALHO USING DESCRIP TOR SQLDA
END-EXEC
....................
....................
....................
FIM ENQUANTO
EXEC SQL
CLOSE TRABALHO
END-EXEC
Laboratório de Banco de Dados Cliente/Servidor 2 -22
2.4 - Interface com LP’s
Comando CURSOR e comando FETCH.
Exemplo do comando do PL/SQL
Cursor – comando SQL declarativo. É uma área de trabalho no programa que
conterá o resultado do comando SQL especificado.
Fetch – comando SQL que obtém uma linha na área de trabalho declarada como
cursor.
Open – Comando SQL que solicita ao SGBD executar o comando SQL
associado a área de trabalho declarada no comando Cursor.
Close – Comando SQL que libera a área de trabalho declarada no comando
Cursor.
Laboratório de Banco de Dados Cliente/Servidor 2 -23
Exemplo do uso do comando SQL CURSOR utilizando a linguagem PL/SQL do
ORACLE.
Desenvolver uma aplicação para avaliar o perfil dos nossos clientes.
A aplicação deverá obter o perfil do cliente na tabela PERFIL_CLIENTE
com base no total de suas compras e atualizar o atributo PERFIL do
cliente na tabela CLIENTE.
Tabelas:
PERFIL_CLIENTE (COD_PERFIL, T_COMPRAS_FX1, T_COMPRAS_FX2 )
CLIENTE (CODCLI, CNOME, BONUS, STATUS, PERFIL)
VENDA (COD_CLI, COD_PRO, COD_LOCAL, QUANTIDADE , VALOR_TOTAL )
Codificação do programa aplicativo, para executar a tarefa:
DECLARE
cli int;
codperfil char(1);
CURSOR TRABALHO IS
SELECT c.cn , p.cod_perfil
FROM venda v, perfil_cliente p, cliente c
WHERE v.cod_cli = c.cn
and (c.perfil <> p.cod_perfil or c.perfil is null)
and somar(c.cn) >= p.t_compras_fx1
and somar(c.cn) <= p.t_compras_fx2;
BEGIN
OPEN TRABALHO;
LOOP
FETCH TRABALHO INTO cli, codperfil;
EXIT WHEN TRABALHO%NOTFOUND;
UPDATE CLIENTE SET perfil = codperfil
WHERE cn = cli;
END LOOP;
CLOSE TRABALHO;
COMMIT;
END;
/