Você está na página 1de 60

Curso Prtico de Programao de SQL

Objetivo
Tornar o profissional, programador, apto a programar SQL para o desenvolvimento de
aplicaes. Inicia com uma introduo aos conceitos bsicos, noes do modelo de BD
relacional. Segue com mdulos sobre as diferentes construes do SQL para criar bancos de
dados e tabelas, incluir, alterar, excluir e consultar os dados. Os mdulos esto organizados
num crescente de dificuldades. Inicia com consultas simples at complexas (operaes sobre
uma tabela, duas tabelas, vrias tabelas, operadores de agrupamentos e funes, diferentes
abordagens para fazer junes, etc.).

Metodologia de Ensino
Curso centrado em aulas prticas utilizando um ambiente desenvolvido para Web, com um
interpretador inteligente de comandos; o processo de avaliao inteligente e semi-
automtico; os mdulos so essencialmente de laboratrio, aps alguns conceitos e exemplos o
aluno convidado a fazer exerccios de fixao tericos e prticos.

CARGA HORRIA: 30 Horas

Habilidades e competncias:
Conhecer a sintaxe e a semntica da linguagem SQL;
Conhecer as diferentes formas de uso de SQL: embutida em programas ou na console
de um cliente; em linhas de comandos ou em scripts;
Conhecer um esquema de Banco de Dados relacional: como um conjunto de tabelas
relacional atravs de chaves primrias e estrangeiras;
Diferenciar as principais operaes da lgebra relacional: projeo, seleo e juno;
saber utiliz-las em consultas;
Saber resolver problemas de armazenamento e consulta de dados em Banco de dados
relacionais atravs da linguagem de consulta SQL:
1. Saber criar um banco;
2. Saber Incluir, Alterar e Excluir dados;
3. Dominar a escrita de consultas em SQL;
4. Usar operaes de seleo, projeo e juno;
5. Usar operaes de agrupamento;


1 Mdulo I - Introduo a Linguagem SQL------------------------------------------------------------- 3
1.1 Histrico ------------------------------------------------------------------------------------------------- 3
1.2 Um banco de dados relacional----------------------------------------------------------------------- 3
1.2.1 Tabela, Linha e coluna. ----------------------------------------------------------------------- 4
1.3 Esquemas de BD: modelagem E-R vs. SQL------------------------------------------------------ 5
1.4 Restries de integridade----------------------------------------------------------------------------- 6
1.5 Usos do SQL: numa console cliente vs. embutida numa aplicao-------------------------- 8
1.6 Tipos de Instrues SQL ----------------------------------------------------------------------------- 10
1.6.1 Instrues DDL -------------------------------------------------------------------------------- 10
1.6.2 Instrues DCL--------------------------------------------------------------------------------- 10
1.6.3 Instrues DML-------------------------------------------------------------------------------- 10
1.7 Elementos da sintaxe SQL --------------------------------------------------------------------------- 11
1.8 Consultas em lgebra relacional -------------------------------------------------------------------- 13
1.8.1 Seleo e Projeo----------------------------------------------------------------------------- 14
1.8.2 Juno e Produto Cartesiano----------------------------------------------------------------- 15
1.8.3 Unio, Interseco e Diferena-------------------------------------------------------------- 15
1.8.4 Diviso------------------------------------------------------------------------------------------- 16
1.9 Questes ------------------------------------------------------------------------------------------------- 17
2 Mdulo II SELECT (bsico) -------------------------------------------------------------------------- 19
2.1 Clusulas FROM e WHERE------------------------------------------------------------------------- 21
2.1.1 Clusula DISTINCT -------------------------------------------------------------------------- 22
2.1.2 Clusula WHERE------------------------------------------------------------------------------ 23
2.2 Clusula ORDER BY--------------------------------------------------------------------------------- 23
2.3 Tipos de operadores ----------------------------------------------------------------------------------- 24
2.3.1 Expresses--------------------------------------------------------------------------------------- 25
2.3.2 Operadores comparao: IN, IS NULL, BETWEEN----------------------------------- 25
2.3.3 Comparaes com LIKE , curingas (string) ---------------------------------------------- 26
2.3.4 Expresses com AND OR NOT e com parnteses-------------------------------------- 27
2.4 Exerccios------------------------------------------------------------------------------------------------ 28
3 Mdulo III Manipulao de Tabelas ----------------------------------------------------------------- 29
3.1 Create Database ---------------------------------------------------------------------------------------- 29
3.2 Create/drop table --------------------------------------------------------------------------------------- 30
3.2.1 Como duplicar uma tabela. ------------------------------------------------------------------ 32
3.3 Insert/update/delete------------------------------------------------------------------------------------ 33
3.4 Create view---------------------------------------------------------------------------------------------- 34
3.5 BD emp, depto, dependente-------------------------------------------------------------------------- 34
3.6 Transaes----------------------------------------------------------------------------------------------- 37
3.7 Create index--------------------------------------------------------------------------------------------- 37
3.8 Restries de FOREIGN KEY no MySQL------------------------------------------------------- 39
4 Mdulo IV GROUP BY-------------------------------------------------------------------------------- 42
4.1 Funes de agrupamento bsicas ------------------------------------------------------------------- 42
4.2 A clusula GROUP BY------------------------------------------------------------------------------- 44
4.3 A clusula HAVING---------------------------------------------------------------------------------- 45
4.3.1 Funes GROUP BY (para MySQL) ------------------------------------------------------ 45
4.3.2 Clusula GROUP_CONCAT---------------------------------------------------------------- 46
4.4 Exerccios------------------------------------------------------------------------------------------------ 47
5 Mdulo V Sub-consultas ------------------------------------------------------------------------------- 48
5.1 Tipos de Join: cross, inner, out, left, right--------------------------------------------------------- 48
5.1.1 Diferentes formas de escrever a mesma coisa-------------------------------------------- 50
5.1.2 Join vs modelo lgico de dados ------------------------------------------------------------- 51
5.2 Subconsultas -------------------------------------------------------------------------------------------- 52
5.2.1 Union--------------------------------------------------------------------------------------------- 52
5.2.2 Select dentro de select ------------------------------------------------------------------------ 52
5.2.3 Tabela derivada -------------------------------------------------------------------------------- 53
5.2.4 Self Join------------------------------------------------------------------------------------------ 53
5.2.5 Funes de agregao e sub-consultas----------------------------------------------------- 54
5.3 Consulta como expresso escalar ------------------------------------------------------------------- 56
5.3.1 Sub-consulta para correlacionar dados ---------------------------------------------------- 57
5.3.2 Usando as clusulas EXISTS e NOT EXISTS. ------------------------------------------ 57
5.3.3 Usando ALL, SOME, ANY ----------------------------------------------------------------- 58
5.4 Exerccios:----------------------------------------------------------------------------------------------- 59



UFPA Universidade Federal do Par
3
1 Mdulo I - Introduo a Linguagem
SQL
1.1 Histrico
O SQL Structured Query Language a linguagem padro de comunicao com
Sistemas Gerenciadores de Banco de Dados relacional (SGBD). Diversos SGBDs
utilizam esse padro de linguagem. Os estudos da linguagem SQL foram iniciados pela
IBM em torno da dcada de 70. O nome utilizado nesta poca era SEQUEL, abreviao
Structured QUEry Language. Desde ento, a IBM uniu-se com diversas empresas do
ramo a fim de desenvolver produtos que utilizassem esta linguagem SQL.
O padro SQL foi definido pela ISO International Standards Organization e
pela ANSI American National Standard Institute. A ANSI publica periodicamente
verses atualizadas do padro SQL: por exemplo, SQL92, SQL98 e SQL2003.
Atualmente os SGBDs esto procurando implementar a ltima verso, SQL2003.
A base deste curso privilegiar a apresentao das construes SQL que seguem
os padres ANSI, com nfase no padro SQL92 que j est implementado na maioria
dos SGBDs. Seguindo-se o padro ANSI o cdigo das aplicaes se torna portvel: isto
, podemos migrar uma aplicao de um SGBD para outro com facilidade. As
construes especficas de um produto devem ser evitadas pois reduzem a portabilidade
das aplicaes; caso estas construes sejam realmente avanos tecnolgicos nas
prximas verses faro parte do padro ANSI.

1.2 Um banco de dados relacional
Um Banco de Dados Relacional um conjunto de tabelas interligadas atravs de
chaves primrias e estrangeiras. O objetivo do BD servir de repositrio
compartilhvel de informaes para diferentes aplicaes. Em cada aplicaes vrios
usurios simultneos podem acessar os dados. O SGBD garante a integridade dos dados
bem como o acesso concorrente aos dados.
Um Banco de Dados Relacional segue o Modelo relacional. Num modelo
relacional temos os conceitos de tabela, linha e coluna. Na cincia da computao uma
tabela associada a outros conceitos:
Sistema de arquivos: vista como um arquivo convencional formado por
uma seqncia de registro de dados; onde cada registro formado por
um conjunto de campos.
lgebra relacional: em estudos formais de lgebra relacional uma tabela
uma relao formada por tuplas; cada tupla formada por um conjunto
de atributos.
Alm disso comum associar tabelas com entidades (com atributos) na
modelagem Entidade Relacionamento; e na modelagem Orientada a objetos, uma tabela
pode ser vista como uma classe (com instancias e com atributos).
No Banco da Fig. 1.1 temos uma tabela Pessoa (cdpessoa, nome, fone) com trs
colunas e cinco linhas. Na primeira linha, lemos, Obilac tem cdpessoa=1 e
fone=260088. Na tabela turma, a turma de Vlei tem cdigo A e o professor a pessoa

UFPA Universidade Federal do Par
4
com cdpessoa=4, que o Lobato. Na tabela participante, vemos que a turma A de Vlei
tem dois participantes: cdpessoa=1 (Obilac) e cdpessoa=3 que o Cabral.
Por outro lado neste BD vemos tambm uma inconsistncia nos dados: O
professor da turma C de Natao o Silva que tambm aluno da mesma turma,
conforme os dados da tabela Participante. Num BD deve-se desenvolver o projeto e as
aplicaes de forma que as inconsistncias nos dados sejam minimizadas.

Pessoa
cdpessoa nome fone
1 Obilac 260088
2 Silva 282677
3 Cabral 260088
4 Lobato 174590
5 Mateus

Turma
cdturma nome profe
A Volei 4
B Karate 4
C Natao 2

Participante
pessoa turma
1 A
3 A
1 B
1 C
2 C

Fig. 1.1 Um exemplo de BD formado por trs tabelas: pessoa, turma e participante.

1.2.1 Tabela, Linha e coluna.
Todos os dados de um BD relacional so armazenados em tabelas. Numa tabela
todas as linhas contm as mesmas colunas; No existe limite no nmero de linhas
(cardinalidade), por exemplo, uma tabela pode possuir um milho de linhas. E tambm,
comum um BD possuir centenas de tabelas.








Na definio de uma tabela, cada linha formada por uma lista ordenada de
colunas (cdpessoa, nome, fone) (1, Obilac, 252677). As linhas no so ordenadas entre
si; existe uma clusula na SQL que permite definir a ordem das linhas para apresentao
em relatrios.
Uma coluna (nome) assume um valor atmico de um dos tipos de dados
(tambm chamados de domnios de dados), por exemplo, numeric, char. Valores das
colunas podem ser vazios (NULL) em certos casos.
As tabelas esto interligadas atravs de relacionamentos. Por exemplo, as trs
tabelas acima esto interligadas: fazendo pessoa(cdpessoa) = participante(pesssoa) a
tabela pessoa esta ligada a tabela Participante; e fazendo turma(cdturma) =
participante(turma) a tabela turma est ligada a tabela participante. Alm disso a tabela
turma tambm est ligada a tabela pessoa: turma(profe) = pessoa(cdpessoa).
Um BD definido por um esquema relacional (que apresentado mais
adiante), que define as tabelas e os relacionamentos entre as tabelas. O esquema do BD
resultado de uma atividade chamada Projeto lgico do BD.
Segue um exemplo de consulta SQL mostrando os valores da tabela pessoa em
ordem alfabtica crescente.



Coluna
(atributo)

cdpesssoa nome fone
1 Obilac 260088
2 Silva 252677
3 Cabral 260088
4 Lobato 174590


Linha
(Tupla)
5 Mateus NULL

UFPA Universidade Federal do Par
5
select * from pessoa order by nome
cdpessoa nome fone
3 Cabral 260088
4 Lobato 174590
5 Mateus
1 Obilac 260088
2 Silva 282677
5 row(s)

1.3 Esquemas de BD: modelagem E-R vs. SQL
A figura 1.2 apresenta um esquema para o BD exemplificado acima. So trs
entidades (Pessoa, Turma e Participante) e trs relacionamentos. Esta notao mostra
visualmente as informaes descritas no script apresentado abaixo em SQL. Note que
neste esquema vemos diagramaticamente os relacionamentos; sobre cada um deles esta
marcada a igualdade, por exemplo, cdpessoa=profe; note tambm que na tabela
participante os dois campos fazem parte da chave primria e, tambm, cada um deles
uma chave estrangeira.


Fig. 1.2 Exemplo de um diagrama Entidade-Relacionamento

Um script de SQL (script 1.1, 1.2) um conjunto de comandos separados por
ponto e vrgula. No script SQL temos a criao da tabela pessoa, com trs colunas
(cdpessoa, nome, fone). cdpessoa (cdigo da pessoa) do tipo integer no nulo, pois a
chave primria. Nome e fone so do tipo caractere de tamanho varivel (varchar).

create table pessoa
(cdpessoa integer not null,
nome varchar(6),
fone varchar(10),
primary key (cdpessoa));

create table turma
(cdturma character(1) not null,
nome varchar(10),
profe integer,
primary key (cdturma));


UFPA Universidade Federal do Par
6
create table participante
(pessoa integer not null,
turma character(1) not null,
primary key (pessoa, turma));

alter table turma add foreign key (profe) references pessoa (cdpessoa);
alter table participante add foreign key (pessoa) references pessoa (cdpessoa);
alter table participante add foreign key (turma) references turma (cdturma);
Script 1.1: Criao de um esquema de BD com trs tabelas e trs relacionamentos

Toda chave primria possui a clusula not null, dizendo que o valor no pode ser
nulo. Outras colunas pode ter esta clusula que verificada automaticamente pelo
gerenciador do BD. No script abaixo (1.2) mostra-se como os dados so inseridos nas
tabelas pessoa, turma e participante. Este um exemplo de um script de carga de um
BD.

/*pessoa*/
insert into pessoa (cdpessoa, nome, fone) values (2, 'Silva', '282677');
insert into pessoa (cdpessoa, nome, fone) values (3, 'Cabral', '260088');
insert into pessoa (cdpessoa, nome, fone) values (4, 'Lobato', '174590');
insert into pessoa (cdpessoa, nome, fone) values (1, 'OBilac', '260088');
/*turma*/
insert into turma (cdturma, nome, profe) values ('A', 'Volei', 4);
insert into turma (cdturma, nome, profe) values ('C', 'Natao', 2);
insert into turma (cdturma, nome, profe) values ('B', 'Karate', 4);
/*participante*/
insert into participante (pessoa, turma) values (1, 'A');
insert into participante (pessoa, turma) values (1, 'B');
insert into participante (pessoa, turma) values (1, 'C');
insert into participante (pessoa, turma) values (2, 'C');
insert into participante (pessoa, turma) values (3, 'A');
Script 1.2: Carga do BD

1.4 Restries de integridade
Na especificao do esquema de um BD so definidas regras de restrio de
chaves, que definem como as tabelas se relacionam. Existem dois tipos de chaves:
Chave primria: (PK - Primary Key) a chave que identifica cada registro. O
valor deve ser nico em cada registro (regra de restrio de chave
primria); em muitos casos uma coluna no suficiente ento a PK
combinao de vrias colunas (por exemplo, no BD acima, a chave primria
da tabela participante composta pelos campos pessoa+turma); neste caso
dizemos que a chave composta.
Chave Estrangeira: (FK - Foreign Key) a chave que forma um
relacionamento com a chave primria de outra tabela. O valor da chave
estrangeira numa tabela deve existir como valor de chave primria em
outra tabela ou deve ser vazio, null (regra de restrio de integridade
referencial). Uma chave estrangeira tambm pode ser composta.
Chave Alternativa: uma das opes (alternativas) de escolha de chave
primria. Por exemplo, numa tabela Pessoa a coluna nome diferente em
todas as linhas, logo ela poderia ser a chave primria. Normalmente escolhe-
se como chave primria a chave candidata de menor de tamanho, mais
estvel e isento de duplicaes. Por exemplo, na escolha entre cdpessoa e

UFPA Universidade Federal do Par
7
nome, o cdpessoa melhor, pois o nome sujeito a duplicaes
(considerando todo o Brasil, existem nomes duplicados); o prprio CPF no
uma chave boa, pois pode ser cancelado e os menores de idade no tem.

As chaves so conceitos fundamentais num BD relacional pois a ligao da
chave primria com a estrangeira que codifica o conceito de relacionamento entre
tabelas. A chave estrangeira aponta para a chave primria de uma tabela: no BD acima,
o campo pessoa da tabela Participante uma chave estrangeira (FK) que aponta para a
chave primria (PK) cdpessoa na tabela pessoa; o campo turma da tabela Participante
tambm chave estrangeira que aponta para o campo cdturma na tabela turma; o campo
profe da tabela turma tambm FK apontando para PK cdpessoa da tabela pessoa. A
chave primria da tabela participante a combinao dos dois campos turma+pessoa;
cada um deles uma chave estrangeira.
As Restries de integridade de chave so verificadas automaticamente pelo
SGBD antes de executar as operaes de incluso, excluso e alterao:
restrio de chave primria:
i. na incluso de um registro o valor da chave primria no pode ser
duplicado; a tentativa de incluir um novo registro com mesma chave erro;
ii. na incluso o valor nunca pode ser null; se for uma chave composta,
nenhum campo da chave primria pode ser null.
iii. na excluso, um registro s pode ser excludo se o seu valor de chave
primria no esta sendo utilizado por nenhuma chave estrangeira (a alterao
do valor de uma chave primria equivale a excluir a linha e incluir
novamente com o novo valor de chave);
restrio de chave estrangeira:
i. na incluso de uma linha, o valor da chave estrangeira deve existir como
valor de uma chave primria ou deve ser null;
ii. na alterao de dados, o valor da chave estrangeira deve existir como valor
de uma chave primria ou deve ser null;
iii. na excluso de valores, quanto a chave estrangeira, no existe regras a
serem verificadas.
Alm das restries de integridade de chave os gerenciados deve verificar mais
dois tipos de restries:
restrio de domnio: toda coluna deve ter um valor compatvel com o seu
domnio(tipo de dados); por exemplo, se for integer, no pode conter um nome com
letras;
restrio de null: toda coluna com a clusula not null deve ter um valor vlido.

As chaves so implementadas atravs de ndices (estruturas de dados de agilizam
o acesso s informaes). Normalmente os ndices so definidos implicitamente pelo
sistema ou pelo administrador do banco de dados (DBA data base administrator). As
consulta de SQL no mencionam explicitamente os ndices; uma consulta quando
executada num banco que possui os ndices apropriados mais gil. ndices podem ser
criados e/ou alterados na atividade de ajuste de performance do BD, que feita pelo
DBA.




UFPA Universidade Federal do Par
8
1.5 Usos do SQL: numa console cliente vs. embutida
numa aplicao
Um Banco de Dados Relacional um conjunto de tabelas interligadas atravs de
chaves primrias e estrangeiras. O objetivo do BD servir de repositrio compartilhvel
de informaes para vrias aplicaes e ou usurios. Tipicamente ele integrado numa
rede de computadores atravs de uma mquina servidor de BD onde instalado.
Normalmente um servidor de BD dedicado somente para a instalao do BD que
acessado por duas principais formas acesso ao BD: via console cliente ou via aplicao
cliente.
O DBA tipicamente faz uso de uma console cliente (ver Fig 1.3) para criar
tabelas, importar dados, fazer manuteno das bases, etc.
Por outro lado, a grande manipulao de dados em BD feita por aplicaes
clientes (Fonte 1.1), onde o SQL usado de forma embutida. Abaixo temos um
exemplo de programa PHP com dois mtodos, um para uma consulta e outro para uma
incluso de dados. Nestes casos, a linguagem SQL est embutida na aplicao PHP
desenvolvida para rodar num navegador Web.
Os SGBDs possuem uma interface que permite a execuo da linguagem SQL,
uma vez com as permisses de administrador, a consulta ao banco se torna uma tarefa
muito simples, independente do gerenciador.

Fig. 1.3 Exemplo uma console Cliente (phpMyAdmin).

Numa aplicao os comandos SQL trazer (ou enviam) os dados para a aplicao
cliente exibi-los via navegador (ou interface). O ideal desenvolvermos as aplicaes
de software utilizando comandos SQL no padro ANSI que combinados com tcnicas
modernas de arquitetura de software (Engenharia de Software) tornam o cdigo da
aplicao portvel e independente de um SGBD de um fornecedor especfico.



UFPA Universidade Federal do Par
9

class CadCursoBD extends CadBD{
...
function inserirCurso($cdInst, $cdTipoCurso, $cdCurso, $nome) {
$sql = " INSERT INTO curso
VALUES('$cdInst', '$cdTipoCurso', '$cdCurso', '$nome')";
return $this->executarIUD($sql); }
function alterarCurso($cdInst, $cdTipoCurso, $cdCurso, $nome) {
$sql = " UPDATE curso SET nome = '$nome'
WHERE cdInst = '$cdInst' AND cdTipoCurso = '$cdTipoCurso'
AND cdCurso = '$cdCurso'";
return $this->executarIUD($sql);}
...
function getCurso($cdInst, $cdTipoCurso, $cdCurso) {
$sql = " SELECT * FROM curso
WHERE cdInst = '$cdInst' AND cdTipoCurso = '$cdTipoCurso'
AND cdCurso = '$cdCurso'";
$rs = $this->con->execute($sql);
return $this->con->fetch_array($rs);}
...}
Fonte1: Exemplo de cdigo PHP com SQL embutida no cdigo hospedeiro

A Fig 1.4 ilustra a conexo dos clientes com o servidor de BD, SGBD. Uma vez
que o cliente se conectou ao banco de dados (mais especificamente o engenho do BD),
as instrues SQL podem ser executadas e os resultados sero retornados. Esta conexo
podes ser feita por diferentes APIs, por exemplo, via ODBC ou conexo nativa na
linguagem. Em algumas API o SQL compilado no cliente em outras no servidos. Em
ambos os casos o plano das consultas executado no servidor. A figura ilustra que
temos o SGBD mais as tabelas num grande disco, mas na verdade existe uma mquina
servidora com boa configurao e um bom nmero de discos (HDs) (para ser RAID
deve ser pelo menos 5, os melhores so SCSI) para suportar as tabelas do banco de
dados, de modo robusto. Um servidor robusto permite a troca de HDs com a mquina
operando; um bom servidor opera por anos a fio sem ser desligado.

SGBD
Clientes
Sistema
Clientes
Clientes

Fig. 1.4 Exemplo como os clientes se conectam ao servidor de BD



UFPA Universidade Federal do Par
10
1.6 Tipos de Instrues SQL
As instrues SQL so subdivididas em trs categorias, como descrito na tabela
abaixo:

DDL
Data Definition Language
Permite criar bancos de dados, tabelas ndices, etc. O
usurio desta camada principalmente o DBA.
DCL
Data Control Language
Permite definir quem ter permisso para exibir ou
modificar os dados; tambm quem utiliza esta camada
DBA.
DML
Data Manipulation Language
Permite consultar e modificar os dados; usurios so
os programadores e/ou aplicaes.
1.6.1 Instrues DDL
As instrues DDL definem o esquema do BD, isto as tabelas, os
relacionamentos e as restries de integridade. Elas tambm so usadas para administrar
o BD, por exemplo, criar uma nova tabela ou remover uma tabela desnecessria. So
trs tipos de instrues: CREATE, ALTER E DROP, respectivamente para criar, alterar
ou remover.
Somente os membros de cargo de administrador podem executar instrues da
camada DDL. Em geral recomenda-se, no utilizar outras contas para criar objetos do
banco de dados. Se os usurios criam seus prprios objetos, cada proprietrio ter que
dar permisses pertinentes de seus objetos. Isso provoca uma sobrecarga administrativa
o que deve ser evitado. Estas restries tambm evitam problemas relacionados
propriedade de objetos, que podem ocorrer quando um proprietrio foi desligado de um
BD.
No script 1, mostramos um exemplo de instrues DDL para criar o esquema de
um BD com trs tabelas.
1.6.2 Instrues DCL
As instrues DCL so usadas para alterar as permisses associadas um usurio
ou cargo do banco de dados. Basicamente so duas instrues: GRANT (cria uma
permisso para um usurio, trabalhar com determinadas tabelas e instrues) e
REVOKE (que revoga a permisso). Segue um exemplo do comando grant: cria o
usurio "aluno1", com a senha "senhateste", que s pode acessar da mquina onde est o
servidor (localhost), e s pode utilizar os comandos select, insert e update.

GRANT SELECT , INSERT, UPDATE
ON TO aluno1@localhost IDENTIFIED BY "senhateste";

1.6.3 Instrues DML
A camada DML a rea que atuam os programadores, que o foco central deste
curso. As instrues de DML operam com os dados contidos nas tabelas do banco de
dados. Ao utilizar instrues DML possvel incluir, alterar, excluir e consultar os
dados; respectivamente INSERT, UPDATE, DELETE e SELECT. A instruo mais
complexa o SELECT. Os outros comandos tambm podem incluir um select.



UFPA Universidade Federal do Par
11
1.7 Elementos da sintaxe SQL
As instrues SQL so construdas com o uso de vrios elementos de sintaxe do
SQL, incluindo: Comentrios, Palavras reservadas, Identificadores e literais, Tipos de
dados, Variveis, Operadores e Expresses.
O comentrio utilizado para documentar ou descrever fragmentos de
programas. Por exemplo, o cabealho de um script pode conter o nome do autor, a data
de criao e da ultima modificao. Os comentrios tambm podem documentar
fragmentos com cdigo de difcil leitura.
Existem 3 tipos de comentrios: i) multi-linha, ii) no fim de uma linha e iii) no
meio de um comando. Eles so exemplificados na figura que segue:

/*
Este um comentrio
de mltiplas linhas
*/
select 1+1; # fim da linha (mysql)
select 1+1; -- fim da linha ANSI
select /* no meio do comando */ 1+1;


Nos comentrios fim de linha um espao em branco deve existir aps -- ou #.

Palavras reservadas: o SQL na verso 2003 possui as seguintes 252 palavras
reservadas (ver abaixo). No necessrio decorar estas palavras, pois medida que
avanamos no curso as principais sero apresentadas.

ADD, ALL, ALLOCATE, ALTER, AND, ANY, ARE, ARRAY, AS, ASENSITIVE, ASYMMETRIC, AT, ATOMIC, AUTHORIZATION
BEGIN, BETWEEN, BIGINT, BINARY, BLOB, BOOLEAN, BOTH, BY,
CALL, CALLED, CASCADED, CASE, CAST, char, charACTER, CHECK, CLOB, CLOSE, COLLATE, COLUMN, COMMIT,
CONDITION, CONNECT, CONSTRAINT, , CONTINUE, CORRESPONDING, CREATE, CROSS, CUBE, CURRENT,
CURRENT_DATE, CURRENT_DEFAULT_TRANSFORM_GROUP, CURRENT_PATH, CURRENT_ROLE, CURRENT_TIME,
CURRENT_TIMESTAMP, CURRENT_TRANSFORM_GROUP_FOR_TYPE, CURRENT_USER, CURSOR, CYCLE,
DATE, DAY, DEALLOCATE, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DEREF, DESCRIBE, DETERMINISTIC,
DISCONNECT, DISTINCT, DO, DOUBLE, DROP, DYNAMIC,
EACH, ELEMENT, ELSE, ELSEIF, END, ESCAPE, EXCEPT, EXEC, EXECUTE, EXISTS, EXIT, EXTERNAL,
FALSE, FETCH, FILTER, FLOAT, FOR, FOREIGN, FREE, FROM, FULL, FUNCTION,
GET, GLOBAL, GRANT, GROUP, GROUPING,
HANDLER, HAVING, HOLD, HOUR,
IDENTITY, IF, IMMEDIATE, IN, INDICATOR, INNER, INOUT, INPUT, INSENSITIVE, INSERT, INT, INTEGER, INTERSECT,
INTERVAL, INTO, IS, ITERATE,
JOIN,
LANGUAGE, LARGE, LATERAL, LEADING, LEAVE, LEFT, LIKE , LOCAL, LOCALTIME, LOCALTIMESTAMP, LOOP,
MATCH, MEMBER, MERGE, METHOD, MINUTE, MODIFIES, MODULE, MONTH, MULTISET, NATIONAL, NATURAL,
NCHAR, NCLOB, NEW, NO, NONE, NOT, NULL, NUMERIC,
OF, OLD, ON, ONLY, OPEN, OR, ORDER, OUT, OUTER, OUTPUT, OVER, OVERLAPS,
PARAMETER, PARTITION, PRECISION, PREPARE, PRIMARY, PROCEDURE,
RANGE, READS, REAL, RECURSIVE, REF, REFERENCES, REFERENCING, RELEASE, REPEAT, RESIGNAL, RESULT,
RETURN, RETURNS, REVOKE, RIGHT, ROLLBACK, ROLLUP, ROW, ROWS,
SAVEPOINT, SCOPE, SCROLL, SEARCH, SECOND, SELECT, SENSITIVE, SESSION_USER, SET, SIGNAL, SIMILAR,
SMALLINT, SOME, SPECIFIC, SPECIFICTYPE, SQL, SQLEXCEPTION, SQLSTATE, SQLWARNING, START, STATIC,
SUBMULTISET, SYMMETRIC, SYSTEM, SYSTEM_USER,
TABLE, TABLESAMPLE, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE, TO, TRAILING, ,
TRANSLATION, TREAT, TRIGGER, TRUE,
UNDO, UNION, UNIQUE, UNKNOWN, UNNEST, UNTIL, UPDATE, USER, USING,
VALUE, VALUES, VARCHAR, VARYING,
WHEN, WHENEVER, WHERE, WHILE, WINDOW, WITH, WITHIN, WITHOUT, YEAR.


UFPA Universidade Federal do Par
12
Identificadores: Existem dois tipos de identificadores: sem delimitadores e com
delimitadores (cdaluno e CD ALUNO). Devemos evitar usar identificadores com
delimitadores mas em alguns casos eles so necessrios.
Identificadores sem delimitadores: O primeiro caractere deve ser uma letra a-z
ou A-Z. Aps o primeiro caractere, os identificadores podem incluir letras nmeros ou
os smbolos @, $, # ou _. Os identificadores que iniciam com um smbolo tm
utilizaes especiais: a) se inicia com o smbolo @, indica um parmetro ou varivel
local; b) se inicia com uma tralha (#) indica um procedimento ou uma tabela
temporria; se inicia com tralha dupla (##) indica um objeto temporrio global.
Identificadores com delimitadores: So delimitados por apstrofos, aspas ou
[]. Os identificadores delimitados podem ser usados nas seguintes situaes: a) em
nomes com espaos; b) quando se utilizam palavras reservadas da linguagem; c) quando
forem utilizadas palavras reservadas como nomes de objetos ou partes de nomes de
objetos.

select * from `aluno disciplina`;
select * from [aluno disciplina];
set @t1=0, @t2=0, @t3=0;

Tipos de Dados: So usados para definir os domnios das colunas. Restringem
os tipos de valores de cada coluna (ou em uma varivel). Os tipos de dados especificam
o tipo de informao que pode ser armazenado em uma coluna, parmetro ou varivel.
Existem trs principais categorias de tipos de dados: tipos numricos, tipos data e hora
e tipos string (caracteres):
Numricos: Estes tipos incluem os dados numricos exatos (NUMERIC,
DECIMAL, INTEGER, e SMALLINT), assim como os tipos de dados
numricos aproximados (FLOAT, REAL, e DOUBLE PRECISION). A palavra-
chave INT um sinnimo para INTEGER, e a palavra-chave DEC um
sinnimo para DECIMAL.
Data e hora: os tipos de data e hora so DATETIME, DATE,
TIMESTAMP, TIME, e YEAR. Cada um desses tipos tem uma faixa de valores
legais, assim com um valor null que usado para especificar um valor ilegal.
String: Os tipos string so char, VARCHAR, BLOB, TEXT, ENUM, e
SET.

Variveis: Em scripts SQL possvel declarar variveis para procedimentos,
cursores (o tipo especial de apontador para linha de tabela) e demais instrues. Segue
um exemplo simples de scripts com variveis na sintaxe do MySQL.

begin
declare @a numeric(15,2);
declare @b varchar(4);
select @a=sum(valor), @b=codvendedor from pedido
where nomevendedor = 'Abel'
group by codvendedor;
update comissao set valor=@a*0.10 where codvendedor=@b;
end

Neste script observa-se que as variveis @a e @b so utilizadas para armazenar
respectivamente o total de vendas e o cdigo do vendedor Abel. Em seguida, atualiza-se
a comisso do vendedor para o total de 10% (@A*0.10).


UFPA Universidade Federal do Par
13
Operadores: O SQL possui diversos tipos de operados: lgicos, aritmticos e
string. A clusula where permite definir restries sobre linhas bem como igualdade
para codificar junes. A clusula where uma expresso do tipo lgico: avaliada
com um resultado verdadeiro ou falso. A tabela a seguir apresenta os operadores que
podem ser utilizados numa clusula where. Na tabela abaixo listamos os operadores
aritmticos lgicos com a precedncia decrescendo de cima para baixo.
Todos os operadores binrios (aritmticos e lgicos) possuem associatividade
mais esquerda. Por exemplo, se temos select 1-1-1 o resultado -1 e no 1. Pois a
expresso parentizada como (1-1)-1 e no 1-(1-1).

Tabela 1.1 precedncia dos operadores, diminuindo de cima para baixo.
Operadores aritmticos & lgicos Operaes
+, - (unrio), identity, negation
*, /, % multiplication, division, resto da
diviso
+, - (binrio) addition, subtraction, concatenao
=, !=, <, >, <=, >=, comparao
IS [NOT] NULL, LIKE , [NOT] BETWEEN, [NOT] IN,
EXISTS, IS OF type
comparao
NOT negao lgica
AND conjuno
OR disjuno

Expresses: Uma expresso uma combinao de smbolos e operadores que
so avaliados como um valor nico. Elas podem ser simples como uma constante,
varivel, coluna ou valor numrico ou podem ser complexas criadas conectando-se
uma ou mais expresses simples com operadores. Utilizando a tabela acima sabemos
como parentizar uma expresso, por exemplo:

Expresso com parnteses
valor + 0.1 * taxa (valor + (0.1 * taxa))
val >= 10 OR val <=10 and sal+10 < 24 (val >= 10) OR ((val <=10) and ((sal+10) < 24))

O tipo de dados do resultado depende dos elementos contidos na expresso. As
converses implcitas de tipo de dados so executadas nos elementos da expresso
durante a avaliao. Por exemplo, select 1.0+3 vs select 1+1.

1.8 Consultas em lgebra relacional
Um banco de dados relacional tem uma fundamentao matemtica em lgebra
Relacional. Esta lgebra define um conjunto de operadores algbricos, que aplicados
sobre operando(s) retornam uma relao. Em contraste com o SQL que uma
linguagem prtica ela uma linguagem formal terica. Muitos sistemas traduzem as
consultas de SQL para planos de execuo em uma linguagem intermediria muito
prxima a da lgebra relacional; nesta notao que so feitas as otimizaes da
consulta para um plano final que ser executado no engenho do BD. Portanto, o

UFPA Universidade Federal do Par
14
entendimento claro de como os operadores de lgebra relacional trabalham facilita o
desenvolvimento de consultas em SQL.
Nesta lgebra temos sete operaes primitivas. Quatro da teoria dos conjuntos
(unio, interseo, diferena e produto cartesiano) e trs prprias da lgebra relacional
(seleo, projeo, juno). Alm dessas existe a operao auxiliar de atribuio e
outras que no so primitivas (por exemplo, diviso); no primitivas podem ser
decompostas nas primitivas. A seguir temos uma tabela com um resumo das operaes
que sero descritas a seguir.

Operao Operador Sintaxe
Seleo (Select)

<condio>(R)
Projeo (Project)

<atributos>(R)
Juno (Join) |x| (R1) |x| <condio> (R2)
Diviso (Divide)

(R1) (R2)
Produto Cartesiano Product) X (R1) X (R2)
Unio (Union)

(R1) (R2)
Interseo (Intersection)

(R1) (R2)
Diferena (Difference) (R1) (R2)
Atribuio := Var := R

1.8.1 Seleo e Projeo
Uma Seleo representada pela letra grega sigma , seleciona as tuplas
(registros) que satisfazem a uma dada condio. Ex:
nome = "Lobato"
(pessoa).
Uma Projeo representada pela letra grega pi , retorna a tabela fornecida com
certas colunas deixadas de fora. Ex:
nome,fone
(pessoa). Chama-se projeo pois como
se as colunas fossem os valores Y projetados no eixo X. As linhas duplicadas so
eliminadas.

/* Seleo */ select * from
pessoa where nome =
'Lobato';
cdpessoa nome fone
4 Lobato 174590
1 row(s)

/* Projeo */ select
nome from pessoa;
nome
Obilac
Silva
Cabral
Lobato
Mateus
5 row(s)


Expresses complexas. Como numa lgebra com valores numricos podemos
combinar os operadores formando expresses complexas. Por exemplo, podemos
combinar as duas operaes acima:
cdpessoa,fone
(
nome = "Lobato"
(pessoa)). Esta expresso
retorna o cdpessoa e fone do Lobato. Para entender como esta expresso executada
podemos utilizar variveis temporrias e um comando de atribuio:
T1 :=
nome = "Lobato"
(pessoa); T2 :=
cdpessoa,fone
(T1). Aqui vemos que primeiro
executada a operao de seleo e depois de projeo.

select cdpessoa, fone from pessoa where nome='Lobato'
cdpessoa fone
4 174590

UFPA Universidade Federal do Par
15
1 row(s)

1.8.2 Juno e Produto Cartesiano
O Produto Cartesiano, operador X, a combinao de tuplas das duas relaes.
Cada tupla da primeira relao combinada com todas as tuplas da segunda relao,
uma a uma. Ex: (pessoa X turma) ter cardinalidade 5x3=15
Uma Juno (Join) equivale a um produto cartesiano com restries. Esta
operao utilizada para combinar tuplas de duas relaes que compartilham um ou
mais atributos comuns a ambas. O resultado conter as colunas das duas relaes que
esto participando da juno. a operao mais importante pois permite recuperar
dados associados a relacionamentos. Ex: (pessoa |X|
cdpessoa=profe
turma). Segue a
sintaxe: (R1 |x| <condio> R2). Uma condio de juno pode ser formada por mais de
uma condio simples, apenas aplicando os operadores relacionais AND ou OR.

/* Produto cartesiano */ select * from pessoa, turma
cdpessoa nome fone cdturma nome profe
1 Obilac 260088 A Volei 4
1 Obilac 260088 B Karate 4
1 Obilac 260088 C Natao 2
2 Silva 282677 A Volei 4
2 Silva 282677 B Karate 4
2 Silva 282677 C Natao 2
3 Cabral 260088 A Volei 4
3 Cabral 260088 B Karate 4
3 Cabral 260088 C Natao 2
4 Lobato 174590 A Volei 4
4 Lobato 174590 B Karate 4
4 Lobato 174590 C Natao 2
5 Mateus A Volei 4
5 Mateus B Karate 4
5 Mateus C Natao 2
15 row(s)

/* juno */ select * from pessoa join turma on cdpessoa = profe
cdpessoa nome fone cdturma nome profe
4 Lobato 174590 A Volei 4
4 Lobato 174590 B Karate 4
2 Silva 282677 C Natao 2
3 row(s)

1.8.3 Unio, Interseco e Diferena
A Unio representada pelo smbolo , cria uma relao juntando as linhas de
duas outras; linhas duplicadas so eliminadas; as duas tabelas devem possuir os mesmos
tipos de dados nas colunas, isto serem compatveis de unio. Ex: (
turma = "A"
(participante)) (
turma = "B"
(participante)).

UFPA Universidade Federal do Par
16
A Interseco representada pelo smbolo , cria uma relao juntando as linhas
comuns de duas tabelas; as duas tabelas devem possuir os mesmos tipos de dados nas
colunas, isto serem compatveis de unio. As operaes de unio ou interseco so:
Comutativas: A B = B A e A B = B A;
Associativas: A (B C) = (A B) C e A (B C) = (A B) C.

A Diferena representada pelo sinal de (-). Equivale a operao de diferena
entre conjuntos. Note que A-B diferente de B-A, logo a operao no comutativa.
Na unio e diferena cada linha considerada como um elemento do conjunto.

select * from participante where turma='A' or turma='B' union select *
from participante where turma='A'
pessoa turma
1 A
3 A
1 B
3 row(s)

select * from participante where turma='A' or turma='B' intersect select
* from participante where turma='A'
pessoa turma
1 A
3 A
2 row(s)

select * from participante where turma='A' or turma='B' minus select *
from participante where turma='A
pessoa turma
1 A
1 row(s)

1.8.4 Diviso
A Diviso um exemplo de operao no primitiva que produz como resultado
a projeo de todos os elementos da primeira relao que se relacionam com todos os
elementos da segunda relao. Como no um operador primitivo o seu resultado pode
ser obtido a partir da combinao dos outros operadores.

Cursou
Estudante Disciplina
Fredi EngenhariaSoftI
Fredi EngenhariaSoftII
Fredi CompiladoresI
Eugenio EngenhariaSoftI
Eugenio CompiladoresI
Sara EngenhariaSoftI
Sara EngenhariaSoftII
DisciplinaEng
Disciplina
EngenhariaSoftI
EngenhariaSoftII
Cursou DisciplinaEng
Estudante
Fredi
Sara


UFPA Universidade Federal do Par
17
1.9 Questes
Questo 1. O que uma chave primria de uma tabela? (10/20 palavras).
Questo 2. O que uma chave estrangeira de uma tabela? (10/20 palavras).
Questo 3. Fale sobre um esquema de um banco de dados? (20/30 palavras).
Questo 4. Porque importante seguir o padro ANSI, na codificao de consultas
SQL? (20/30 palavras).

Questes 5
a. Em Tabela x Relao: Uma coluna equivale a uma tupla. ( F/V)
b. Em Relao x Sistema de Arquivos: Uma tupla equivale a um registro. ( F/V)
c. Em Relao x Orientao a Objetos: Um registro equivale a uma classe. (F/V )

Questes 6
a. A operao de produto cartesiano oriunda da teoria dos conjuntos. (F/V)
b. A operao de juno oriunda da teoria dos conjuntos. (F/V)
c. A operao de projeo oriunda da teoria dos conjuntos. (F/V)
d. A operao de diferena comutativa. (F/V)

Questo 7.
O que um SGBD?
a) Sistema de gesto de bases de dados;
b) Sistema gerenciados de bancos de dados;
c) Servio de gerencia de bases de dados;
d) Software gerente da base de dados.

Questo 8. Num Banco de Dados relacional, examine as afirmaes sobre a restrio de
integridade referencial:
(I) Quando da incluso de registro em uma tabela, os valores das chaves
estrangeiras devem existir como valores na chave primria referenciada;
(II) Quando da alterao de registros em uma tabela, os novos valores para chaves
estrangeiras devem existir como valores nas chaves primrias referenciadas;
(III) Quanto da excluso de registros em uma tabela os valores das chaves primrias
no podem existir em outros registros como valores em chaves estrangeiras;
Assinale a opo correta:
(a) somente a (I) verdadeira;
(b) somente a (II) verdadeira;
(c) somente a (III) verdadeira;
(d) somente a (II) e (III) so verdadeiras;
(e) todas (I), (II) e (III) so verdadeiras;

Questo 9. Num Banco de Dados relacional, examine as afirmaes sobre a restrio de
integridade de chave primria:
(I) Uma chave primria simples no pode ter valores nulos (vazios);
(II) Uma chave primria composta pela concatenao de vrios campos, pode ter
alguns dos campos nulos (vazios), porm no todos;
(III) Uma chave primria pode ter valores duplicados;

UFPA Universidade Federal do Par
18

Assinale a opo correta:
(a) somente a (I) verdadeira;
(b) somente a (II) verdadeira;
(c) somente a (III) verdadeira;
(d) somente a (II) e (III) so verdadeiras;
(e) todas (I), (II) e (III) so verdadeiras;

Questo 10. Sobre operadores aritmticos e lgicos. != diferente e % modulo (resto
da diviso inteira). Em SQL, qual o resultado de avaliao das expresses:
(1-1-1 != 1) e (1 % 2 -1).

a. 0 e 1
b. 1 e 0
c. 1 e 1
d. 0 e 0
e. 1 e 2


UFPA Universidade Federal do Par
19
2 Mdulo II SELECT (bsico)
O SELECT o principal comando do SQL. Ele usado para consulta de dados,
permitindo codificar todas as operaes da lgebra relacional (seleo, projeo, juno,
produto cartesiano, etc.).
Conveno de escrita: Muitas vezes utilizamos as palavras reservadas do SQL
em caixa alta, por exemplo, a clusula SELECT DISTINCT; quando fazemos isso
para destacar as palavras reservadas as quais estamos apresentando. No entanto, na
programao estas palavras do SQL podem ser tanto em caixa alta como em caixa
baixa. Quando programamos melhor usar caixa baixa, pois a digitao mais fcil;
alm disso, tudo em caixa alta fica feio.
Neste mdulo, inicialmente usamos o BD da figura abaixo nos exemplos de
consultas de SQL.

Banco com 3 tabelas: pessoa, turma e participante.
select * from pessoa
cdpessoa nome fone
1 Obilac 260088
2 Silva 282677
3 Cabral 260088
4 Lobato 174590
5 Mateus
5 row(s)

select * from turma
cdturma nome profe
A Volei 4
B Karate 4
C Natao 2
3 row(s)

select * from
participante
pessoa turma
1 A
3 A
1 B
1 C
2 C
5 row(s)


Apresentamos uma sintaxe inicial do comando select, com diversos exemplos e
exerccios para as diferentes configuraes das suas clusulas: select, from where, order
by, etc. Nos mdulos seguintes algumas das clusulas so retomadas para serem
estudados com mais detalhes.

select [distinct] coluna1 [as nome1] {, column [as nome]}
[from from-list]
[where clause]
[order by attr_name1 [asc | desc ] [using op1 ] {, nom-atributo-i...}]
[union {all} select ...]

O select * from pessoa mostra todas as colunas da tabela; para fazer uma
projeo, isto , mostrar s algumas, basta listar os nomes das colunas na ordem
desejada, como segue.

select nome, fone from pessoa
nome fone
Obilac 260088
Silva 282677
Cabral 260088
Lobato 174590
Mateus
5 row(s)

UFPA Universidade Federal do Par
20
Os nomes no select podem aparecer em qualquer ordem. Os dados so listados
na mesma ordem. Por exemplo, a consulta abaixo mostra primeiro o nome e depois o
cdpessoa:

Select nome, cdpessoa from pessoa;
nome cdpessoa
Obilac 1
Silva 2
Cabral 3
Lobato 4
Mateus 5
5 row(s)

Podemos trocar os nomes das colunas a serem exibidas, com COLUNA AS
ALIAS (novo nome). Neste caso a tabela original continua a mesma, muda s a
exibio do resultado. Como segue:

Select nome as Nmpessoa, cdpessoa as Codigo from pessoa;
Nmpessoa Codigo
Obilac 1
Silva 2
Cabral 3
Lobato 4
Mateus 5
5 row(s)

Podemos tambm usar uma string com espaos em branco no cabealho das
colunas, como segue:

Select nome as 'Nome Pessoa', cdpessoa as Codigo from pessoa
Nome Pessoa Codigo
Obilac 1
... ...
5 row(s)

Podemos usar operadores de concatenao de string para formar um relatrio
mais personalizado, como segue:

Select concat(nome, ' tem o cdigo ', cdpessoa) as 'Lista com cdigos'
from pessoa
Lista com cdigos
Obilac tem o cdigo 1
Silva tem o cdigo 2
Cabral tem o cdigo 3
Lobato tem o cdigo 4
Mateus tem o cdigo 5
5 row(s)


UFPA Universidade Federal do Par
21
No padro ANSI a concatenao de string tambm feita pelo operador ||. Toda
consulta com concat pode ser escrita com || e vice-versa.

sql> Select concat('abc',' 123') -> abc 123
sql> Select ('abc' || ' 123') -> abc 123
sql> Select concat('abc', 123) -> abc123
sql> Select concat('abc', 1+2+3) -> abc6

sql> Select concat(nome, ' tem o cdigo ', cdpessoa) as 'Lista com cdigos' from pessoa
sql> Select (nome || ' tem o cdigo '|| cdpessoa) as 'Lista com cdigos' from pessoa


2.1 Clusulas FROM e WHERE
A clusula FROM define quais tabelas so consultadas. No caso mais simples,
quando usamos duas tabelas sem uma condio de ligao estaremos executando um
produto cartesiano da lgebra relacional.

select * from pessoa, turma
cdpessoa nome fone cdturma nome profe
1 Obilac 260088 A Volei 4
1 Obilac 260088 B Karate 4
1 Obilac 260088 C Natao 2
... ... ... ... ... ..
4 Lobato 174590 C Natao 2
5 Mateus A Volei 4
5 Mateus B Karate 4
5 Mateus C Natao 2
15 row(s)

O produto cartesiano no tem muita utilidade. Por outro lado, a operao de
juno, que vista como um produto cartesiano com uma condio de juno, a mais
importante do SQL. Segue um exemplo:

select * from pessoa, turma where cdpessoa=profe
cdpessoa nome fone cdturma nome profe
4 Lobato 174590 A Volei 4
4 Lobato 174590 B Karate 4
2 Silva 282677 C Natao 2
3 row(s)

Neste exemplo, usando as mesmas duas tabelas pessoa e turma, fizemos a
ligao da chave primria da tabela pessoa(cdpessoa) com a chave estrangeira profe da
tabela turma. O resultado so s as trs turmas da tabela turma, mas cada uma com o
seu professor.
No resultado acima tem dois campos nome. O nome da pessoa e o nome da
turma. Quando queremos referenciar uma das duas colunas podemos qualificar a
coluna (TABELA.COLUNA), por exemplo, pessoa.nome ou turma.nome, como no
exemplo:


UFPA Universidade Federal do Par
22

select turma.nome as TURMA, pessoa.nome AS PROF from pessoa, turma
where cdpessoa=profe
TURMA PROF
Volei Lobato
Karate Lobato
Natao Silva
3 row(s)

Outro recurso necessrio o alias de tabela. Os nomes de tabelas podem ser
grandes e em algumas consultas necessrio qualificar vrias colunas, neste caso,
melhor usar alias de tabela, como exemplificado:
select t.nome as TURMA, p.nome AS PROF
from pessoa p, turma t where cdpessoa=profe
TURMA PROF
Volei Lobato
Karate Lobato
Natao Silva
3 row(s)

Aqui ns no utilizamos o conectivo AS. Ele opcional para a maioria dos
SQLs. Por exemplos todas as consultas abaixo geram o mesmo resultado.

select t.nome as TURMA, p.nome AS PROF from pessoa as p, turma as t where cdpessoa=profe
select t.nome TURMA, p.nome PROF from pessoa as p, turma as t where cdpessoa=profe
select t.nome as TURMA, p.nome AS PROF from pessoa p, turma t where cdpessoa=profe
select t.nome TURMA, p.nome PROF from pessoa p, turma t where cdpessoa=profe

Os alias de tabelas podem ser utilizados para os propsitos de: a) simplificar a
escrita do cdigo; b) tirar ambigidade, qualificando as colunas; c) fazer certas
consultas como self-join, a ser visto mais adiante.

2.1.1 Clusula DISTINCT
Na lgebra relacional as linhas duplicadas so eliminadas do resultado de uma
consulta. Ao contrrio no SQL no so. O motivo que s vezes ns queremos saber
quantas vezes um determinado valor acontece, por exemplo, podemos contar em
quantas turmas est o Obilac. Como a seguinte consulta:

select nome from pessoa, participante where cdpessoa=pessoa and
cdpessoa=1
nome
Obilac
Obilac
Obilac
3 row(s)

Como vemos a consulta traz trs vezes Obilac. Logo, ele participa de trs
turmas. Para retornar o valor 3 basta utilizar count(*), como ser visto mais adiante.
Com um comando Select distinct... elimina-se as linhas repetidas (ou duplicadas), como
segue:

UFPA Universidade Federal do Par
23
select distinct nome from pessoa, participante where cdpessoa=pessoa
and cdpessoa=1
nome
Obilac
1 row(s)
2.1.2 Clusula WHERE
A clusula where aceita uma expresso do tipo lgico que avaliada com um
resultado verdadeiro ou falso. A clusula where tem dois principais propsitos: a)
codificar as operao de seleo (de linhas) da lgebra relacional e b) permitir definir as
condies para uma operao de juno. Alm disso, vrios outros operadores de sub-
consulta so utilizados na clusula where, os quais sero vistos mais adiante.
Na consulta abaixo a clusula where apenas utilizada para definir a condio do join.

select t.nome as TURMA, p.nome AS PROF
from pessoa p, turma t
where p.cdpessoa=t.profe

Agora, foi adicionada uma restrio para selecionar s as linhas do professor Lobato.

select t.nome as TURMA, p.nome AS PROF
from pessoa p, turma t
where p.cdpessoa=t.profe and p.nome=Lobato

Note que aqui j estamos utilizando um operador lgico (and) e dois operadores
relacionais (=). O exemplo abaixo usa tambm um operador aritmtico e o parntese,
para selecionar todos os valores de cdpessoa maiores que 1 e menores que 4.

select t.nome as TURMA, p.nome AS PROF from pessoa p, turma t
where p.cdpessoa=t.profe and (p.cdpessoa>1 or p.cdpessoa<3+1)
TURMA PROF
Natao Silva
Volei Lobato
Karate Lobato
3 row(s)
2.2 Clusula ORDER BY
A clusula ORDER BY classifica os registros no conjunto de resultados, em
ordem crescente (ASC) ou decrescente (DESC). Por default, os resultados so
classificados em ordem crescente. Pode-se classificar tambm por valores calculados.

Select cdpessoa, Nome from pessoa order by cdpessoa
cdpessoa Nome
1 Obilac
2 Silva
3 Cabral
4 Lobato
5 Mateus
5 row(s)

UFPA Universidade Federal do Par
24

Na consulta abaixo se ordena pelo fone e dentro mesmo fone (260088) pelo
nome, mostrando que o order by pode ser por vrias colunas. As colunas no select no
precisam estar na mesma ordem que as colunas do order by.

Select fone, nome, cdpessoa from pessoa order by fone, nome desc
fone nome cdpessoa
Mateus 5
174590 Lobato 4
260088 Obilac 1
260088 Cabral 3
282677 Silva 2
5 row(s)

2.3 Tipos de operadores
O SQL tem trs principais classes de operadores: aritmticos, lgicos e
relacionais. Os operadores so utilizados para escrever expresses, principalmente na
clusula where mas tambm em outras clusulas como veremos em alguns exemplos.
Para entendermos como funciona a avaliao de uma expresso necessrio conhecer a
tabela de precedncia e associatividade dos operadores.
Os operadores so agrupados em classes com mesma precedncia, por exemplo,
os relacionais. Todos os operadores binrios (aritmticos e lgicos) possuem
associatividade mais esquerda. Por exemplo, se temos select 1-1-1 o resultado -1 e
no 1. Pois a expresso parentizada como (1-1)-1 e no 1-(1-1).

sql> select (1-1)-1
sql> select 1-(1-1)
sql> select 1-1-1

Na tabela abaixo listamos os operadores com a precedncia decrescendo de cima
para baixo.


Tabela 1.1 precedncia dos operadores, diminuindo de cima para baixo.
Operadores aritmticos & lgicos Operaes Resultado
+, - (unrio), identidade, negao numrico
*, /, %, mod multiplicao, diviso, resto
da diviso
numrico
+, - (binrio), || (ANSI) adio, subtrao,
concatenao
numrico ou
string
=, !=, <, >, <=, >=, comparao lgico
IS [NOT] NULL, LIKE , [NOT] BETWEEN, [NOT]
IN, EXISTS, IS OF type
comparao lgico
NOT ! negao lgica lgico
AND conjuno lgico
OR disjuno lgico

UFPA Universidade Federal do Par
25
Esta tabela faz um resumo dos principais operadores do SQL, mas existem
vrios outros que so detalhados em um mdulo especifico que trata s sobre
operadores e funes.
2.3.1 Expresses
Uma expresso uma combinao de smbolos e operadores que so avaliados
como um valor nico. Elas podem ser simples, como uma constante (numrica ou
string), uma coluna ou uma varivel; ou podem ser complexas, criadas conectando-se
uma ou mais expresses simples com operadores. Utilizando a tabela acima sabemos
como parentizar uma expresso, por exemplo:

Expresso Com parnteses
valor + 0.1 * taxa (valor + (0.1 * taxa))
val >= 10 OR val <=10 and sal+10 < 24 (val >= 10) OR ((val <=10) and ((sal+10) < 24))

O tipo de dados do resultado depende dos elementos contidos na expresso. As
converses implcitas de tipo de dados so executadas nos elementos da expresso
durante a avaliao.

sql> select 1.0+3 -> 4.0
sql> select 1+3 -> 4

Uma expresso lgica retorna um resultado verdadeiro ou falso, respectivamente, 1 ou
0. Quando utilizamos AND entre valores de tipos no lgicos eles so convertidos para
valores numricos: se o valor zero ento o valor falso seno verdadeiro. Seguem
alguns exemplos:

sql> select 1.0 and 3 -> 1
sql> select 0 and 3 -> 0
sql> select 1=1 and 3 -> 1
sql> select !1=1 and 3 -> 0
sql> select !1=1 or 3 -> 1
sql> select 1!=1 or 3 -> 1

2.3.2 Operadores comparao: IN, IS NULL, BETWEEN
O SQL tem os operadores lgicos (AND OR NOT) alm de ter vrios tipos de
operadores de comparao que retornam um valor lgico. A tabela a seguir descreve
resume os principais operadores lgicos e de comparao:

Tipo de Operador Operadores
Operadores comparao =, <,>, <=, >= , != ou <>
Comparao de Seqncias LIKE e NOT LIKE
Intervalo de valores BETWEEN e NOT BETWEEN
Lista de Valores IN e NOT IN
Valores vazios ou desconhecidos IS NULL e IS NOT NULL

Os operadores de comparao comparam colunas ou variveis de tipos de dados
compatveis. Alguns operadores testam se um valor pertence a uma lista de valores ou
tuplas. Seguem exemplos:

sql> select 0 > 3 -> 0
sql> select 1<=2 -> 1
sql> select ! 1<=1 -> 1

UFPA Universidade Federal do Par
26
O operador BETWEEN usado para definir um intervalo. A condio NOT
BETWEEN recupera as linhas fora do intervalo especificado. O operador BETWEEN X
AND Y equivale ao intervalo de X at Y inclusive.
O operador IN similar a um operador pertence que testa se um valor pertence a
uma lista de linhas. A condio IN equivale a uma serie de expresses ligadas com um
operador OR.

sql> select (1,'a') in ((2,'b'), (1,'a')) -> 1
sql> select 1 not in (1,2,3) -> 0
sql> select 1 in (1,2,3) -> 1
sql> select 2>=1 and 2 <= 3 ->1
sql> select 2 between 1 and 3 -> 1
sql> select 2 between 1 and 3 -> 1
sql> select 5 between 1 and 3 -> 0

Usa-se IS NULL e IS NOT NULL para testar campos com valores vazios. Na
criao de uma tabela devemos dizer se no queremos valores null numa coluna.

select * from pessoa where fone is null
cdpessoa nome fone
5 Mateus
1 row(s)

2.3.3 Comparaes com LIKE , curingas (string)
possvel usar a condio de pesquisa LIKE , em combinaes com caracteres
curinga, para selecionar registros comparando seqncias de caracteres. A tabela a
seguir lista exemplos do uso de curingas com a condio de pesquisa LIKE .

Expresso Retorna
like a% Qualquer seqncia iniciando com a letra a;
like %AB% Todos os nomes que contm as letras AB;
like b_a% Comea b seguida uma letra seguida de a;
like %\_% escape / Que tenha underline na palavra;
like %een Todos os nomes terminados com as letras een;
like _ex Todos os nomes com 3 letras terminados em ex;
like [CK]% Todos os nomes iniciados com as letras C ou K;
like [S-V]ing Todos os nomes de quatro letras terminados com as letras
ing e iniciados com uma letra s no intervalo de S a V;
like M[^c]% Todos os nomes iniciados com a letra M que no
contenham a letra c na segunda posio;

Na comparao de cadeias de caracteres usando o LIKE , todos os caracteres na
so significativos, incluindo os espaos em branco esquerda e direita. LIKE s pode
ser usado com dados do tipo literal e data. Segue um exemplo.

select * from pessoa where nome like '_a%'
cdpessoa nome fone
3 Cabral 260088
5 Mateus
2 row(s)


UFPA Universidade Federal do Par
27
2.3.4 Expresses com AND OR NOT e com parnteses
Usa-se os operadores lgicos (AND OR NOT) para combinar expresses. Os
resultados de uma consulta podem variar em funo de como a expresso parentizada
pelos critrios de precedncia e associatividade dos operadores.
O uso de parnteses permite alterar a ordem default de avaliao. Pode-se dar
prioridade para certas sub-expresses. O uso explcito de parnteses pode deixar mais
clara leitura de uma expresso complexa.
Nos exemplo abaixo mostramos que o parntese fora a avaliao da expresso
de forma diferente. A primeira consulta avaliada como ((nome like 'S%' and cdpessoa <= 2)
or fone = '174590').

select * from pessoa where nome like 'S%' and cdpessoa <= 2 or fone =
'174590'
cdpessoa nome fone
2 Silva 282677
4 Lobato 174590
2 row(s)

select * from pessoa where nome like 'S%' and (cdpessoa <= 2 or fone =
'174590')
cdpessoa nome fone
2 Silva 282677
1 row(s)

Existem diversas formas de escrever consultas equivalentes, por exemplo, as
duas consultas que seguem so equivalentes: a primeira usa uma conjuno com OR e a
segunda uma lista de valores com IN.

select nome from turma where cdturma = 'A' or cdturma = 'B' or cdturma
= 'C'
nome
Volei
Karate
Natao
3 row(s)


select nome from turma where cdturma in ('A', 'B', 'C')
nome
Volei
Karate
Natao
3 row(s)


UFPA Universidade Federal do Par
28
2.4 Exerccios
Na soluo dos exerccios de SQL considere o BD com as tabelas: pessoa, turma
e participante.

Discursivas:
1. O que uma operao de juno, como feita com o SQL (20/30 palavras)?
2. O que uma operao de produto cartesiano, como feito em SQL (20/30 palavras)?
3. O que retorna na consulta: Select * from pessoa where nome like _a% (10/20 palavras)?

Sejam as consultas:
a) select * from pessoa, turma
b) select distinct nome from pessoa, participante where cdpessoa=pessoa and cdpessoa=1
c) select nome as 'Nome Pessoa', cdpessoa as Codigo from pessoa
d) select * from pessoa where fone is null
e) select nome from turma where cdturma = 'A' or cdturma = 'B' or cdturma = 'C'

Pode existir mais de uma opo:
4. Na(s) consulta(s) tem um alias de coluna (a, b,c, d, e, nenhuma).
5. Na(s) consulta(s) tem um alias de tabela (a, b,c, d, e, nenhuma).
6. Na(s) consulta(s) tem uma operao de seleo (a, b,c, d, e, nenhuma).
7. Na(s) consulta(s) tem uma operao de projeo (a, b,c, d, e, nenhuma).
8. Na(s) consulta(s) tem uma operao de juno (a, b,c, d, e, nenhuma).
9. Na(s) consulta(s) tem uma operao de produto cartesiano (a, b,c, d, e, nenhuma).

SQLs:
10. Liste os nomes da pessoas repetindo o nome trs vezes seguido do cdigo: Obilac Obilac 1.
11. Mostre a pessoa com seu fone entre parnteses e o seu cdigo entre chaves.
12. Selecione todos os fones, sem duplicados.
13. Mostre os professores (nome) de cada turma (nome) com o telefone do professor.
14. Mostre as pessoas em ordem decrescente de cdigo.
15. Mostre todos os alunos (nome) em ordem crescente de cdigo.
16. Mostre todos os alunos em ordem decrescente de fone, e dentro do mesmo fone,
decrescente de cdigo.
17. Mostre todas as pessoas que tem as letras br dentro do nome.
18. Mostre todos os professores que iniciam com a letra C ou M.
19. Mostre cada pessoa com o quadrado do valor do cdigo e com raiz quadrada do fone.
20. Mostre todos os alunos das turmas A e B.

UFPA Universidade Federal do Par
29
3 Mdulo III Manipulao de Tabelas

Nesta seo so abordados vrios assuntos relativos a DDL (data definition
language) e a DCL (data control language). O objetivo aprender a criar um banco de
dados e dar manuteno das tabelas e/ou usurios.
Algumas sees deste captulo utilizam a sintaxe do MySQL. Outros Sistemas
possuem construes equivalentes: para isso deve-se consultar a documentao
pertinente.

3.1 Create Database
Existem diversos comandos para fazer a criao e manuteno das tabelas do
BD. Podemos inicialmente mostrar todas as tabelas do banco com SHOW TABLES.
Podemos ver as informaes de status de uma tabela com show table status.

show tables;
show table status;
show create database NOMEBD;
show columns from cliente;
show triggers;

show columns from cliente
Field Type Null Key Default Extra
nomecliente varchar(50) NO PRI
cidade varchar(20) NO
tipoindustria char(1) NO
3 row(s)


show table status
Name Engine ... Rows Create_time Collation Comment
cliente MyISAM 4
2006-10-25
18:31:17
latin1_swedish_ci
dependente InnoDB 2
2006-11-20
12:18:34
latin1_swedish_ci
InnoDB free: 4096 kB; (`cdemp`) REFER
`iets_dados1152675/emp`(`cdemp`)
depto InnoDB 3
2006-11-20
12:18:34
latin1_swedish_ci InnoDB free: 4096 kB
emp InnoDB 7
2006-11-20
12:18:34
latin1_swedish_ci InnoDB free: 4096 kB
participante InnoDB 5
2006-11-20
12:18:34
latin1_swedish_ci
InnoDB free: 4096 kB; (`pessoa`) REFER
`iets_dados1152675/pessoa`(`cdpessoa`);
(
pedido MyISAM 7
2006-10-25
18:31:17
latin1_swedish_ci
pessoa InnoDB 6
2006-11-20
12:18:34
latin1_swedish_ci InnoDB free: 4096 kB
pessoa1 InnoDB 0
2006-11-23
11:15:52
latin1_swedish_ci InnoDB free: 4096 kB
turma InnoDB 3
2006-11-20
12:18:34
latin1_swedish_ci
InnoDB free: 4096 kB; (`profe`) REFER
`iets_dados1152675/pessoa`(`cdpessoa`)
vendedor MyISAM 6
2006-10-25
18:31:17
latin1_swedish_ci


UFPA Universidade Federal do Par
30

Com show grants pode-se ver a permisso de cada usurio.

show grants
Grants for favero1152675@%
GRANT USAGE ON *.* TO 'favero1152675'@'%' IDENTIFIED
BY PASSWORD 'xxxxx'
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON
`iets\_dados1152675`.* TO 'favero1152675'@'%'
2 row(s)


3.2 Create/drop table
No mdulo I vimos um script para criar as tabelas Pessoa, Turma e Participante.


Pessoa
cdpessoa nome fone
1 Obilac 260088
2 Silva 282677
3 Cabral 260088
4 Lobato 174590
5 Mateus

Turma
cdturma nome profe
A Volei 4
B Karate 4
C Natao 2

Participante
pessoa turma
1 A
3 A
1 B
1 C
2 C

Fig. 1.1 Um exemplo de BD formado por trs tabelas: pessoa, turma e participante.

A figura 1.2 apresenta um esquema para estas 3 tabelas. So trs entidades
(Pessoa, Turma e Participante) e trs relacionamentos. Esta notao mostra visualmente
as informaes descritas no script apresentado abaixo em SQL. Neste esquema vemos
os relacionamentos; sobre cada um deles esta marcada a igualdade, por exemplo,
cdpessoa=profe; note tambm que na tabela Participante os dois campos fazem parte da
chave primria sendo cada um deles uma chave estrangeira.


Fig. 1.2 Exemplo de um diagrama Etidade-Relacionamento

Este esquema serve de base para projetarmos uma consulta SQL que retorna
todos os dados do banco interligando as tabelas de forma adequada. Toda consulta sobre
estas 3 tabelas, em principio, um caso mais especfico desta consulta geral.

UFPA Universidade Federal do Par
31

select cdturma, t.nome nmturma, profe, pr.nome prof, pessoa aluno,
al.nome aluno, al.fone cdpessoa
from turma t, participante p, pessoa pr, pessoa al
where t.cdturma=p.turma and p.pessoa=al.cdpessoa and
pr.cdpessoa=t.profe
cdturma nmturma profe prof aluno aluno cdpessoa
A Volei 4 Lobato 1 Obilac 260088
A Volei 4 Lobato 3 Cabral 260088
B Karate 4 Lobato 1 Obilac 260088
C Natao 2 Silva 1 Obilac 260088
C Natao 2 Silva 2 Silva 282677
5 row(s)

Como so 3 relacionamentos, no join natural, tambm so usadas trs
igualdades: t.cdturma=p.turma and p.pessoa=al.cdpessoa and pr.cdpessoa=t.profe.
A tabela pessoa especializada em al(uno) e pr(ofessor). No SQL necessrio
explicitar esta especializao, utilizando-se dois alias respectivamente al e pr.
Em resumo importante conhecer o esquema (os relacionamentos) na hora de
elaborar consultas que envolvem joins.
O script 1.1 um conjunto de comandos separados por ponto e vrgula. Neste
script temos a criao da tabela Pessoa, com trs colunas (cdpessoa, nome, fone).
Cdpessoa (cdigo da pessoa) do tipo integer no nulo, pois a chave primria. Nome
e fone so do tipo caractere de tamanho varivel (varchar).

create table pessoa
(cdpessoa integer not null,
nome varchar(6),
fone varchar(10),
primary key (cdpessoa));

create table turma
(cdturma character(1) not null,
nome varchar(10),
profe integer,
primary key (cdturma));

create table participante
(pessoa integer not null,
turma character(1) not null,
primary key (pessoa, turma));

alter table turma add foreign key (profe) references pessoa (cdpessoa);
alter table participante add foreign key (pessoa) references pessoa
(cdpessoa);
alter table participante add foreign key (turma) references turma
(cdturma);
Script 1.1: Criao de um esquema de BD com trs tabelas e trs relacionamentos

Toda chave primria possui a clusula not null, dizendo que o valor no pode
ser nulo. Outras colunas pode ter esta clusula que verificada automaticamente pelo
gerenciador do BD.
No final do script 1.1 temos trs comandos para criar os relacionamentos (chaves
estrangeiras) com o comando alter table add foreing key. So trs chaves: duas
referenciando a tabela Pessoa e uma referenciando para a tabela Turma.

UFPA Universidade Federal do Par
32
O script 1.2 d a carga dos dados iniciais na tabela usando o comando insert
into. Este um exemplo de um script de carga de um BD.

/*pessoa*/
delete from pessoa;
insert into pessoa (cdpessoa, nome, fone)values (2, 'Silva', '282677');
insert into pessoa (cdpessoa, nome, fone)values (3, 'Cabral', '260088');
insert into pessoa (cdpessoa, nome, fone)values (4, 'Lobato', '174590');
insert into pessoa (cdpessoa, nome, fone)values (1, 'OBilac',
'260088');
/*turma*/
delete from turma;
insert into turma (cdturma, nome, profe)values ('A', 'Volei', 4);
insert into turma (cdturma, nome, profe)values ('C', 'Natao', 2);
insert into turma (cdturma, nome, profe)values ('B', 'Karate', 4);
/*participante*/
delete from participante;
insert into participante (pessoa, turma)values (1, 'A');
insert into participante (pessoa, turma)values (1, 'B');
insert into participante (pessoa, turma)values (1, 'C');
insert into participante (pessoa, turma)values (2, 'C');
insert into participante (pessoa, turma)values (3, 'A');
Script 1.2: Carga do BD

O comando alter table utilizado tambm para fazer manuteno da tabela.
Pode-se, por exemplo, incluir ou excluir campos, como segue:

sql> alter table pessoa add email varchar(80);
alter table pessoa delete email;
alter table pessoa add sexo char(1) check (upper(sexo)=M or upper(sexo)=F);

3.2.1 Como duplicar uma tabela.
Como duplicar uma tabela? fcil, veja script que segue. Como trazer s uma
parte dos dados? Tambm facil, s colocar uma restrio na consulta, por exemplo,
na clusula where.

drop table if exists pessoa2;
create table pessoa2 like pessoa;
insert into pessoa2 select * from pessoa;
select * from pessoa2;
select * from turma;

drop table if exists pessoa2;
create table if not exists pessoa2 like pessoa;
insert into pessoa2 select * from pessoa where nome like '_a%';
select * from pessoa2;

O show create table mostra o comando que foi utilizado para criar a tabela.

show create table pessoa
Table Create Table
pessoa
CREATE TABLE `pessoa` ( `cdpessoa` int(11) NOT
NULL, `nome` varchar(6) default NULL, `fone`
varchar(10) default NULL, PRIMARY KEY
(`cdpessoa`) ) ENGINE=InnoDB DEFAULT
CHARSET=latin1
1 row(s)

UFPA Universidade Federal do Par
33
3.3 Insert/update/delete
As operaes de atualizao de dados devem verificar as restries de
integridade de chave primria e de integridade referencial. Se tentarmos inserir duas
vezes o mesmo valor de chave primria o sistema deve acusar um erro, como no
exemplo abaixo.

sql> insert into pessoa values (7, 'Silva7', '282677');
sql> insert into pessoa (cdpessoa, nome, fone) values (7, 'Silva7',
'282677');
Errormessage: Duplicate entry '7' for key 1

Se tentarmos apagar um registro sendo referenciado por uma chave estrangeira o
sistema tambm deve reclamar. Seguem dois exemplos de tentativa de violar a
integridade referencial.

sql> delete from pessoa where cdpessoa=1

Error: Cannot delete or update a parent row: a foreign key constraint
fails (`iets_dados1152675/participante`, CONSTRAINT
`participante_ibfk_1` FOREIGN KEY (`pessoa`) REFERENCES `pessoa`
(`cdpessoa`))

sql> delete from pessoa where nome=Lobato

Error: Cannot delete or update a parent row: a foreign key constraint
fails (`iets_dados1152675/turma`, CONSTRAINT `turma_ibfk_1` FOREIGN KEY
(`profe`) REFERENCES `pessoa` (`cdpessoa`))

Existem comandos que foram o sistema ignorar as restries de integridade, por
exemplo, a clusula ON UPDATE CASCADE que declarada junto com o comando de
criao da tabela; no final deste mdulo esse assunto retomado, mostrando-se um
exemplo.

SQL> select * from turma;
SQL> update turma set nome = 'Futebol' where nome = 'Volei';
SQL> select * from turma;

delete from pessoa where cdpessoa = 7;
insert into pessoa values (7, 'Silva7', '282677');
select * from pessoa;

delete from pessoa where cdpessoa = 7;
insert into pessoa (cdpessoa, nome) values (7, 'Silva7');
select * from pessoa;

delete from pessoa where cdpessoa = 7;
insert into pessoa (cdpessoa) values (7);
select * from pessoa;

delete from pessoa where cdpessoa = 7;
insert into pessoa values (7, 'Mateus7', Null);
select * from pessoa;

Seguem alguns exemplos de atualizaes. Usa-se o comando update tabela set
campo=... associado a uma clusula where que seleciona as linhas a serem alteradas.

update pessoa set fone = 'xxxxx' where cdpessoa=1;
UPDATE pessoa SET sal=sal+1;
select * from pessoa;

UFPA Universidade Federal do Par
34


3.4 Create view
Podemos salvar o resultado de uma consulta como uma viso. Este recurso
til quando, por exemplo, temos uma tabela com o salrio do funcionrio e queremos
que um usurio veja tudo menos a coluna do salrio.

sql> create view prof_pessoa (turma_nome, cdpessoa)
as select turma.nome, pessoa.nome
from turma, pessoa where profe = cdpessoa;
sql> select turma_nome from prof_turma;


3.5 BD emp, depto, dependente
Nos mdulos deste curso trabalhamos tambm com BD emp, depto e
dependente. Seguem as trs tabelas:

select * from emp
cdemp nome fone salario chefe depto
1 OBilac 2688 20000 3 S
2 Silva 2677 30000 H
3 Cabral 1088 22000 2 S
4 Lobato 4590 28000 2 H
8 Maria 2690 25000 4 C
9 Antune 2698 26000 8 C
10 Petter 2645 22000 8 C
7 row(s)

select * from depto
cddepto nome responsavel
C Computao 8
H Sede 2
S Seguranca 3
3 row(s)

select * from
dependente
cdemp cddep nome
2 1 Jose
2 2 Ana
2 row(s)


Abaixo mostramos o diagrama E-R para estas 3 tabelas. A tabela emp(regado)
pode ser vista como: (responsvel, chefe ou empregado). Podemos pensar numa
especializao: um empregado pode ser um responsvel pelo departamento ou pode ser
tambm um chefe; um depto tem um s responsvel, porm nele podem existir vrios
chefes. Portanto, nas consultas SQL fica mais fcil trabalhar com trs alias: (r, c, e),
respectivamente. Abaixo temos o diagrama E-R com os relacionamentos entre estas trs
tabelas.


UFPA Universidade Federal do Par
35

Fig. 5.2 Exemplo de um diagrama E-R com um auto-relacionamento: emp --(chefe)--> emp;

Segue abaixo um esquema de consulta genrica que considera todos os
relacionamentos e alias. Para cada relacionamento devemos ter uma igualdade na
clusula where.

Select d.nome DEPTO, r.nome RESP, c.nome CHEFE, e.nome EMP
from emp e, emp c, emp r, depto d
where e.chefe=c.cdemp and d.responsavel=r.cdemp and e.depto=d.cddepto
order by d.nome, r.nome, c.nome
DEPTO RESP CHEFE EMP
Computao Maria Lobato Maria
Computao Maria Maria Antune
Computao Maria Maria Petter
Sede Silva Silva Lobato
Seguranca Cabral Cabral OBilac
Seguranca Cabral Silva Cabral
6 row(s)

Abaixo apresentamos um script para criar estas duas tabelas emp e depto.
Inicialmente criamos somente estas duas pois elas tem relacionamentos circulares o
que dificulta ou impossibilita a incluso dos dados. Desafio: rode o script abaixo e tente
fazer alguma incluso de dado, tipo insert into emp (cdemp, nome, fone, salario, depto)
values (2, 'Silva', '2677', 30000, 'H'); insert into depto (cddepto, nome, responsavel)
values ('H', 'Sede', 2);

create table emp (cdemp integer not null,
nome varchar(6),
fone varchar(10),
salario integer,
chefe integer,
depto character(1),
primary key (cdemp));


UFPA Universidade Federal do Par
36
create table depto
(cddepto character(1) not null,
nome varchar(12),
responsavel integer,
primary key (cddepto));

alter table emp add constraint emp_to_chefe foreign key (chefe)
references emp (cdemp);
alter table emp add constraint emp_to_dept foreign key (depto)
references depto (cddepto);
alter table depto add constraint depto_to_responsavel foreign key
(responsavel) references emp (cdemp);

Para facilitar a carga dos dados melhor remover as restries de integridade
referencial, i.e., as chaves estrangeiras. Fazer as incluses e depois voltar a colocar as
restries de integridade referencial. Com segue.

/* remove restries de chave */
alter table emp drop constraint emp_to_chefe;
alter table emp drop constraint emp_to_dept;
alter table depto drop constraint depto_to_responsavel;

/* insere os registros */
insert into emp (cdemp, nome, fone, salario, depto)
values (2, 'Silva', '2677', 30000, 'H');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (3, 'Cabral', '1088', 22000, 2, 'S');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (4, Lobato, '4590', 28000, 2, 'H');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (1, OBilac, '2688', 20000, 3, 'S');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (8, 'Maria', '2690', 25000, 4, 'C');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (9, 'Antune', '2698', 26000, 8, 'C');
insert into emp (cdemp, nome, fone, salario, chefe, depto)
values (10, 'Petter', '2645', 22000, 8, 'C');

insert into depto (cddepto, nome, responsavel) values ('H', 'Sede', 2);
insert into depto (cddepto, nome, responsavel) values ('S', 'Seguranca', 3);
insert into depto (cddepto, nome, responsavel) values ('C', 'Computao', 8);

/* reativa as restries de chave */
alter table emp add constraint emp_to_chefe foreign key (chefe) references
emp(cdemp);
alter table emp add constraint emp_to_dept foreign key (depto) references
depto (cddepto);
alter table depto add constraint depto_to_responsavel foreign key
(responsavel) references emp (cdemp);

Por fim criamos a tabela dependente e inclumos alguns dependentes. Para
incluir dependentes no existem maiores problemas desde que o cdemp j exista na
tabela emp.

create table dependente (cdemp integer not null,
cddep integer not null,
nome varchar(6),
primary key (cdemp, cddep));

alter table dependente add constraint dept_to_emp foreign key (cdemp)
references emp (cdemp);
insert into dependente (cdemp, cddep, nome) values (2, 1, 'Jose');
insert into dependente (cdemp, cddep, nome) values (2, 2, 'Ana');


UFPA Universidade Federal do Par
37

3.6 Transaes
As transaes so recursos utilizados para manter a integridade dos dados. Se
uma operao falha, um DB est sujeito a entrar num estado inconsistente. Por exemplo,
suponha que durante uma venda num caixa eletrnico falta luz. E que numa tabela j
foi registrado o total da venda, mas ainda no foram registrados todos os produtos
vendidos naquela venda.
Para tratar transaes, o SQL assume que a palavra commit pode ser usada para
abrir e/ou fechar uma transao. A palavra roolbak usada para desfazer o estado de
execuo at o ponto do ltimo commit.

> commit;
Transaction committed
> delete from pessoa where nome = 'Isaac';
Ok (1 row affected)
> select * from pessoa;
> rollback;
Transaction aborted
> select * from pessoa;

commit;
select * from pessoa;
update pessoa SET nome = upper(nome);
select * from pessoa;
rollback;
select * from pessoa;

3.7 Create index
Os ndices para o modelo relacional so apenas utilizados para otimizar o acesso
aos dados. Por outro lado, enquanto que um ndice otimiza as buscas, ele penaliza as
inseres.
Para saber se um ndice efetivo devermos criar o ndice e testar o tempo das
consultas para ver se elas reduzem o tempo de execuo (executando as consultas vrias
vezes).
Em princpio usam-se ndices para as seguintes situaes:
recomendvel que toda chave primria tenha ndice (nico); quase
todos os sistemas de BD geram automaticamente estes ndices; chaves
compostas deve ter um ndice formado pelos vrios campos;
recomendvel tambm que os campos que so chaves estrangeiras
tenham ndice, mas no obrigatrio (em muitos sistemas);
chaves candidatas tipo nome e CPF se forem usadas para buscas tambm
devem ser indexadas; estas chaves podem conter a clusula UNIQUE,
neste caso muitos sistemas criam um ndice para facilitar o teste de
unicidade.

Seguem alguns exemplos de criao de ndices. O comando CREATE INDEX
cria um ndice com uma ou mais colunas. E o comando DROP INDEX remove o
ndice. Abaixo tambm listamos o comando ANALYSE e EXPLAIN. No MySQL o
comando ANALYZE TABLE informa para o sistema verificar as chaves e ndice antes
de fazer o plano da consulta (decidir como ser executada a consulta). O EXPLAIN
mostra o plano da consulta (esquema estratgico de execuo da consulta) que mostra

UFPA Universidade Federal do Par
38
os recursos necessrios para a execuo da mesma. Examinando o plano sabemos se o
sistema vai ou no utilizar um ndice.

CREATE INDEX xcdpessoa ON pessoa (cdpessoa);
CREATE INDEX xparticipante ON participante (pessoa, turma);
DROP INDEX xcdpessoa;

ANALYZE TABLE pessoa;
EXPLAIN select * from pessoa limit 3;
CREATE INDEX dpessoa ON pessoa (cdpessoa);
EXPLAIN select * from pessoa LIMIT 3;

Suponha que queremos executar a consulta select * from pessoa2 where nome='M%'
limit 3. Como podemos otimiz-la? Vendo que queremos pesquisar um nome, um ndice
em ordem alfabtica pode otimizar a consulta. Portanto cria-se o ndice idxnome com
este propsito. Como saber se ele ser utilizado? Basta executar o EXPLAIN sobre a
consulta antes e depois de criar o ndice. Como vemos abaixo, antes de se criar o plano
no considera nenhuma chave; porm aps a criao do ndice a chave nome
considerada. Na primeira consulta o nmero estimado de linhas a serem examinadas
toda a tabela (6 rows) enquanto que aps a criao do ndice apenas uma linha ser
examinada. Suponha que esta tabela tenha 100 mil linhas ento a otimizao seria muito
grande.

explain select * from pessoa2 where nome='M%' limit 3
create index idxnome on pessoa2 (nome);
explain select * from pessoa2 where nome='M%' limit 3

Plano
antes
de criar
o ndice
explain select * from pessoa2 where nome='M%' limit 3
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pessoa2 ALL 6
Using
where
1 row(s)

Plano
aps
criar o
ndice
explain select * from pessoa2 where nome='M%' limit 3
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pessoa2 ref nome nome 9 const 1
Using
where
1 row(s)


O SQL pode tirar proveito dos ndices em vrias situaes: para ordenar as
linhas (ORDER BY); para executar operadores relacionais tais como = > < ; para
encontrar os valores max() e min(), etc. A consulta que segue otimizada se for criado
um indice na coluna last_name.

WHERE last_name >= 'Mac' AND last_name < 'Mad'

Sejam as expresses abaixo. Destas duas expresses a primeira bem mais
eficiente, pois a expresso 4/2 calculada uma s vez; na segunda consulta tem que ser
calculada para todos os valores da coluna.

WHERE coluna < 4 / 2
WHERE coluna * 2 < 4


UFPA Universidade Federal do Par
39
Sejam as duas consultas abaixo. A segunda mais eficiente pois no exige o
clculo da funo para todos os valores da coluna; ela tambm pode se beneficiar com
um ndice.

SELECT * FROM tbl WHERE YEAR(data_col) < 1990;
SELECT * FROM tbl WHERE data_col < '1990-01-01'

Sejam as duas consultas abaixo. A segunda pode fazer uso do ndice enquanto
que a primeira no. Logo, devemos evitar o uso de curinga no inicio de um like, como
na primeira, pois forar uma pesquisa/varredura de toda a tabela.

WHERE col_name LIKE '%string%'
WHERE last_name LIKE 'Mac%'

Por fim, todos os sistemas possuem comandos especficos para dar dicas para a
consulta ser corretamente otimizada, por exemplo, no MySQL existe a opo
STRAIGHT_JOIN, FORCE INDEX, USE INDEX ou IGNORE INDEX que guia
manualmente a estratgia de execuo da consulta.
Para uma maior compreenso deste tpico o leitor deve consultar livros sobre
organizao de arquivos e estruturas de dados para estudar tpicos relacionados com
ndices e ordenao, tais como: rvore B+ (btree), ndices do tipo hashing, etc.


3.8 Restries de FOREIGN KEY no MySQL
No MySQL o tipo de tabela InnoDB implementa as restries de integridade
referencial para manter a integridade dos dados. Segue a sintaxe:

[CONSTRAINT [symbol]] FOREIGN KEY (index_col_name, ...)
REFERENCES nome_tabela (index_nome_coluna, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
Para as restries funcionarem todas as tabelas devem ser do tipo InnoDB: na
tabela deve existir um ndice onde as colunas de chaves estrangeiras listadas como
as PRIMEIRAS colunas e na tabela indicada deve haver um ndice onde as colunas
indicadas so listadas como as PRIMEIRAS colunas e na mesma ordem. O
InnoDB no cria ndices automaticamente em chaves estrangeiras para chaves
referenciadas: eles devem ser criadas explicitamente pelo usurio.
Os ndices so necessrios para verificao de chaves estrangeiras ser rpida.
Ambas as chaves devem ter tipos de dados internos compatveis, dentro do InnoDB,
para que possam ser comparados sem uma converso de tipo. Por exemplo, para
numricos o tamanho e a sinalizao de tipos inteiros devem ser o mesmo. O tamanho
dos tipos string no precisam ser o mesmo. Caso seja especificada uma ao SET
NULL, devemos ter certeza que os campos da tabela filha no possuem a clusula NOT
NULL.
Se o MySQL retorna o erro de nmero 1005 de uma instruo CREATE TABLE
(e a string de mensagem de erro se referir ao errno 150) ento a criao da tabela falhou
porque um restrio de chaves estrangeiras no foi formada corretamente.
Similarmente, se uma ALTER TABLE falhar e se referir ao errno 150, significa
que um definio de chave estrangeira foi formada incorretamente na tabela alterada.

UFPA Universidade Federal do Par
40
Pode-se usar SHOW INNODB STATUS para ver uma explicao detalhada do ltimo
erro de chave estrangeira do InnoDB no servidor.
Existem as clusulas ON DELETE CASCADE ou ON DELETE SET NULL
com a restrio de chave estrangeira.. Se ON DELETE CASCADE for especificado, e
um registro na tabela pai for deletado, ento o InnoDB automaticamente tambm deleta
todos aqueles registros na tabela filha cujos valores de chaves estrangeiras so iguais ao
valor da chave referenciada no registro pai.
Se ON DELETE SET NULL for especificado, os registros filhos so
automaticamente atualizados e assim as colunas na chave estrangeira so definidas com
o valor NULL do SQL.
Um desvio dos padres SQL: se ON UPDATE CASCADE ou ON UPDATE
SET NULL retornam para atualizar a MESMA TABELA que j tenha sido atualizada
durante o processo cascata, ele atua como RESTRICT. O RESTRICT: se existir um
registro filho com diversos registros pais, o InnoDB no permite a deleo de qualquer
um dos registros pais. Isto para prevenir loops infinitos resultantes de atualizaes em
cascata. Estas duas clusulas, ON DELETE SET NULL e ON DELETE CASCADE
tambm funcionam para auto referncias.

CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT, INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE SET NULL
) TYPE=INNODB;

Um exemplo completo:
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)) TYPE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
product_category INT NOT NULL,
product_id INT NOT NULL,
customer_id INT NOT NULL,
PRIMARY KEY(no),
INDEX (product_category, product_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
INDEX (customer_id),
FOREIGN KEY (customer_id)
REFERENCES customer(id)) TYPE=INNODB;

Pode-se adicionar novas restries de chaves estrangeiras para a uma tabela mas
primeiro deve-se criar os ndices necessrios.

ALTER TABLE seunomedetabela
ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES anothertablename(...)
[on_delete_and_on_update_actions]

ALTER TABLE suatabela DROP FOREIGN KEY id_chave_estrangeira_gerada_internamente

O SHOW CREATE TABLE mostra os ids das chaves primrias geradas
internamente.
show create table pessoa

UFPA Universidade Federal do Par
41
Table Create Table
pessoa
CREATE TABLE `pessoa` ( `cdpessoa` int(11) NOT
NULL, `nome` varchar(6) default NULL, `fone`
varchar(10) default NULL, PRIMARY KEY
(`cdpessoa`) ) ENGINE=InnoDB DEFAULT
CHARSET=latin1
1 row(s)

No MYSQL, qualquer ALTER TABLE remove todas as restries de chaves
estrangeiras definidas na tabela. Portanto, para tabelas referenciadas deve-se usar DROP
TABLE e CREATE TABLE para modificar o esquema. Quando o MySQL faz um
ALTER TABLE ele pode usar internamente RENAME TABLE, e isto ir confundir a
restrio de chave estrangeira que se refere tabela. Uma instruo CREATE INDEX
processada no MySQL como um ALTER TABLE, assim estas restries tambm se
aplicam a ele.
Ao fazer a verificao de chaves estrangeiras, o InnoDB define o bloqueio a
nvel de linhas compartilhadas em registros filhos e pais que ele precisa verificar. O
InnoDB verifica a restrio de chaves estrangeiras imediatamente: a verificao no
aplicada no commit da transao.
Para ignorar as restries de chaves estrangeiras durante, por exemplo, uma
operao LOAD DATA, usa-se SET FOREIGN_KEY_CHECKS=0.
O InnoDB permite apagar qualquer tabela mesmo que ela quebre a
restrio de chaves estrangeira que referencia a tabela. Ao apagar uma tabela as
restries definidas na instruo create tambm so apagadas.
Ao recriar uma tabela que foi apagada, ela deve ter uma definio de acordo com
a restrio de chaves estrangeiras que fazem referncia a ela. Ela deve ter os nomes e
tipos de colunas corretos e deve ter os ndices na chave referenciada como indicado
acima. Se esta condio no for satisfeita, o MySQL retornar o erro de nmero 1005 e
se refere ao errno 150 na string de mensagem de erro.

UFPA Universidade Federal do Par
42
4 Mdulo IV GROUP BY
Nesta seo so abordados assuntos relativos as consultas agregadas. O objetivo
aprender a criar consultas agregadas resumindo os dados da tabela.
Algumas sees deste captulo utilizam a sintaxe do MySQL. Outros Sistemas
possuem construes equivalentes: para isso deve-se consultar a documentao
pertinente.

4.1 Funes de agrupamento bsicas
No SQL existem funes para agrupar e resumir dados, so as funes de
agrupamento (ou agregao). As funes so utilizadas em conjunto com trs clusulas
SELECT, GROUP BY e HAVING. Segue a lista das principais funes de
agrupamento.

Funes agregadas Descrio
AVG Mdia de valores em uma expresso numrica
COUNT(expr) Nmero de linhas que satisfazem a expr
COUNT(*) Numero de linhas da consulta
MAX(expr) Maior valor da expr
MIN(expr) Menor valor da expr
SUM(expr) Soma dos valores da expr

Segue alguns exemplos destes operadores sobre todas as linhas de uma tabela.
Count(*) contabiliza tambm linhas com campos nulos, porm quando aplicamos sobre
uma coluna apenas, e.g., count(fone), os valores nulos no so contados. Podemos
tambm contar os valores distintos com a clusula DISTINCT.

select * from pessoa
cdpessoa nome fone
1 Obilac 260088
2 Silva 282677
3 Cabral 260088
4 Lobato 174590
5 Mateus
5 row(s)

sql> select count(*) from pessoa -> 5
sql> select count(fone) from pessoa -> 4
sql> select count(distinct fone) from pessoa -> 3

select count(fone) from pessoa
count(fone)
4
1 row(s)


UFPA Universidade Federal do Par
43
O tipo de dados de uma coluna determina as funes que podem ser usadas.
SUM s pode ser usada com valores numricos. MAX e MIN podem tambm para
valores literais.

select * from emp
cdemp nome fone salario chefe depto
1 OBilac 2688 20000 3 S
2 Silva 2677 30000 H
3 Cabral 1088 22000 2 S
4 Lobato 4590 28000 2 H
8 Maria 2690 25000 4 C
9 Antune 2698 26000 8 C
10 Petter 2645 22000 8 C
7 row(s)

Considerando a tabela acima, temos os exemplos, que seguem.

select max(nome) from emp
max(nome)
Silva
1 row(s)

select max(salario) from emp
max(salario)
30000
1 row(s)

No clculo de uma mdia ou de uma soma os valores nulos so ignorados. Por
exemplo, na tabela temos 7 linhas, mas s temos seis valores para chefe. Logo a mdia
do chefe 27/6=4.5.

select (select sum(chefe) from emp)/(select count(chefe) from emp)
(select sum(chefe) from emp)/(select count(chefe) from emp)
4.5000
1 row(s)

Seguem alguns exemplos para serem praticados. Note que podemos contar
tambm s linhas que possuem alguma coluna com valor nulo.

sql> select count(*) from pessoa where fone is null -> 1
sql> select max(nome) from emp -> Silva
sql> select min(nome) from emp -> Antune
sql> select count(chefe) from emp -> 6
sql> select avg(chefe) from emp -> 4.5

Seguem mais alguns exemplos para serem praticados
select avg(salario) from emp;
select chefe, avg(salario) from emp group by chefe;


UFPA Universidade Federal do Par
44
select chefe, sum(salario) from emp group by chefe;
select depto, avg(salario) from emp group by depto;
select depto, count(*) from emp group by depto;

Um erro bastante comum tentar o uso direto de funes de agrupamento nas
clusulas where como segue:

select * from pessoa where fone max(fone)
Errormessage: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server
version for the right syntax to use near 'max(fone)'
at line 1

O certo usar um select para cada clculo de funo de agregao, como
mostrado no exemplo abaixo.

select * from pessoa where cdpessoa = (select max(cdpessoa) from
pessoa)
cdpessoa nome fone
5 Mateus
1 row(s)



4.2 A clusula GROUP BY
Uma funo agregao sem a clusula GROUP BY opera sobre toda a tabela.
Por exemplo, a mdia de salrio da tabela emp.

select avg(salario) from emp
avg(salario)
24714.2857
1 row(s)

Pode-se utilizar as funes sobre grupos de linhas como exemplificado abaixo,
onde calcula-se a mdia de salrio para cada chefe.

select chefe, avg(salario) from emp group by chefe
chefe avg(salario)
30000.0000
2 25000.0000
3 20000.0000
4 25000.0000
8 24000.0000
5 row(s)

O group by muito til para se fazer relatrio com totalizaes de grupos como
segue. Note que podemos ter tambm a clusula where para impor restries nas linhas.

select chefe, sum(salario) from emp

UFPA Universidade Federal do Par
45
where chefe is not null group by chefe
chefe sum(salario)
2 50000
3 20000
4 25000
8 48000
4 row(s)



4.3 A clusula HAVING
Assim como a clusula WHERE esta para o SELECT a clusula HAVING est
para o GROUP BY, para impor restries sobre as funes de agregao. Enquanto que
a clusula WHERE restringe linhas, a clusula HAVING restringe grupos de linhas.
Note que numa consulta podem coexistir ambas where e having, cada uma cumprindo o
seu papel.
select chefe, sum(salario) from emp where chefe is not
null group by chefe having sum(salario)>25000
chefe sum(salario)
2 50000
8 48000
2 row(s)

sql> select chefe, sum(salario) from emp
group by chefe
having chefe is not null and sum(salario)>25000; /* mesmo que acima */

sql> select depto, avg(salario) from emp
group by depto having avg(salario) > 22000;

O uso da clusula HAVING sem a clusula GROUP BY no faz sentido; pode-
se fazer referencia a qualquer uma das colunas exibidas na lista de seleo.

select chefe, sum(salario) from emp
where chefe is not null
group by chefe having chefe>5 and sum(salario)>25000
chefe sum(salario)
8 48000
1 row(s)

Mais exemplos para praticar.
sql> select depto, avg(salario) from emp where salario > 20000 group by depto;
sql> select depto, avg(salario) from emp group by depto having avg(salario) >
22000;
sql> select depto, avg(salario) from emp where salario > 20000 group by depto
having avg(salario) > 22000;



4.3.1 Funes GROUP BY (para MySQL)


UFPA Universidade Federal do Par
46
Nesta seo listamos mais algumas funes de agrupamento, tais como funes
para estatstica (desvio padro e varincia) e funes sobre valores binrios que so
utilizadas para implementar conjuntos (cada bit representa um elemento do conjunto).

COUNT(expr) retorna a quantidade de valores no-NULL nas linhas recuperadas pelo SELECT.
COUNT(*) conta tambm os valores NULL.
COUNT(DISTINCT
expr,[expr...])
conta valores no-NULL diferentes.
AVG(expr) retorna o valor mdio de expr.
MIN(expr), MAX(expr) retorna o valor mnimo ou mximo de expr; podem ser string como argumento.
SUM(expr) soma no nulos.
VARIANCE(expr) retorna a varincia padro de expr (considera o grupo uma populao).
STD(expr),
STDDEV(expr)
retorna o desvio padro, que a raiz quadrada da varincia.
BIT_OR(expr)
BIT_AND(expr)
BIT_XOR(expr)
retorna o bitwise de todos os bits em expr (em valores 64-bits (BIGINT)). A
funo retorna 0 se no houver linhas coincidentes.

mysql > SELECT avg(salario), min(salario), max(salario) FROM emp GROUP BY
chefe
mysql> SELECT avg(salario), std(salario), variance(salario) FROM emp GROUP BY
chefe

4.3.2 Clusula GROUP_CONCAT
Vrias verses de SQL provem uma clusula GROUP_CONCAT para gerar
uma lista para cada grupo. Por exemplo, na consulta abaixo listamos todos os
funcionrios de cada departamento.

SELECT depto,count(*), GROUP_CONCAT(DISTINCT nome ORDER BY chefe
DESC SEPARATOR , ) as emp-lista FROM emp GROUP BY depto
depto count(*) emp-lista
C 3 Petter, Antune, Maria
H 2 Lobato, Silva
S 2 OBilac, Cabral
3 row(s)


GROUP_CONCAT(expr) retorna a string resultante contendo valores de um grupo, segue
a sintaxe:

GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {inteiro_sem_sinal | nome_coluna | formula} [ASC | DESC]
[,col ...]]
[SEPARATOR valor_str])

mysql> SELECT chefe,count(*), GROUP_CONCAT(DISTINCT nome ORDER BY chefe DESC SEPARATOR , ) as
subordinados FROM emp GROUP BY chefe having count(*)>1

mysql> SELECT nome_estudante,
GROUP_CONCAT(note_teste)
FROM estudante
GROUP BY nome_estudante;

mysql> SELECT nome_estudante,
GROUP_CONCAT(DISTINCT nota_teste

UFPA Universidade Federal do Par
47
ORDER BY nota_teste DESC SEPARATOR " ")
FROM estudante
GROUP BY nome_estudante;

4.4 Exerccios
Questes Falso/verdadeiro:
1. Count(*) tambm conta os nulos .
2. Count(campo) tambm conta os nulos.
3. Count(distinct campo) tambm conta os nulos.
4. A clusula having est associada clusula select.
5. A clusula having est associada clusula group by.
6. As funes de agregao s podem ser utilizadas com a clusula group by.
7. A funo de agregao sum pode ser utilizada para dados alfanumricos

Questes discursivas:
8. Para que serve a opo GROUP_CONCAT()? (30 palavras)
9. Fale sobre as clusulas: select, where, group by, having? (30 palavras)
10. Quais so as funes de agregao ou agrupamento? (10 palavras).
11. Qual o resultado desta consulta, explique com palavras (20 palavras)? (para cada
uma)
a) select avg(salario) from emp;
b) select chefe, avg(salario) from emp group by chefe;
c) select chefe, sum(salario) from emp group by chefe;
d) select depto, avg(salario) from emp group by depto;
e) select depto, count(*) from emp group by depto;
f) select depto, avg(salario) from emp where salario > 20000 group by depto;
g) select depto, avg(salario) from emp group by depto having avg(salario) > 22000;
h) select depto, avg(salario) from emp where salario > 20000 group by depto having avg(salario) >
22000;

Questes de SQL:
12. Mostre o nome do professor, o nome da turma e o nro de alunos da turma (em
trs colunas).
13. Usando Group_concat mostre, o nome do professor, da turma e uma lista de
alunos, separados por vrgulas (em trs colunas); uma turma por linha.
14. Usando a tabela EMP, mostre o salrio de valor mnimo pago em cada
departamento (duas colunas depto e mim).
15. Usando a tabela EMP, mostre o salrio mximo pago aos funcionrios
subordinados do Silva (s um valor).
16. Usando a tabela EMP, mostre a mdia de salrio pago aos funcionrios
subordinados da Maria (s um valor).
17. Usando a tabela EMP, mostre todas as pessoas que ganham acima da mdia (s
uma coluna).
18. Usando a tabela EMP. Quem ganha 15% acima da mdia (s uma coluna).
19. Usando a tabela EMP. Quem ganha mais que o seu chefe (s uma coluna).
20. Usando a tabela EMP. Qual o desvio padro dos salrios (s um valor).

UFPA Universidade Federal do Par
48
5 Mdulo V Sub-consultas
Nesta sesso so abordados vrios assuntos relativos a consultas mais
complexas, as quais usam todo o poder expressivo do SQL.

5.1 Tipos de Join: cross, inner, out, left, right
O tipo mais simples de juno o join implcito, pela ligao de uma chave
primria com uma chave estrangeira, como na consulta que segue.

select a.turma turma, b.nome nmaluno
from participante a, pessoa b where a.pessoa = b.cdpessoa
turma nmaluno
A Obilac
B Obilac
C Obilac
C Silva
A Cabral
5 row(s)

O outro tipo de juno acontece com o join explcito, que segue a sintaxe: from
TAB1 [inner] join TAB2 on TAB1.col=TAB2.col que pode ligar duas ou mais tabelas. A
palavra inner opcional. O inner join quando liga duas tabelas pela condio de
igualdade entre duas (ou mais) colunas tambm chamado de join natural ou equi-join.
A condio de igualdade atende a grande maioria das consultas, mas pode ser tambm
uma condio de desigualdade (!=, < , <=, >, >=). Se for uma desigualdade j no
mais chamado equi-join.
A palavra inner usada para diferenciar o inner do outer, como exemplificado
em duas consulta abaixo:
inner join s retornam as linhas com a condio vlida (uma espcie de
interseo);
outer join retornada todas as linhas de pelo menos uma das tabelas envolvidas
(uma especie de unio esquerda ou unio direita).

select a.turma turma, b.nome nmaluno
from participante a inner join pessoa b on a.pessoa = b.cdpessoa
turma nmaluno
A Obilac
B Obilac
C Obilac
C Silva
A Cabral
5 row(s)

A palavra outer tambm opcional, isto , a expresso, ... from participante
a right join pessoa b on a.pessoa = b.cdpessoa dar o mesmo resultado. Note que

UFPA Universidade Federal do Par
49
no outer join todos os registro que tem um valor comum so trazidos mais todos os da
tabela da direita ou da esquerda conforme for left ou right.
Semanticamente o join natural (ou inner join ou join) traz os alunos de cada
turma. E o outer join traz tambm todos os alunos que ainda no esto matriculados nas
turmas. Serve para ver quais os alunos que ainda no esto matriculados nas turmas.
Um outro exemplo de uso: suponha que queremos fazer um relatrio dos
homens cadastrados num clube, com as informaes das esposas; e que existem duas
tabelas relacionadas: dos homens e das esposas. Um join natural s retorna os homens j
casados, que tem uma esposa. Um outer join retorna todos os homens, com ou sem
esposa.

select a.turma turma, b.nome nmaluno
from participante a right outer join pessoa b on a.pessoa = b.cdpessoa
turma nmaluno
A Obilac
B Obilac
C Obilac
C Silva
A Cabral
Lobato
Mateus
7 row(s)

O mesmo efeito da consulta acima pode ser conseguido com left outer join,
trocando-se as tabelas pessoa e participante:

sql> select a.turma turma, b.nome nmaluno
from pessoa b left outer join participante a on a.pessoa = b.cdpessoa

Pode-se combinar o efeito do left e do right join num comando com a palavra
full outer join, como no exemplo:

sql> select a.turma turma, b.nome nmaluno
from participante a full outer join pessoa b on a.pessoa = b.cdpessoa

Por fim, segue um exemplo para inner join com >. O problema com as junes
no equi-join descobrir o que significa a consulta: primeiro feito um produto
cartesiano; depois, sobre todas as linhas do resultado verificada a condio do join; se
for verdadeira a linha retornada.

select a.turma turma, b.nome nmaluno
from pessoa b join participante a on a.pessoa > b.cdpessoa
turma nmaluno
C Obilac
A Obilac
A Silva
3 row(s)

Segue um exemplo com left outer join e >.


UFPA Universidade Federal do Par
50
select a.turma turma, b.nome nmaluno
from pessoa b left outer join participante a on a.pessoa > b.cdpessoa
turma nmaluno
A Obilac
C Obilac
A Silva
Cabral
Lobato
Mateus
6 row(s)

Segue duas formas de se escrever a mesma consulta:
sql> select a.turma turma, b.nome nmaluno
from pessoa b right outer join participante a on a.pessoa > b.cdpessoa
sql> select a.turma turma, b.nome nmaluno
from pessoa b right join participante a on a.pessoa > b.cdpessoa

5.1.1 Diferentes formas de escrever a mesma coisa
Comeamos mostrando que existem mais de um modo de fazer um produto
cartesiano. O cross join um sinnimo de produto cartesino. As duas sintaxes so
vlidas.
sql> select * from pessoa, turma
sql> select * from pessoa cross join turma

Podemos impor restries sobre as linhas resultantes do produto cartesiano na
clusula where, como segue.

sql> select * from pessoa cross join turma where profe > cdpessoa
sql> select * from pessoa, turma where profe > cdpessoa

Sobre join tambm temos vrias sintaxes alternativas. Por exemplo, as trs
consultas que seguem trazem o mesmo resultado; na segunda usamos alias de tabelas e
inner join implcito; na terceira o inner join explcito. Alm disso as palavras inner so
opcionais.
sql> select turma.nome nmturma from turma, participante, pessoa
where cdturma = turma and pessoa = cdpessoa and pessoa.nome =\'OBilac\'
sql> select A.nome nmturma from turma A, participante B, pessoa C
where A.cdturma = B.turma and B.pessoa = C.cdpessoa and C.nome ='OBilac';
sql> select A.nome nmturma
from turma A inner join participante B on A.cdturma = B.turma
inner join pessoa C on B.pessoa = C.cdpessoa
where C.nome =\'OBilac\'

select A.nome nmturma
from turma A inner join participante B on A.cdturma = B.turma
inner join pessoa C on B.pessoa = C.cdpessoa
where C.nome =\'OBilac\'
nmturma
Volei
Karate
Natao
3 row(s)


UFPA Universidade Federal do Par
51
5.1.2 Join vs modelo lgico de dados
Quando a juno acontece com uma igualdade entre duas colunas ela chamada
de equi-join. Este tipo de join o mais utilizado para se gerar consultas que combinam
as informaes de vrias tabelas do banco de dados, todas elas ligadas interligadas pelas
relaes de chave estrangeira com chave primria. Sempre bom ter em mente o
modelo lgico do BD na hora de se fazer os joins.


Fig. 5.1 Exemplo de um diagrama Etidade-Relacionamento e duas consultas que traz os dados
combinados das trs tabelas; note que cada equi-join uma relao entre chaves;

sql> select turma.nome nmturma from turma, participante, pessoa
where cdturma = turma and pessoa = cdpessoa

sql> select t.nome turma, pr.nome profe, al.nome aluno, prof
from turma t, participante p, pessoa pr, pessoa al
where t.cdturma = p.turma and p.pessoa = al.cdpessoa and pr.cdpessoa=profe



select t.nome turma, pr.nome profe, al.nome aluno
from turma t, participante p, pessoa pr, pessoa al
where t.cdturma = p.turma and p.pessoa = al.cdpessoa and pr.cdpessoa=profe
turma profe aluno
Volei Lobato Obilac
Volei Lobato Cabral
Karate Lobato Obilac
Natao Silva Obilac
Natao Silva Silva
5 row(s)

Sempre que possvel condio de associao entre tabelas deve seguir o
modelo lgico definido pela ligao entre chaves primrias e estrangeiras. Para
evitar expanso dos dados (criar linhas no existentes), quando a chave composta,
deve-se fazer referencia a chave inteira.
A operao de join das mais caras do SQL (em termos de tempo e memria)
logo deve ser usada com parcimnia.
Segue uma lista de comandos para exercitar.


UFPA Universidade Federal do Par
52
select * from dependente d join emp e on d.cdemp = e.cdemp;
select * from dependente d left outer join emp e on d.cdemp = e.cdemp;
select * from dependente d right outer join emp e on d.cdemp = e.cdemp;
select * from dependente d join emp e ;

select depto.nome nmdepto, emp.nome nmdepto
from depto, emp where depto.responsavel = emp.cdemp;


5.2 Subconsultas

5.2.1 Union
O SQL uma linguagem bastante flexvel e poderosa. Podemos usar sub-
consulta em diferentes situaes, um primeiro exemplo do uso do union. Para o union
as tabelas resultantes de cada sub-consulta devem ser compatveis de unio (isto , ter
os mesmos tipos de dados em cada coluna e na mesma ordem). Segue um exemplo.

(select * from pessoa where cdpessoa > 3)
union
(select * from pessoa where cdpessoa <= 3)
cdpessoa nome fone
4 Lobato 174590
5 Mateus
1 Obilac 260088
2 Silva 282677
3 Cabral 260088
5 row(s)

5.2.2 Select dentro de select
Outro uso comum de sub-consulta como valor escalar ou como sub-conjunto
(ou lista de valores). Seguem alguns exemplos de consultas simples que podem ser
combinada numa nica consulta complexa.

sql> select cdpessoa from pessoa where nome = 'OBilac' -> 1
sql> select turma from participante where pessoa = 1 -> ('A', 'B', 'C')
sql> select nome as nmtuma from turma where cdturma in ('A', 'B', 'C') -> /* tabela abaixo*/

select nome as nmtuma from turma
where cdturma in (select turma from participante
where pessoa in (select cdpessoa from pessoa where nome = \'OBilac\') )
nmtuma
Volei
Karate
Natao
3 row(s)

Isto mostra uma abordagem de refinamento passo-a-passo para desenvolver uma
consulta. Cada passo pode ser testado isoladamente e depois feita juno dos
pedaos numa consulta complexa.

UFPA Universidade Federal do Par
53
5.2.3 Tabela derivada
Podemos criar tabelas derivadas a partir de uma subconsulta. Uma tabela
derivada nomeada e a partir disso us-se o nome (alias) na consulta principal. Segue
um exemplo inicial.

select T.nmturma
from (select nome as nmturma from turma) as T
nmturma
Volei
Karate
Natao
3 row(s)

5.2.4 Self Join
Muitos bancos de dados tm tabelas que so auto-relacionamentos. Nestes casos
para mostrarmos os dados relativos ao auto-relacionamento precisamos de um tipo de
sub-consulta chamada self-join que utiliza uma mesma tabela com dois alias, como
segue:

select e.nome CHEFE, c.nome EMP
from emp c, emp e
where c.chefe=e.cdemp order by chefe
CHEFE EMP
Cabral OBilac
Lobato Maria
Maria Antune
Maria Petter
Silva Cabral
Silva Lobato
6 row(s)

Nesta consulta a tabela emp vista como de empregados ou de chefes. Pois os
chefes tambm so empregados.


UFPA Universidade Federal do Par
54

Fig. 5.2 Exemplo de um diagrama E-R com um auto-relacionamento: emp --(chefe)--> emp;

5.2.5 Funes de agregao e sub-consultas
No mdulo anterior vimos as funes de agregao. Agora mostramos como
explorar o potencial destas funes combinando-as com as sub-consultas. Dado o
esquema da base acima mostramos os dados das trs tabelas:

select * from emp
cdemp nome fone salario chefe depto
1 OBilac 2688 20000 3 S
2 Silva 2677 30000 H
3 Cabral 1088 22000 2 S
4 Lobato 4590 28000 2 H
8 Maria 2690 25000 4 C
9 Antune 2698 26000 8 C
10 Petter 2645 22000 8 C
7 row(s)

select * from depto
cddepto nome responsavel
C Computao 8
H Sede 2
S Seguranca 3
3 row(s)

select * from dependente
cdemp cddep nome
2 1 Jose
2 2 Ana
2 row(s)


Note que, a tabela emp(regado) acima pode ser vista como: (responsvel, chefe ou
empregado). Pense numa especializao: um empregado pode ser um responsvel pelo
departamento ou pode ser tambm um chefe. Num depto podem ter vrios chefes.

UFPA Universidade Federal do Par
55
Portanto, fica mais fcil trabalhar com trs alias: (r, c, e), respectivamente. Note
tambm que, para cada relacionamento devemos ter a sua expresso na clusula where.

Select d.nome DEPTO, r.nome RESP, c.nome CHEFE, e.nome EMP
from emp e, emp c, emp r, depto d
where e.chefe=c.cdemp and d.responsavel=r.cdemp and e.depto=d.cddepto
order by d.nome, r.nome, c.nome
DEPTO RESP CHEFE EMP
Computao Maria Lobato Maria
Computao Maria Maria Antune
Computao Maria Maria Petter
Sede Silva Silva Lobato
Seguranca Cabral Cabral OBilac
Seguranca Cabral Silva Cabral
6 row(s)

Nesta tabela podemos responder: Mostre quantos chefes tem em cada depto,
mostre com o nome do departamento? s tirar as tabelas que no so usadas:
responsvel e chefe (pois no precisa saber o nome do chefe).

Select d.nome nmdepto, count(e.chefe) from emp e, depto d
where e.depto=d.cddepto group by nmdepto order by d.nome
nmdepto count(e.chefe)
Computao 3
Sede 1
Seguranca 2
3 row(s)

Existem outras solues. Comeando s com a tabela depto, contando os chefes.
Depois acrescentar uma consulta na coluna para pegar o nome do depto.

select depto, count(chefe) from emp group by depto
depto count(chefe)
C 3
H 1
S 2
3 row(s)

select (select nome from depto where depto=cddepto) nmdepto,
count(chefe) from emp group by depto
nmdepto count(chefe)
Computao 3
Sede 1
Seguranca 2
3 row(s)


UFPA Universidade Federal do Par
56
Continuando nesta linha podemos responder: Qual depto com mais chefes?
fcil ver que Computao. Mas como fazer com o SQL. Acima mostramos como
contar com group by. Agora selecionamos o mximo daquela contagem.
Depois temos que selecionar o cdigo do depto usando group by e having
count() igual ao valor mximo j encontrado.

Select Max(s) from
(select depto d, count(cdemp) s from emp group by depto ) tab
Max(s)
3
1 row(s)

select nome from depto where cddepto =
(select depto from emp
group by depto having count(cdemp) =
(Select Max(s) from (select depto d, count(cdemp) s from emp group by
depto ) tab) )
nome
Computao
1 row(s)

Podemos tambm armazenar valores escalares temporrios em variveis. Veja a
mesma soluo abaixo.

sql> set @M = (select Max(s) from
(select depto d, count(cdemp) s from emp group by depto ) tab);
set @D = (select depto d from emp
group by depto having count(cdemp) = @M);
select nome from depto where cddepto=@D;


5.3 Consulta como expresso escalar
Se uma (sub)consulta retorna um valor escalar ela pode ser usada no lugar do
valor escalar. Alm disso, se usamos o operador IN podemos ter uma sub-consulta que
retorna uma tabela (preferencialmente uma coluna).
Segue um exemplo que retorna a quantidade de clientes existentes em cada par
(cidade, tipo de industria).

Select * ,
(Select Count(NOMECLIENTE) from cliente A
Where A.TIPOINDUSTRIA = B.TIPOINDUSTRIA and A.CIDADE = B.CIDADE ) as T
from cliente B
nomecliente cidade tipoindustria T
Abernathy Construction Willow B 1
Manchester Lumber Manchester F 1
Tri-City Builders Memphis B 2
Amalgamated Housing Memphis B 2
4 row(s)


UFPA Universidade Federal do Par
57
Existem uma forma mais simples e elegante de se obter um resultado similar,
como segue usando GROUP BY.

Select * , count(A.nomecliente) from cliente A group by A.tipoindustria, A.cidade
nomecliente cidade tipoindustria count(A.nomecliente)
Tri-City
Builders
Memphis B 2
Abernathy
Construction
Willow B 1
Manchester
Lumber
Manchester F 1
3 row(s)

5.3.1 Sub-consulta para correlacionar dados
Sub-consultas podem ser avaliadas de duas formas: a) uma nica vez durante a
consulta ou b) uma vez para cada linha do resultado da consulta, como se fosse um
JOIN entre o resultado da consulta e da sub-consulta.
O exemplo abaixo retorna o nome das pessoas que participam mais de uma
turma; a sub-consulta executada uma vez para cada linha da tabela A.

Select nome from pessoa A
Where (Select count(turma) from participante B Where A.cdpessoa = B.pessoa )>1
nome
Obilac
1 row(s)

5.3.2 Usando as clusulas EXISTS e NOT EXISTS.
Numa sub-consulta os operadores EXISTS e NOT EXISTS retornam TRUE ou
FALSE, conforme sejam ou no satisfeita a condio de ligao entre as tabelas
(resultados das consultas); caso pelo menos uma linha exista ento TRUE. A consulta
externa testa a existncia dos registros que a sub-consulta retorna, caso verdadeiro ento
retornada a linha externa.
Pode-se pensar como consultas independentes; para cada linha da tabela externa
a consulta interna executa; caso existam valores coincidentes (tipo equi-join) ento a
linha da externa retornada.
Esta consulta retorna o nome das turmas que o OBilac participa.

select nome as nmturma from turma A
where exists (select P.turma from participante P
where exists (select PE.cdpessoa from pessoa PE where nome = 'OBilac'))
nmturma
Volei
Karate
Natao
3 row(s)


UFPA Universidade Federal do Par
58
5.3.3 Usando ALL, SOME, ANY
Para trabalhar com sub-consultas (como sub-conjuntos) existem os operadores
ALL e ANY (ou SOME). SOME sinnimo de ANY. ALL fora a comparao ser
TRUE para todas as linhas da sub-consulta; j com ANY basta ser vlida para uma linha
da sub-consulta.

select nome as nmturma from turma A
where A.cdturma = any (select P.turma from participante P
where P.pessoa =any (select PE.cdpessoa from pessoa PE where nome = 'OBilac'))
nmturma
Volei
Karate
Natao
3 row(s)

Considerando os dados do BD de pessoa-particip-turma, listados abaixo, vamos
exemplificar o uso do ALL.

select t.nome turma, cdturma, pr.nome profe, pr.cdpessoa cdprof, al.nome aluno, al.cdpessoa cdal
from turma t, participante p, pessoa pr, pessoa al
where t.cdturma = p.turma and p.pessoa = al.cdpessoa and pr.cdpessoa=profe
turma cdturma profe cdprof aluno cdal
Volei A Lobato 4 Obilac 1
Volei A Lobato 4 Cabral 3
Karate B Lobato 4 Obilac 1
Natao C Silva 2 Obilac 1
Natao C Silva 2 Silva 2
5 row(s)

Queremos listar todos os alunos que no tem aula com o professor Lobato (4).
Seleciona-se as turmas dele via uma sub-consulta e depois usa-se o <> ALL para
mostrar o cdigo dos alunos.

sql> select T.cdturma from turma T where T.profe = 4 -> A B
sql> select P.pessoa from participante P
where P.turma <> all (select T.cdturma from turma T where T.profe = 4 ) -> 1 2

IN um alias para = ANY. Prefira sempre usar a palavra chave IN. Segue um
exemplo com duas consultas equivalentes:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
NOT IN um sinnimo para <> ALL. Seguem dois comandos equivalentes:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);

A palavra SOME um alias para ANY. Assim, ANY lido como ALGUM.
Seja t1=(10) e t2=(21,14,7). A consulta abaixo verdadeira.


UFPA Universidade Federal do Par
59
Agora seja t2=(20,10). A consulta abaixo falsa.
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 > SOME (SELECT s1 FROM t2);

5.4 Exerccios:
Discursivas:
1. O que um equi-join? (20 palavras)
2. Sejam duas tabelas relacionadas pela ligao entre chave primria e estrangeira.
O que traz um join natural? (20 palavras)
3. Sejam duas tabelas relacionadas pela ligao entre chave primria e estrangeira.
O que traz um outer join? (20 palavras)
4. Na hora de se escrever uma consulta com algum tipo de join, para que serve o
modelo de dados? (30 palavras)
5. O que so duas tabelas compatveis de unio? (20 palavras)
6. O que um self-join? (20 palavras)

F/V:
7. O inner join s retornam as linhas com a condio vlida (uma espcie de
interseo).
8. O outer join s retornam as linhas com a condio vlida (uma espcie de
interseo).
9. O outer join retornada todas as linhas de pelo menos uma das tabelas envolvidas
(uma especie de unio esquerda ou unio direita).
10. O inner join retornada todas as linhas de pelo menos uma das tabelas envolvidas
(uma especie de unio esquerda ou unio direita).
11. O full outer join equivalente a um left join mais um right join.
12. O full outer join equivalente a um join natural.
13. O join natural equivalente ao inner join.
14. possvel escrever um outer join implcito.
15. O cross join igual a um equi-join.
16. O cros join igual a um produto carteziano.
17. IN equivalente a = SOME.
18. IN equivalente a = ANY.
19. SOME alias de ANY.
20. NOT IN equivalente a <> ALL.

SQL:
21. Usando um join natural implcito mostre todos os professores com suas turma?
22. Usando um join natural explcito mostre todos os alunos com suas turmas?
23. Mostre os professores de cada aluno, s para alunos onde o cdpessoa > profe.
24. Mostre o nome da turma, do professor e a lista de alunos na mesma linha (use
group_concat)?
25. Usando as tabelas emp, depto e dependente. Mostre a lista de funcionrios de
cada depto, com o chefe. Uma linha para cada empregado.
26. Mostre a lista de funcionrios de cada depto, com o chefe. Todos empregados do
mesmo chefe na mesma linha.

UFPA Universidade Federal do Par
60
27. Mostre a lista de dependentes. Cada funcionrios com os seus dependentes. Um
dependente por linha. S liste o funcionrio que tem dependente.
28. Mostre a lista de dependentes. Cada funcionrios com os seus dependentes. Um
dependente por linha. Liste todos os funcionrios.
29. Mostre quantos dependentes tem cada emp.
30. Mostre os nomes dos deptos, dos responsveis, dos chefes e dos empregados.
31. Mostre os nomes dos deptos, dos responsveis, dos chefes, dos emp e dos
dependentes de cada empregado. Mostre todos tambm os emp que no tem
dependentes.
32. Mostre o depto que tem o maior salrio.
33. Mostre o depto que tem o menor salrio.
34. Mostre a media dos solrios de cada depto.
35. Mostre o depto que tem a menor mdia de salrio.
36. Mostre todos os funcionrios de cada depto que ganham acima da mdia; um
funcionrio por linha.
37. Mostre o depto que gasta mais com o pagamento de salrios.
38. Mostre o depto que gasta menos com o pagamento de salrios.
39. Mostre quantos chefes tem em cada depto, mostre com o nome do departamento.
40. Qual depto com mais empregados?
41. Mostre quantos emp tem cada chefe.
42. Quem o chefe que tem mais subordinados?
43. Quem o chefe que tem menos subordinados?
44. Mostre numa tabela, o depto, o responsvel com salrio, os empregados com
salrio (5 colunas).
45. Mostre quais so os funcionrios de cada depto que ganham mais que o
responsvel (5 colunas).

Você também pode gostar