Вы находитесь на странице: 1из 260

SQL - Mdulo I

COD.: TE 1586/1_WEB

SQL - Mdulo I

Crditos

Copyright TechnoEdition Editora Ltda.


Todos os direitos autorais reservados. Este manual no pode ser copiado,
fotocopiado, reproduzido, traduzido ou convertido em qualquer forma eletrnica,
ou legvel por qualquer meio, em parte ou no todo, sem a aprovao prvia, por
escrito, da TechnoEdition Editora Ltda., estando o contrafator sujeito a responder
por crime de Violao de Direito Autoral, conforme o art.184 do Cdigo Penal
Brasileiro, alm de responder por Perdas e Danos. Todos os logotipos e marcas
utilizados neste material pertencem s suas respectivas empresas.
As marcas registradas e os nomes comerciais citados nesta obra, mesmo que no sejam assim
identificados, pertencem aos seus respectivos proprietrios nos termos das leis, convenes e
diretrizes nacionais e internacionais.

SQL - Mdulo I
Coordenao Geral
Marcia M. Rosa
Coordenao Editorial
Henrique Thomaz Bruscagin
Superviso Editorial
Simone Rocha Arajo Pereira
Atualizao
Carlos Magno Pratico de Souza
Diagramao
Iv Lucino Camargo
Equipe de Apoio
Carolina A. Messias
Guilherme Yuji Kinoshita

Edio n 2 | cd.: 1586/1_WEB


Outubro/ 2013

Este material constitui uma nova obra e uma derivao da seguinte obra original,
produzida por TechnoEdition Editora Ltda., em Abr/2009:
SQL Server 2008 Mdulo I
Autoria: Alexandre Hideki Chicaoka, Athos Morais Valverde Junior, Carla Banci Cole,
Carlos Magno Pratico de Souza, Cristiana Hoffmann Pavan e Henrique Thomaz Bruscagin.

Sumrio

Informaes sobre o treinamento........................................................................................ 9


Captulo 1 Introduo ao SQL Server 2012................................................................... 11
1.1.
Banco de dados relacional...................................................................... 12
1.2.
As linguagens SQL e T-SQL..................................................................... 14
1.3.
Arquitetura cliente / servidor ................................................................ 15
1.4.
SQL Server.............................................................................................16
1.4.1. Componentes........................................................................................16
1.4.2. Ferramentas de gerenciamento.............................................................. 17
1.5.
SQL Server Management Studio (SSMS) .................................................. 18
1.5.1. Inicializando o SSMS...............................................................................19
1.5.2. Interface................................................................................................20
1.5.3. Executando um comando ...................................................................... 24
1.5.4. Salvando scripts.....................................................................................26
Pontos principais................................................................................................. 27
Teste seus conhecimentos ..................................................................................................... 29
Captulo 2 Criando um banco de dados......................................................................... 33
2.1.
Introduo.............................................................................................34
2.2.
CREATE DATABASE.................................................................................34
2.3.
CREATE TABLE.......................................................................................35
2.4.
Tipos de dados......................................................................................37
2.4.1. Numricos exatos..................................................................................37
2.4.2. Numricos aproximados........................................................................ 39
2.4.3. Data e hora............................................................................................40
2.4.4. Strings de caracteres ANSI...................................................................... 41
2.4.5. Strings de caracteres Unicode................................................................ 42
2.4.6. Strings binrias.....................................................................................43
2.4.7. Outros tipos de dados...........................................................................44
2.5.
Chave primria.......................................................................................44
2.6.
Campo de autonumerao (IDENTITY).................................................... 45
2.7.
Inserindo dados.....................................................................................45
2.7.1. INSERT posicional..................................................................................47
2.7.2. INSERT declarativo.................................................................................48
2.8.
Constantes.............................................................................................48
2.9.
Normalizao de dados.......................................................................... 52
2.9.1. Regras de normalizao......................................................................... 53
Pontos principais................................................................................................. 60
Teste seus conhecimentos ..................................................................................................... 61
Mos obra!................................................................................................................................... 69

SQL - Mdulo I

Captulo 3 Consultando dados........................................................................................... 73


3.1.
Introduo.............................................................................................74
3.2.
SELECT...................................................................................................78
3.2.1. Consultando todas as colunas................................................................ 80
3.2.2. Consultando colunas especficas............................................................ 80
3.2.3. Redefinindo os identificadores de coluna com uso de alias....................82
3.3.
Ordenando dados..................................................................................84
3.3.1. Retornando linhas na ordem ascendente................................................ 84
3.3.2. Retornando linhas na ordem descendente.............................................. 84
3.3.3. Ordenando por nome, alias ou posio.................................................. 85
3.3.4. ORDER BY com TOP................................................................................88
3.3.5. ORDER BY com TOP WITH TIES............................................................... 89
3.4.
Filtrando consultas................................................................................91
3.5.
Operadores relacionais.......................................................................... 91
3.6.
Operadores lgicos................................................................................93
3.7.
Consultando intervalos com BETWEEN.................................................... 95
3.8.
Consultando com base em strings de caractere......................................96
3.9.
Consultando valores pertencentes ou no a uma lista

de elementos.................................................................................. 99
3.10. Lidando com valores nulos..................................................................... 100
3.11. Substituindo valores nulos..................................................................... 102
3.11.1. ISNULL...................................................................................................102
3.11.2. COALESCE..............................................................................................103
3.12. Manipulando campos do tipo datetime................................................... 103
3.13. Alterando a configurao de idioma a partir do SSMS.............................114
Pontos principais................................................................................................. 118
Mos obra.!.................................................................................................................................. 119
Captulo 4 Atualizando e excluindo dados.................................................................... 125
4.1.
Introduo.............................................................................................126
4.2.
UPDATE.................................................................................................126
4.2.1. Alterando dados de uma coluna............................................................. 128
4.2.2. Alterando dados de diversas colunas..................................................... 129
4.3.
DELETE..................................................................................................130
4.3.1. Excluindo todas as linhas de uma tabela................................................ 131
4.4.
Transaes............................................................................................132
4.4.1. Transaes explcitas.............................................................................133
4.4.2. Clusula OUTPUT...................................................................................134
Pontos principais................................................................................................. 138
Mos obra!................................................................................................................................... 139

Sumrio

Captulo 5 Constraints e ndices........................................................................................ 143


5.1.
Constraints............................................................................................144
5.1.1. Nulabilidade..........................................................................................144
5.1.2. Modelo EntidadeRelacionamento (MER)................................................. 144
5.1.2.1. Relacionamento entre tabelas................................................................ 144
5.1.3. Tipos de constraints..............................................................................148
5.1.3.1. PRIMARY KEY (chave primria)................................................................ 148
5.1.3.2. UNIQUE..................................................................................................149
5.1.3.3. CHECK...................................................................................................150
5.1.3.4. DEFAULT................................................................................................151
5.1.3.5. FOREIGN KEY (chave estrangeira)............................................................ 152
5.1.4. Criando constraints................................................................................153
5.1.4.1. Criando constraints com CREATE TABLE................................................. 153
5.1.4.2. Criando constraints com ALTER TABLE................................................... 156
5.1.4.3. Criando constraints graficamente........................................................... 157
5.2.
ndices...................................................................................................166
5.2.1. Criando ndices......................................................................................168
5.2.2. Excluindo ndices...................................................................................169
Pontos principais................................................................................................. 170
Mos obra!................................................................................................................................... 171
Captulo 6 Associando tabelas........................................................................................... 181
6.1.
Introduo.............................................................................................182
6.2.
INNER JOIN.............................................................................................182
6.3.
OUTER JOIN............................................................................................189
6.4.
CROSS JOIN............................................................................................193
Pontos principais................................................................................................. 194
Mos obra!................................................................................................................................... 195
Captulo 7 Consultas com subqueries............................................................................ 199
7.1.
Introduo.............................................................................................200
7.2.
Principais caractersticas das subqueries................................................ 200
7.3.
Subqueries introduzidas com IN e NOT IN..............................................203
7.4.
Subqueries introduzidas com sinal de igualdade (=)...............................205
7.5.
Subqueries correlacionadas.................................................................... 205
7.5.1. Subqueries correlacionadas com EXISTS................................................. 206
7.6.
Diferenas entre subqueries e associaes.............................................207
7.7.
Diferenas entre subqueries e tabelas temporrias.................................208
Pontos principais................................................................................................. 211
Mos obra!................................................................................................................................... 213

SQL - Mdulo I

Captulo 8 Atualizando e excluindo dados em associaes



e subqueries............................................................................................. 215
8.1.
UPDATE com subqueries........................................................................ 216
8.2.
DELETE com subqueries......................................................................... 216
8.3.
UPDATE com JOIN..................................................................................217
8.4.
DELETE com JOIN...................................................................................217
Pontos principais................................................................................................. 218
Mos obra!................................................................................................................................... 219
Captulo 9 Agrupando dados............................................................................................. 223
9.1.
Introduo.............................................................................................224
9.2.
Funes de agregao............................................................................224
9.2.1. Tipos de funo de agregao................................................................ 225
9.3.
Funes de cadeia de caracteres............................................................ 228
9.4.
GROUP BY..............................................................................................232
9.4.1. Utilizando ALL........................................................................................235
9.4.2. Utilizando HAVING.................................................................................235
9.4.3. Utilizando WITH ROLLUP........................................................................ 236
9.4.4. Utilizando WITH CUBE............................................................................239
Pontos principais................................................................................................. 241
Mos obra!................................................................................................................................... 243
Apndice 1 - Outros recursos Outros recursos ............................................................. 247
1.1.
Funo CASE..........................................................................................248
1.2.
UNION...................................................................................................249
1.2.1. Utilizando UNION ALL............................................................................250
Apndice 2 - Resumo de objetos de um banco de dados

do SQL Server 2012 ......................................................................................... 251
2.1.
Objetos de banco de dados.................................................................... 252
2.1.1. Tabela....................................................................................................252
2.1.2. ndice.....................................................................................................252
2.1.3. Constraint..............................................................................................252
2.1.4. View......................................................................................................253
2.1.5. Procedure..............................................................................................254
2.1.6. Function................................................................................................255
2.1.7. Trigger..................................................................................................258

Informaes sobre o treinamento

Para que os alunos possam obter um bom aproveitamento


do curso SQL Mdulo I, imprescindvel que eles
tenham participado dos nossos treinamentos de Ambiente
Windows e Introduo Lgica de Programao,
ou possuam conhecimentos equivalentes.

Introduo ao
SQL Server 2012

99 Banco de dados relacional;


99 As linguagens SQL e T-SQL;
99 Arquitetura Cliente / Servidor;
99 SQL Server;
99 Componentes;
99 Ferramentas de gerenciamento;
99 SQL Server Management Studio.

SQL - Mdulo I

1.1.Banco de dados relacional


Um banco de dados uma forma organizada de armazenar informaes de
modo a facilitar sua insero, alterao, excluso e recuperao.
Um banco de dados relacional uma arquitetura na qual os dados so
armazenados em tabelas retangulares, semelhantes a uma planilha. Na maioria
das vezes estas tabelas possuem uma informao chave que as relaciona.
Observe as tabelas a seguir:
TABELA EMPREGADOS

TABELA CARGOS

12

Introduo ao SQL Server 2012

TABELA DEPARTAMENTOS

Podemos concluir que no seria lgico termos dois empregados ou dois


departamentos ou dois cargos com o mesmo cdigo. Isso porque cada
coluna CDIGO uma informao-chave, que identifica de forma nica cada
linha de uma tabela. Este tipo de coluna chamada de CHAVE PRIMRIA e,
embora no seja obrigatria, criar uma tabela sem esta informao poder
causar problemas futuros.
Observe que a tabela EMPREGADOS no armazena os nomes de cargo e
departamento, mas sim seus cdigos. Isso economiza espao e evita
redundncia. Para saber em qual departamento trabalha um empregado,
basta verificar o COD_DEPTO e busc-lo na tabela DEPARTAMENTOS. Uma
coluna de uma tabela que est relacionada chave primria de outra tabela
chamada de CHAVE ESTRANGEIRA.
Observe o seguinte diagrama relacional:
DIAGRAMA RELACIONAL

13

SQL - Mdulo I

1.2.As linguagens SQL e T-SQL


Toda a manipulao de um banco de dados feita atravs de uma linguagem
especfica, com uma exigncia sinttica rgida, chamada SQL (Structure Query
Language). Os fundamentos desta linguagem esto baseados no conceito de
banco de dados relacional.
Esta linguagem foi desenvolvida pela IBM no incio da dcada de 70 e,
posteriormente, foi adotada como linguagem padro pela ANSI (American
National Standard Institute) e pela ISO (International Organization for
Standardization), em 1986 e 1987, respectivamente.
A T-SQL (Transact-SQL) uma implementao da Microsoft para a SQL padro
ANSI. Ela cria opes adicionais para os comandos e tambm cria novos
comandos que permitem o recurso de programao, como os de controle de
fluxo, variveis de memria etc.

Alm da T-SQL, h outras implementaes da SQL, como Oracle PL/


SQL (Procedural Language/SQL) e IBMs SQL Procedural Language.
Veja um exemplo de comando SQL:

Resultado da execuo
do comando SELECT.

14

Introduo ao SQL Server 2012

1.3.Arquitetura cliente / servidor


A imagem a seguir ilustra a arquitetura cliente / servidor:

A
BANCO DE
DADOS

b
SISTEMA GERENCIADOR DE
BANCO DE DADOS (S.G.D.B.)

B
APLICAO CLIENTE

Cria um comando SQL (texto)


o envia ao S.G.B.D. e recebe o
retorno da instruo.

Em que:
A - Mquina servidora
a - Software servidor de banco de dados. ele que gerencia todo o
acesso ao banco de dados. Ele recebe os comandos SQL, verifica sua
sintaxe e os executa, enviando o retorno para a aplicao que enviou o
comando;
b - Banco de dados, incluindo as tabelas que sero manipuladas.
B - Mquina cliente
a - Aplicao contendo a interface visual que envia os comandos SQL ao
servidor.

15

SQL - Mdulo I
Essa arquitetura funciona da seguinte forma:
Usurios acessam o servidor atravs de um aplicativo instalado no prprio
servidor ou de outro computador;
O computador cliente executa as tarefas do aplicativo, ou seja, fornece a
interface do usurio (tela, processamento de entrada e sada) e manda uma
solicitao ao servidor;
O servidor de banco de dados processa a solicitao, que pode ser uma
consulta, alterao, excluso, incluso etc.

1.4.SQL Server
O SQL Server uma plataforma de banco de dados utilizada para armazenar
dados e process-los, tanto em um formato relacional quanto em documentos
XML. Tambm utilizada em aplicaes de comrcio eletrnico e atua como
uma plataforma inteligente de negcios para integrao e anlise de dados,
bem como de solues.
Para essas tarefas, o SQL Server faz uso da linguagem T-SQL para gerenciar
bancos de dados relacionais, que contm, alm da SQL, comandos de linguagem
procedural.

1.4.1.Componentes
O SQL Server oferece diversos componentes opcionais e ferramentas relacionadas
que auxiliam e facilitam na manipulao de seus sistemas. Por padro, nenhum
dos componentes ser instalado.
A seguir, descreveremos as funcionalidades oferecidas pelos principais
componentes do SQL Server:
SQL Server Database Engine: o principal componente do MS-SQL.
Recebe as instrues SQL, as executa e devolve o resultado para a aplicao
solicitante. Funciona como um servio no Windows e, normalmente,
iniciado juntamente com a inicializao do sistema operacional;
16

Introduo ao SQL Server 2012

Analysis Services: Usado para consultas avanadas, que envolvem muitas


tabelas simultaneamente, e para gerao de estruturas OLAP (On-Line
Analytical Processing);
Reporting Services:Ferramenta para gerao de relatrios;
Integration Services:Facilita o processo de transferncia de dados entre
bancos de dados.

1.4.2.Ferramentas de gerenciamento
A seguir, descreveremos as funcionalidades oferecidas pelas ferramentas de
gerenciamento disponveis no SQL Server e que trabalham associadas aos
componentes descritos anteriormente:
SQL Server Management Studio (SSMS)
um aplicativo usado para gerenciar bancos de dados, permite criar, alterar e
excluir objetos no banco de dados:

17

SQL - Mdulo I
SQL Server Configuration Manager
Permite visualizar, alterar e configurar os servios dos componentes do SQL Server:

Microsoft SQL Server Profiler


Essa ferramenta permite capturar e salvar dados de cada evento em um arquivo
ou tabela para anlise posterior.
Database Engine Tuning Advisor
Analisa o desempenho das operaes e sugere opes para sua melhora.
SQL Server Data Tools
Possui uma interface que integra os componentes Business Intelligence, Analysis
Services, Reporting Services e Integration Services.

1.5.SQL Server Management Studio


(SSMS)
Esta a principal ferramenta para gerenciamento de bancos de dados, por
isso, fundamental conhecer o seu funcionamento. Os prximos tpicos
apresentam como inicializar o SSMS, sua interface, como executar comandos
e como salvar scripts.

18

Introduo ao SQL Server 2012

1.5.1.Inicializando o SSMS
Para abrir o SQL Server Management Studio, siga os passos adiante:
1. Clique no boto Iniciar e selecione a opo Programas;
2. Selecione Microsoft SQL Server 2012 e, em seguida, SQL Server
Management Studio:

3. Na tela Connect to Database Engine, escolha a opo Windows


Authentication para o campo Authentication e, no campo Server Name,
especifique o nome do servidor com o qual ser feita a conexo:

19

SQL - Mdulo I
4. Clique no boto Connect. A interface do SQL Server Management Studio
ser aberta, conforme mostra a imagem a seguir:

1.5.2.Interface
A interface do SSMS composta pelo Object Explorer e pelo Code Editor,
explicados a seguir:
Object Explorer
uma janela que contm todos os elementos existentes dentro do seu servidor
MS-SQL Server no formato de rvore:

20

Introduo ao SQL Server 2012

Observe que a pasta Databases mostra todos os bancos de dados existentes


no servidor. No caso da imagem a seguir, PEDIDOS um banco de dados:

Expandindo o item PEDIDOS e depois o item Tables, veremos os nomes das


tabelas existentes no banco de dados:

Tabelas existentes
no banco de dados
PEDIDOS

21

SQL - Mdulo I

Expandindo uma das tabelas, veremos caractersticas da sua estrutura, como


as suas colunas:

Campos
(colunas)
da tabela

22

Introduo ao SQL Server 2012

Code Editor
O Code Editor (Editor de cdigo) do SQL Server Management Studio permite
escrever comandos T-SQL, MDX, DMX, XML/A e XML. Clicando no boto New
Query (Nova Consulta), ser aberta uma janela vazia para edio dos comandos.
Cada vez que clicarmos em New Query, uma nova aba vazia ser criada:

Nmero de sesso.

Cada uma dessas abas representa uma conexo com o banco de dados e recebe
um nmero de sesso. Cada conexo tem um nmero de sesso nico,
mesmo que tenha sido aberta pelo mesmo usurio com o mesmo login e senha.
Quando outra aplicao criada em outra linguagem, como Delphi, VB, C#, abrir
uma conexo, ela tambm receber um nmero nico de sesso.

23

SQL - Mdulo I

1.5.3.Executando um comando
Para executar um comando a partir do SQL Server Management Studio, adote o
seguinte procedimento:
1. Escreva o comando desejado no Code Editor. Enquanto um comando
digitado no Code Editor, o SQL Server oferece um recurso denominado
IntelliSense, que destaca erros de sintaxe e digitao, e fornece ajuda para
a utilizao de parmetros no cdigo. Ele est ativado por padro, mas pode
ser desativado. Para forar a exibio do IntelliSense, utilize CTRL + Barra de
espao:

2. Selecione o comando escrito. A seleo necessria apenas quando comandos


especficos devem ser executados, dentre vrios;

24

Introduo ao SQL Server 2012

3. Na barra de ferramentas do Code Editor, clique sobre o boto Execute


ou pressione a tecla F5 (ou CTRL + E) para que o comando seja executado. O
resultado do comando ser exibido na parte inferior da interface, conforme a
imagem a seguir:

Com relao ao procedimento anterior, importante considerar as seguintes


informaes:
possvel ocultar o resultado do comando por meio do atalho CTRL + R;
master um banco de dados de sistema, j vem instalado no MS-SQL Server;
Se mandar executar o comando e nada foi selecionado, todos os comandos
escritos no texto sero executados e, neste caso, eles precisam estar
organizados em uma sequencia lgica perfeita, seno ocorrero erros;
Quando salvamos o arquivo contido no editor, ele receber a extenso sql,
por padro. um arquivo texto e tambm conhecido como SCRIPT SQL.

25

SQL - Mdulo I

1.5.4.Salvando scripts
Para salvar os scripts utilizados, siga os passos adiante:
1. Acesse o menu File e clique em Save As:

2. Digite o nome escolhido para o script:

3. Clique em Save.

26

Introduo ao SQL Server 2012

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
Um banco de dados composto por tabelas;
Cada tabela possui vrias colunas de dados (campos);
Uma tabela precisa ter uma coluna que identifica de forma nica cada uma
de suas linhas. Esta coluna chamada de CHAVE PRIMRIA;
A coluna de uma tabela que se relaciona com a chave primria de outra
tabela chamada de CHAVE ESTRANGEIRA.

27

Introduo
ao SQL Server 2012
Teste seus conhecimentos

SQL - Mdulo I

1. Qual das alternativas a seguir um item composto por linhas e


colunas e responsvel pelo armazenamento de dados?

a) Campo
b) Chave primria
c) Chave estrangeira
d) Tabela
e) Banco de dados

2. Por qual outro nome conhecida uma coluna de uma tabela?

a) Campo
b) Chave primria
c) Chave estrangeira
d) Tabela
e) Banco de dados

30

Introduo ao SQL Server 2012

3. Qual das alternativas a seguir descreve o que uma chave


primria?

a) Uma linha de uma tabela.


b) Um campo de uma tabela que se relaciona com a chave primria
de outra tabela.
c) Um campo que identifica de forma nica cada uma das linhas da
tabela.
d) A primeira linha de uma tabela.
e) Uma senha de acesso ao banco de dados.

4. Qual das alternativas a seguir descreve o que uma chave


estrangeira?

a) Uma linha de uma tabela.


b) Um campo de uma tabela que se relaciona com a chave primria
de outra tabela.
c) Um campo que identifica de forma nica cada uma das linhas da
tabela.
d) A primeira linha de uma tabela.
e) Uma senha de acesso ao banco de dados.

31

Criando um
banco de dados

99 CREATE DATABASE;
99 CREATE TABLES;
99 Tipos de dados;
99 Chave primria;
99 Campo de autonumerao;
99 Inserindo dados;
99 Constantes;
99 Normalizao de dados.

SQL - Mdulo I

2.1.Introduo
Neste captulo, veremos os recursos iniciais para criao de banco de dados:
os comandos CREATE DATABASE e CREATE TABLE, os tipos de dados, as
constantes e como fazer a normalizao dos dados.
Quando formos mostrar as opes de sintaxe de um comando SQL, usaremos
a seguinte nomenclatura:
[]: Termos entre colchetes so opcionais;
<>: Termos entre os sinais menor e maior so nomes ou valores definidos
por ns;
{a1|a2|a3...}: Lista de alternativas mutuamente exclusivas.

2.2.CREATE DATABASE
Database um conjunto de arquivos que armazena todos os objetos do banco
de dados.
Para que um banco de dados seja criado no SQL Server, necessrio utilizar a
instruo CREATE DATABASE, cuja sintaxe bsica a seguinte:
CREATE DATABASE <nome_banco_de_dados>

A seguir, veja um exemplo de criao de banco de dados:


CREATE DATABASE SALA_DE_AULA;

Esta instruo criar dois arquivos:


SALA_DE_AULA.MDF: Armazena os dados;
SALA_DE_AULA_LOG.LDF: Armazena os logs de transaes.
Normalmente, estes arquivos esto localizados na pasta DATA dentro do
diretrio de instalao do SQL-Server.
34

Criando um banco de dados

Assim que so criados, os bancos de dados possuem apenas os objetos de


sistema, como tabelas, procedures, views, necessrios para o gerenciamento
das tabelas.
Para facilitar o acesso a um banco de dados, devemos coloc-lo em uso, mas isso
no obrigatrio. Para colocar um banco de dados em uso, utilize o seguinte
cdigo:
USE <nome_banco_de_dados>

Veja um exemplo:
USE SALA_DE_AULA

Observe que na parte superior esquerda do SSMS existe um


ComboBox que mostra o nome do banco de dados que est em uso.

2.3.CREATE TABLE
Os principais objetos de um banco de dados so suas tabelas, responsveis
pelo armazenamento dos dados.
A instruo CREATE TABLE deve ser utilizada para criar tabelas dentro de um
banco de dados j existente. A sintaxe para uso dessa instruo a seguinte:
CREATE TABLE <nome_tabela>
( <nome_campo1> <data_type> [IDENTITY [(<inicio>,<incremento>)]
[NOT NULL] [DEFAULT <exprDef>]
[, <nome_campo2> <data_type> [NOT NULL] [DEFAULT <exprDef>]

Em que:
<nome_tabela>: Nome que vai identificar a tabela. A princpio, nomes
devem comear por uma letra, seguida de letras, nmeros e sublinhados.
Porm, se o nome for escrito entre colchetes, poder ser ter qualquer
sequncia de caracteres;
35

SQL - Mdulo I
<nome_campo>: Nome que vai identificar cada coluna ou campo da tabela.
criado utilizando a regra para os nomes das tabelas;
<data_type>: Tipo de dado que ser gravado na coluna (texto, nmero,
data etc.);
[IDENTITY [(<inicio>,<incremento>)]:
autonumerao;

Define

um

campo

como

[NOT NULL]: Define um campo que precisa ser preenchido, isto , no


pode ficar vazio (NULL);
[DEFAULT <exprDef>]: Valor que ser gravado no campo, caso ele fique
vazio (NULL).
Com relao sintaxe de CREATE TABLE, importante considerar, ainda, as
seguintes informaes:
A sintaxe descrita foi simplificada, h outras clusulas na instruo CREATE
TABLE;
Uma tabela no pode conter mais de um campo IDENTITY;
Uma tabela no pode conter mais de uma chave primria, mas pode ter
uma chave primria composta por vrios campos.
A seguir, veja um exemplo de como criar uma tabela em um banco de dados:
CREATE TABLE ALUNOS
( NUM_ALUNO INT,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
FONE_RES CHAR(8),
FONE_COM CHAR(8),
FAX CHAR(8),
CELULAR CHAR(9),
PROFISSAO VARCHAR(40),
EMPRESA VARCHAR(50) );

A estrutura desta tabela no respeita as regras de normalizao de


dados. Adiante, corrigiremos este problema.
36

Criando um banco de dados

2.4.Tipos de dados
Cada elemento, como uma coluna, varivel ou expresso, possui um tipo de
dado. O tipo de dado especifica o tipo de valor que o objeto pode armazenar,
como nmeros inteiros, texto, data e hora, etc. O SQL Server organiza os tipos
de dados dividindo-os em categorias.
A seguir, sero descritas as principais categorias de tipos de dados utilizados
na linguagem Transact-SQL.

2.4.1.Numricos exatos
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Inteiros
Nome

Descrio

bigint
8 bytes

Valor de nmero inteiro compreendido entre


-2^63 (-9,223,372,036,854,775,808) e
2^63-1 (9,223,372,036,854,775,807).

int
4 bytes

Valor de nmero inteiro compreendido entre


-2^31 (-2,147,483,648) e 2^31 - 1 (2,147,483,647).

smallint
2 bytes

Valor de nmero inteiro compreendido entre


-2^15 (-32,768) e 2^15 - 1 (32,767).

tinyint
1 byte

Valor de nmero inteiro de 0 a 255.

Bit
Nome

Descrio

bit
1 byte

Valor de nmero inteiro com o valor 1 ou o valor 0.

37

SQL - Mdulo I

Numricos exatos
Nome

Descrio

decimal(<T>,<D>)

Valor numrico de preciso e escala fixas de


-10^38 +1 at 10^38 1.

numeric(<T>,<D>)

Valor numrico de preciso e escala fixas de


-10^38 +1 at 10^38 1.

Nos numricos exatos, importante considerar as seguintes informaes:


<T>: Corresponde quantidade mxima de algarismos que o nmero
pode ter;
<D>: Corresponde quantidade mxima de casas decimais que o
nmero pode ter;
A quantidade de casas decimais <D> est contida na quantidade mxima
de algarismos <T>;
A quantidade de bytes ocupada varia dependendo de <T>.
Valores monetrios

38

Nome

Descrio

money
8 bytes

Compreende valores monetrios ou de moeda


corrente
entre
-922.337.203.685.477,5808
e
922.337.203.685.477,5807.

smallmoney
4 bytes

Compreende valores monetrios ou de moeda corrente


entre -214,748.3648 e +214,748.3647.

Criando um banco de dados

2.4.2.Numricos aproximados
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Nome

Descrio

float[(n)]

Valor numrico de preciso flutuante entre


-1.79E + 308 e -2.23E - 308, 0 e de 2.23E + 308 at 1.79E + 308.

real
Valor numrico de preciso flutuante entre -3.40E + 38 e
o mesmo que
-1.18E - 38, 0 e de 1.18E - 38 at 3.40E + 38.
float(24)
Em que:
O valor de n determina a preciso do nmero. O padro (default) 53;
Se n est entre 1 e 24, a preciso de 7 algarismos e ocupa 4 bytes de
memria. Com n entre 25 e 53, a preciso de 15 algarismos e ocupa 8
bytes.

Esses tipos so chamados de Numricos aproximados porque


podem gerar impreciso na parte decimal.

39

SQL - Mdulo I

2.4.3.Data e hora
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Nome

Descrio

datetime
8 bytes

Data e hora compreendidas entre 1 de Janeiro de 1753


e 31 de Dezembro de 9999, com a exatido de 3.33
milissegundos.

smalldatetime
4 bytes

Data e hora compreendidas entre 1 de Janeiro de 1900


e 6 de Junho de 2079, com a exatido de 1 minuto.

datetime2[(p)]
8 bytes

Data e hora compreendidas entre 01/01/0001 e


31/12/9999 com preciso de at 100 nanossegundos,
dependendo do valor de p, que representa a quantidade
de algarismos na frao de segundo. Omitindo p, o valor
default ser 7.

date
3 bytes

Data compreendida entre 01/01/0001 e 31/12/9999,


com preciso de 1 dia.

time[(p)]
5 bytes

Hora
no
intervalo
de
00:00:00.0000000
a
23.59.59.9999999. O parmetro p indica a quantidade
de dgitos na frao de segundo.

Data e hora compreendidas entre 01/01/0001 e


31/12/9999 com preciso de at 100 nanossegundos e
Datetimeoffset[(p)] com indicao do fuso horrio, cujo intervalo pode variar
de - 14:00 a + 14:00. O parmetro p indica a quantidade
de dgitos na frao de segundo.

40

Criando um banco de dados

2.4.4.Strings de caracteres ANSI


chamada de string uma sequncia de caracteres. No padro ANSI, cada
caractere armazenado em 1 byte, o que permite a codificao de at 256
caracteres.
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Nome

Descrio

char(<n>)

Comprimento fixo de no mximo 8.000 caracteres no padro


ANSI. Cada caractere armazenado em 1 byte.

varchar(<n>)

Comprimento varivel de no mximo 8.000 caracteres no


padro ANSI. Cada caractere armazenado em 1 byte.

text ou
varchar(max)

Comprimento varivel de no mximo 2^31 - 1 (2,147,483,647)


caracteres no padro ANSI. Cada caractere armazenado em
1 byte.

Em que:
<n>: Representa a quantidade mxima de caracteres que poderemos
armazenar. Cada caractere ocupa 1 byte.

recomendvel a utilizao do tipo varchar(max) em vez do tipo


text. Este ltimo ser removido em verses futuras do SQL Server.
No caso de aplicaes que j o utilizam, indicado realizar a
substituio pelo tipo recomendado. Ao utilizarmos max para varchar,
estamos ampliando sua capacidade de armazenamento para 2 GB,
aproximadamente.

41

SQL - Mdulo I

2.4.5.Strings de caracteres Unicode


Em strings Unicode, cada caractere armazenado em 2 bytes, o que amplia a
quantidade de caracteres possveis para mais de 65000.
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Nome

Descrio

nchar(<n>)

Comprimento fixo de no mximo 4.000 caracteres Unicode.

nvarchar(<n>)

Comprimento varivel de no mximo 4.000 caracteres


Unicode.

ntext ou
Comprimento varivel de no mximo 2^30 - 1 (1,073,741,823)
nvarchar(max) caracteres Unicode.
Em que:
<n>: Representa a quantidade mxima de caracteres que poderemos
armazenar. Cada caractere ocupa 2 bytes. Essa quantidade de 2 bytes
destinada a pases cuja quantidade de caracteres utilizados muito grande,
como Japo e China.

Tanto no padro ANSI quanto no UNICODE, existe uma tabela (ASCII)


que codifica todos os caracteres. Esta tabela usada para converter o
caractere no seu cdigo, quando gravamos, e para converter o cdigo
no caractere quando lemos.

42

Criando um banco de dados

2.4.6.Strings binrias
No caso das strings binrias, no existe uma tabela para converter os caracteres,
voc interpreta os bits de cada byte de acordo com uma regra sua.
A tabela a seguir descreve alguns dos tipos de dados que fazem parte dessa
categoria:
Nome

Descrio

binary(<n>)

Dado binrio com comprimento fixo de no mximo 8.000


bytes.

varbinary(<n>)

Dado binrio com comprimento varivel, de no mximo


8.000 bytes.

image ou
Dado binrio com comprimento varivel de no mximo
varbinary(max) 2^31 - 1 (2,147,483,647) bytes.

Os tipos image e varbinary(max) so muito usados para importar


arquivos binrios para dentro do banco de dados. Imagens, sons ou
qualquer outro tipo de documento podem ser gravados em um campo
desses tipos. recomendvel a utilizao do tipo varbinary(max)
em vez do tipo image. Este ltimo ser removido em verses futuras
do SQL Server. No caso de aplicaes que j o utilizam, indicado
realizar a substituio pelo tipo recomendado.

43

SQL - Mdulo I

2.4.7.Outros tipos de dados


Essa categoria inclui tipos de dados especiais, cuja utilizao especfica e
restrita a certas situaes. A tabela adiante descreve alguns desses tipos:
Nome

Descrio

table

Serve para definir um dado tabular, composto de linhas e


colunas, assim como uma tabela.

cursor

Serve para percorrer as linhas de um dado tabular.

sql_variant

Um tipo de dado que armazena valores de vrios tipos


suportados pelo SQL Server, exceto os seguintes: text,
ntext, timestamp e sql_variant.

Timestamp ou
RowVersion

Nmero hexadecimal sequencial gerado automaticamente.

Globally Unique Identifier (GUID), tambm conhecido como


Identificador nico Global ou Identificador nico Universal.
uniqueidentifier
um nmero hexadecimal de 16 bytes semelhante a
64261228-50A9-467C-85C5-D73C51A914F1.

2.5.Chave primria
Uma chave primria identifica de forma nica cada linha de uma tabela. Veja um
exemplo:
DROP TABLE ALUNOS;
CREATE TABLE ALUNOS
(
NUM_ALUNO
INT PRIMARY KEY,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
FONE_RES CHAR(8),
FONE_COM CHAR(8),
FAX CHAR(8),
CELULAR CHAR(9),
PROFISSAO VARCHAR(40),
EMPRESA VARCHAR(50) );

44

Criando um banco de dados

2.6.Campo de autonumerao (IDENTITY)


A coluna de identidade, ou campo de autonumerao, definida pela propriedade
IDENTITY. Ao atribumos essa propriedade a uma coluna, o SQL Server cria
nmeros em sequncia para linhas que forem posteriormente inseridas na
tabela em que a coluna de identidade est localizada.
importante saber que uma tabela pode ter apenas uma coluna do tipo identidade
e que no possvel inserir ou alterar seu valor, que gerado automaticamente
pelo SQL-Server.
Veja um exemplo:
DROP TABLE ALUNOS;
CREATE TABLE ALUNOS
(
NUM_ALUNO
INT IDENTITY PRIMARY KEY,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
FONE_RES CHAR(8),
FONE_COM CHAR(8),
FAX CHAR(8),
CELULAR CHAR(9),
PROFISSAO VARCHAR(40),
EMPRESA VARCHAR(50) );

2.7.Inserindo dados
Para acrescentar novas linhas de dados em uma tabela, utilize o comando
INSERT, que possui a seguinte sintaxe:
INSERT [INTO] <nome_tabela>
[ ( <lista_de_colunas> ) ]
{ VALUES ( <lista_de_expressoes1> )
[, (<lista_de_expressoes2>)] [,...] |
<comando_select> }

45

SQL - Mdulo I

Em que:
<lista_de_colunas>: uma lista de uma ou mais colunas que recebero
dados. Os nomes das colunas devem ser separados por vrgula e a lista
deve estar entre parnteses;
VALUES (<lista_de_espressoes>): Lista de valores que sero inseridos em
cada uma das colunas especificadas em <lista_de_colunas>.
Para inserir uma nica linha em uma tabela, o cdigo o seguinte:
INSERT INTO ALUNOS
(NOME, DATA_NASCIMENTO, IDADE, E_MAIL,
FONE_RES, FONE_COM,FAX, CELULAR,
PROFISSAO, EMPRESA )
VALUES
(CARLOS MAGNO, 1959.11.12, 53, magno@magno.com,
23456789,23459876,, 998765432,
ANALISTA DE SISTEMAS, IMPACTA TECNOLOGIA);
-- Consultando os dados inseridos na tabela
SELECT * FROM ALUNOS;

Podemos inserir vrias linhas em uma tabela com o uso de vrios comandos
INSERT ou um nico:
INSERT INTO ALUNOS
(NOME, DATA_NASCIMENTO, IDADE, E_MAIL,
FONE_RES, FONE_COM, FAX, CELULAR,
PROFISSAO, EMPRESA)
VALUES
(Andr da Silva, 1980.1.2, 33, andre@silva.com,
23456789,23459876,, 998765432,
ANALISTA DE SISTEMAS, SOMA INFORMTICA),
(Marcelo Soares, 1983.4.21, 30, marcelo@soares.com,
23456789,23459876,, 998765432,
INSTRUTOR, IMPACTA TECNOLOGIA);
-- Consultando os dados da tabela
SELECT * FROM ALUNOS;

46

Criando um banco de dados

Podemos tambm fazer INSERT de SELECT:


CREATE TABLE ALUNOS2
( NUM_ALUNO INT,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
FONE_RES CHAR(8),
FONE_COM CHAR(8),
FAX CHAR(8),
CELULAR CHAR(9),
PROFISSAO VARCHAR(40),
EMPRESA VARCHAR(50) );
INSERT INTO ALUNOS2
SELECT * FROM ALUNOS;

No necessrio determinar os nomes das colunas na sintaxe do comando


INSERT quando os valores forem inseridos na mesma ordem fsica das colunas
no banco de dados. J para valores inseridos aleatoriamente, preciso especificar
exatamente a ordem das colunas. Esses dois modos de utilizao do comando
INSERT so denominados INSERT posicional e INSERT declarativo.

2.7.1.INSERT posicional
O comando INSERT classificado como posicional quando no especifica a lista
de colunas que recebero os dados de VALUES. Neste caso, a lista de valores
precisa conter todos os campos, exceto o IDENTITY, na ordem fsica em que
foram criadas no comando CREATE TABLE. Veja o exemplo a seguir:
INSERT INTO ALUNOS
VALUES
(MARIA LUIZA, 1997.10.29, 15, luiza@luiza.com,
23456789,23459876,, 998765432,
ESTUDANTE, COLGIO MONTE VIDEL);
-- Consultando os dados
SELECT * FROM ALUNOS;

47

SQL - Mdulo I

2.7.2.INSERT declarativo
O INSERT classificado como declarativo quando especifica as colunas que
recebero os dados da lista de valores. Veja o prximo exemplo:
INSERT INTO ALUNOS
(NOME, DATA_NASCIMENTO, IDADE, E_MAIL,
FONE_RES, FONE_COM,FAX, CELULAR,
PROFISSAO, EMPRESA )
VALUES
(PEDRO PAULO, 1994.2.5, 19, pedro@pedro.com,
23456789,23459876,, 998765432,
ESTUDANTE, COLGIO MONTE VIDEL);
-- Consultando os dados
SELECT * FROM ALUNOS;

Quando utilizamos a instruo INSERT dentro de aplicativos, stored procedures


ou triggers, deve ser o INSERT declarativo, pois, se houver alterao na estrutura
da tabela (incluso de novos campos), ele continuar funcionando, enquanto
que o INSERT posicional provocar erro.

2.8.Constantes
As constantes, ou literais, so informaes fixas, como o nome sugere, que no
se alteram no decorrer do tempo. Por exemplo, o seu nome escrito no papel
uma constante e a sua data de nascimento outra constante. Existem regras
para escrever constantes no SQL:
Constantes de cadeia de caracteres (CHAR e VARCHAR)
So sequncias compostas por quaisquer caracteres existentes no teclado. Este
tipo de constante deve ser escrita entre apstrofos:
IMPACTA TECNOLOGIA, SQL-SERVER, XK-1808/2,
CAIXA DAGUA

48

Criando um banco de dados

Se o contedo do texto possuir o caractere apstrofo, ele deve ser colocado


duas vezes, como mostrado em CAIXA DAGUA.
Cadeias de caracteres Unicode
Semelhante ao caso anterior, estas constantes devem ser precedidas pela letra
maiscula N (identificador):
NIMPACTA TECNOLOGIA, NSQL-SERVER, NXK-1808/2

Constantes binrias
So cadeias de nmeros hexadecimais e apresentam as seguintes caractersticas:
No so includas entre aspas;
Possuem o prefixo 0x.
Veja um exemplo:
0xff, 0x0f, 0x01a0

Constantes datetime
Utilizam valores de data includos em formatos especficos. Devem ser includos
entre aspas simples:
2009.1.15, 20080115, 01/15/2008, 22:30:10, 2009.1.15
22:30:10

O formato da data pode variar dependendo de configuraes do SQL. Podemos


tambm utilizar o comando SET DATEFORMAT para definir o formato durante
uma seo de trabalho.

49

SQL - Mdulo I

Constantes bit
No includas entre aspas, as constantes bit so representadas por 0 ou 1. Uma
constante desse tipo ser convertida em 1 caso um nmero maior do que 1 seja
utilizado.
0, 1

Constantes float e real


So constantes representadas por notao cientfica:
2.53E4
2.53 x 104
4.5E-2
4.5 / 102

2.53 x 10000 25300


4.5 / 100
0.045

Constantes integer
So representadas por uma cadeia de nmeros sem pontos decimais e no
includos entre aspas. As constantes integer no aceitam nmeros decimais,
somente nmeros inteiros:
1528
817215
5

Nunca utilize o separador de milhar.

50

Criando um banco de dados

Constantes decimal
So representadas por cadeias numricas com ponto decimal e no includas
entre aspas:
162.45
5.78

O separador decimal sempre ser o ponto, independente de


configuraes regionais do Windows.
Constantes uniqueidentifier
uma cadeia de caracteres que representa um GUID. Pode ser especificada
como uma cadeia de binrios ou em um formato de caracteres, veja:
0xff19966f868b11d0b42d00c04fc964ff
6F9619FF-8B86-D011-B42D-00C04FC964FF

Constantes money
So precedidas pelo caractere cifro ($). Este tipo de dado sempre reserva 4
posies para a parte decimal. Os algarismos alm da quarta casa decimal sero
desprezados.
$1543.56
$12892.6534
$56.275639

No ltimo exemplo, ser armazenado apenas 56.2756.

51

SQL - Mdulo I

2.9. Normalizao de dados


O processo de organizar dados e eliminar informaes redundantes de um
banco de dados denominado normalizao.
A normalizao envolve a tarefa de criar as tabelas e definir os seus
relacionamentos. O relacionamento entre as tabelas criado de acordo com
regras que visam proteo dos dados e eliminao de dados repetidos.
Essas regras so denominadas normal forms ou formas normais.
A normalizao apresenta grandes vantagens:
Elimina dados repetidos, o que torna o banco mais compacto;
Garante o armazenamento dos dados de forma lgica;
Maior velocidade dos processos de classificar e indexar, j que as tabelas
possuem uma quantidade menor de colunas;
Permite o agrupamento de ndices conforme a quantidade de tabelas
aumenta. Alm disso, reduz o nmero de ndices por tabela. Dessa forma,
permite melhor performance de atualizao do banco de dados.
Entretanto, o processo de normalizao pode aumentar a quantidade de tabelas
e, consequentemente, a complexidade das associaes exigidas entre elas
para que os dados desejados sejam obtidos. Isso pode acabar prejudicando o
desempenho da aplicao.
Outro aspecto negativo da normalizao que as tabelas, em vez de dados
reais, podem conter cdigos. Nesse caso, ser necessrio recorrer tabela
de pesquisa para obter os valores necessrios. A normalizao tambm pode
dificultar a consulta ao modelo de dados.

52

Criando um banco de dados

2.9.1.Regras de normalizao
A normalizao inclui 3 regras principais: first normal form (1NF), second
normal form (2NF) e third normal form (3NF).
Consideramos que um o banco de dados est no first normal form quando a
primeira regra (1NF) cumprida. Se as trs regras forem cumpridas, o banco de
dados estar no third normal form.

possvel atingir outros nveis de normalizao (4NF e 5NF),


entretanto, o 3NF considerado o nvel mais alto requerido pela
maior parte das aplicaes.

Veja quais as regras que devem ser cumpridas para atingir cada nvel de
normalizao:
First Normal Form (1NF)
Para que um banco de dados esteja nesse nvel de normalizao, cada coluna
deve conter um nico valor e cada linha deve abranger as mesmas colunas. A
fim de atendermos a esses aspectos, os conjuntos que se repetem nas tabelas
individuais devem ser eliminados. Alm disso, devemos criar uma tabela
separada para cada conjunto de dados relacionados e identificar cada um deles
com uma chave primria.

53

SQL - Mdulo I

Uma tabela sempre ter esse formato:


CAMPO 1 CAMPO 2 CAMPO 3 CAMPO 4

E nunca poder ter esse formato:


CAMPO 1

CAMPO 2

CAMPO 3

CAMPO 4

Considere os seguintes exemplos:


Uma pessoa tem apenas um nome, um RG, um CPF, mas pode ter estudado
em N escolas diferentes e pode ter feito N cursos extracurriculares;
Um treinamento da Impacta tem um nico nome, tem uma nica carga
horria, mas pode haver N instrutores que ministram este treinamento;
Um aluno da Impacta tem apenas um nome, um RG, um CPF, mas pode
ter N telefones.
Percebemos aqui que a tabela ALUNOS, que criamos anteriormente, precisa ser
reestruturada para que respeite a primeira forma normal.

54

Criando um banco de dados

Sempre que uma linha de uma tabela tiver N informaes relacionadas a ela,
precisaremos criar outra tabela para armazenar essas N informaes:
DROP TABLE ALUNOS;
CREATE TABLE ALUNOS
(
NUM_ALUNO
INT IDENTITY PRIMARY KEY,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
PROFISSAO VARCHAR(40),
EMPRESA VARCHAR(50) );
CREATE TABLE FONES
( NUM_ALUNO INT,
FONE CHAR(9),
TIPO VARCHAR(15),
PRIMARY KEY (NUM_ALUNO, FONE) ) ;

No caso da tabela FONES, a chave primria formada por dois campos, NUM_
ALUNO e FONE. Isso impedir que se cadastre o mesmo telefone mais de uma
vez para o mesmo aluno:
INSERT INTO ALUNOS
(NOME, DATA_NASCIMENTO, IDADE, E_MAIL,
PROFISSAO, EMPRESA )
VALUES
(CARLOS MAGNO, 1959.11.12, 53, magno@magno.com,
ANALISTA DE SISTEMAS, IMPACTA TECNOLOGIA),
(Andr da Silva, 1980.1.2, 33, andre@silva.com,
ANALISTA DE SISTEMAS, SOMA INFORMTICA),
(Marcelo Soares, 1983.4.21, 30, marcelo@soares.com,
INSTRUTOR, IMPACTA TECNOLOGIA),
(PEDRO PAULO, 1994.2.5, 19, pedro@pedro.com,
ESTUDANTE, COLGIO MONTE VIDEL),
(MARIA LUIZA, 1997.10.29, 15, luiza@luiza.com,
ESTUDANTE, COLGIO MONTE VIDEL) ;

55

SQL - Mdulo I

INSERT INTO FONES


( NUM_ALUNO, FONE, TIPO )
VALUES
( 1,28739988,RESIDENDIAL),
( 1,68336989,COMERCIAL),
( 1,991259976,CELULAR),
( 2,992736266,CELULAR),
( 3,52417262,COMERCIAL),
( 3,998271717,CELULAR),
( 5,77162525,RESIDENDIAL);

Second Normal Form (2NF)


No segundo nvel de normalizao, devemos criar tabelas separadas para
conjuntos de valores que se aplicam a vrios registros, ou seja, que se repetem.
Com a finalidade de criar relacionamentos, devemos relacionar essas novas
tabelas com uma chave estrangeira e identificar cada grupo de dados relacionados
com uma chave primria.
Em outras palavras, a segunda forma normal pede que evitemos campos
descritivos (alfanumricos) que se repitam vrias vezes na mesma tabela.
Alm de ocupar mais espao, a mesma informao pode ser escrita de formas
diferentes. Veja o caso da tabela ALUNOS, em que existe um campo chamado
PROFISSAO (descritivo) onde possvel grafarmos a mesma profisso de vrias
formas diferentes:
ANALISTA DE SISTEMAS
ANALISTA SISTEMAS
AN. SISTEMAS
AN. DE SISTEMAS
ANALISTA DE SIST.

56

Criando um banco de dados

Isso torna impossvel que se gere um relatrio filtrando os ALUNOS por


PROFISSAO. A soluo, neste caso, criar uma tabela de profisses em que
cada profisso tenha um cdigo. Para isso, na tabela ALUNOS, substituiremos o
campo PROFISSAO por COD_PROFISSAO:
DROP TABLE ALUNOS;
CREATE TABLE ALUNOS
(
NUM_ALUNO
INT IDENTITY PRIMARY KEY,
NOME VARCHAR(30),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT,
E_MAIL VARCHAR(50),
COD_PROFISSAO INT,
COD_EMPRESA INT );
CREATE TABLE PROFISSOES
( COD_PROFISSAO INT IDENTITY PRIMARY KEY,
PROFISSAO
VARCHAR(30) );
INSERT INTO PROFISSOES
( PROFISSAO )
VALUES (ANALISTA DE SISTEMAS), (INSTRUTOR), (ESTUDANTE);
SELECT * FROM PROFISSOES;
CREATE TABLE EMPRESAS
( COD_EMPRESA
INT IDENTITY PRIMARY KEY,
EMPRESA
VARCHAR(50) );

57

SQL - Mdulo I

INSERT INTO EMPRESAS


( EMPRESA )
VALUES (IMPACTA TECNOLOGIA),(SOMA INFORMTICA), (COLGIO
MONTE VIDEL);
SELECT * FROM EMPRESAS;
INSERT INTO ALUNOS
(NOME, DATA_NASCIMENTO, IDADE, E_MAIL,
COD_PROFISSAO, COD_EMPRESA )
VALUES
(CARLOS MAGNO, 1959.11.12, 53, magno@magno.com,
1, 1),
(Andr da Silva, 1980.1.2, 33, andre@silva.com,
1, 2),
(Marcelo Soares, 1983.4.21, 30, marcelo@soares.com,
2, 1),
(PEDRO PAULO, 1994.2.5, 19, pedro@pedro.com,
3, 3),
(MARIA LUIZA, 1997.10.29, 15, luiza@luiza.com,
3, 3);

Third Normal Form (3NF)


No terceiro nvel de normalizao, aps ter concludo todas as tarefas do 1NF
e 2NF, devemos eliminar os campos que no dependem de chaves primrias.
Cumpridas essas trs regras, atingimos o nvel de normalizao requerido pela
maioria dos programas.

58

Criando um banco de dados

Considere os seguintes exemplos:


Em uma tabela de PRODUTOS, que tenha os campos PRECO_COMPRA
e PRECO_VENDA, no devemos ter um campo LUCRO, pois ele no
depende do cdigo do produto (chave primria), mas sim dos preos de
compra e de venda. O lucro ser facilmente gerado atravs da expresso
PRECO_VENDA PRECO_CUSTO;
Na tabela ALUNOS, no devemos ter o campo IDADE, pois ela no
depende do nmero do aluno (chave primria), mas sim do campo
DATA_NASCIMENTO.
-- Eliminar o campo IDADE da tabela ALUNOS
ALTER TABLE ALUNOS DROP COLUMN IDADE;
-- Calcular a IDADE do ALUNO
SELECT *,
CAST((GETDATE() - DATA_NASCIMENTO) AS FLOAT)/365.25 AS IDADE
FROM ALUNOS;

Por fim, o banco de dados SALA_DE_AULA ficou com a seguinte estrutura:

59

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
Os objetos que fazem parte de um sistema so criados dentro de um objeto
denominado database, ou seja, uma estrutura lgica formada por dois
tipos de arquivo, um responsvel pelo armazenamento de dados e outro
que armazena as transaes feitas. Para que um banco de dados seja criado
no SQL Server, necessrio utilizar a instruo CREATE DATABASE;
Os dados de um sistema so armazenados em objetos denominados
tabelas (table). Cada uma das colunas de uma tabela refere-se a um atributo
associado a uma determinada entidade. A instruo CREATE TABLE deve
ser utilizada para criar tabelas dentro de bancos de dados j existentes;
Cada elemento, como uma coluna, uma varivel ou uma expresso possui
um tipo de dado. O tipo de dado especifica o tipo de valor que o objeto
pode armazenar, como nmeros inteiros, texto, data e hora, etc.;
Normalmente, as tabelas possuem uma coluna contendo valores capazes
de identificar uma linha de forma exclusiva. Essa coluna recebe o nome
de chave primria, cuja finalidade assegurar a integridade dos dados
da tabela;
Para acrescentar novas linhas de dados em uma tabela, utilizamos o comando
INSERT;
O processo de organizar dados e eliminar informaes redundantes de
um banco de dados denominado normalizao. Envolve a tarefa de criar
as tabelas, bem como definir relacionamentos. O relacionamento entre as
tabelas criado de acordo com regras que visam proteo dos dados e
eliminao de dados repetidos. Essas regras so denominadas normal
forms, ou formas normais.

60

Criando um
banco de dados

Teste seus conhecimentos

SQL - Mdulo I
1. Qual dos comandos a seguir cria um banco de dados chamado VENDAS?

a) CREATE TABLE VENDAS


b) CREATE NEW DATA VENDAS
c) CREATE VENDAS DATABASE
d) CREATE DATABASE VENDAS
e) NEW DATABASE VENDAS

2. Qual das alternativas possui uma afirmao correta a respeito do


seguinte cdigo?
CREATE TABLE ALUNOS
(

COD_ALUNO
INT IDENTITY
NOME VARCHAR(40),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT
)

PRIMARY KEY,

a) A coluna NOME armazenar sempre 40 caracteres, independente


do nome inserido nela.
b) A coluna DATA_NACIMENTO poder armazenar datas desde o
ano 0001 at 9999.
c) A coluna NOME armazenar no mximo 40 caracteres, ocupando
apenas a quantidade de caracteres contida no nome inserido nela.
d) A coluna IDADE poder armazenar nmeros inteiros no intervalo
de -255 at +255.
e) A coluna COD_ALUNO poder armazenar nmeros inteiros de
-32000 at +32000.

62

Criando um banco de dados

3. Qual das alternativas possui uma afirmao correta a respeito do


seguinte cdigo?
CREATE TABLE ALUNOS
(

COD_ALUNO
INT IDENTITY
NOME VARCHAR(40),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT
)

PRIMARY KEY,

a) A coluna COD_ALUNO ser numerada automaticamente pelo SQLSERVER.


b) A coluna DATA_NACIMENTO poder armazenar datas desde o
ano 0001 at 9999.
c) Ocorrer erro na definio da coluna COD_ALUNO porque no
existe um tipo chamado INT, o correto INTEGER.
d) A coluna IDADE poder armazenar nmeros inteiros no intervalo
de -255 at +255.
e) A coluna COD_ALUNO poder armazenar nmeros inteiros de
-32000 at +32000.

63

SQL - Mdulo I

4. Qual das alternativas possui uma afirmao correta a respeito do


seguinte cdigo?
CREATE TABLE ALUNOS
(

COD_ALUNO
INT IDENTITY
NOME VARCHAR(40),

DATA_NASCIMENTO DATETIME,
IDADE TINYINT
)

PRIMARY KEY,

a) A coluna DATA_NACIMENTO poder armazenar datas desde o


ano 0001 at 9999.
b) De acordo com as regras de normalizao, a coluna IDADE no
deveria fazer parte da estrutura da tabela, pois decorrente de um
clculo envolvendo o campo DATA_NASCIMENTO.
c) Ocorrer erro na definio da coluna COD_ALUNO porque no
existe um tipo chamado INT, o correto INTEGER.
d) A coluna IDADE poder armazenar nmeros inteiros no intervalo
de -255 at +255.
e) A coluna COD_ALUNO poder armazenar nmeros inteiros de
-32000 at +32000.

64

Criando um banco de dados

5. Qual dos comandos adiante insere uma linha com dados na tabela
chamada ALUNOS, admitindo que a configurao de formato de data
seja yyyy.mm.dd?
CREATE TABLE ALUNOS
COD_ALUNO
INT IDENTITY
PRIMARY KEY,
NOME VARCHAR(40),

DATA_NASCIMENTO DATETIME,

E_MAIL VARCHAR(100)

a) INSERT INTO ALUNOS (COD_ALUNO, NOME, DATA_NASCIMENTO, E_MAIL)


VALUES (1, MAGNO, 1959.11.12, magno@magno.com.br)
b) INSERT INTO ALUNOS (COD_ALUNO, NOME, DATA_NASCIMENTO, E_MAIL)
VALUES (1, MAGNO, 1959.11.12, magno@magno.com.br)
c) INSERT INTO ALUNOS (NOME, DATA_NASCIMENTO, E_MAIL)
VALUES (MAGNO, 1959.11.12, magno@magno.com.br)
d) INSERT INTO ALUNOS (NOME, DATA_NASCIMENTO, E_MAIL)
VALUES (MAGNO, 1959.11.12, magno@magno.com.br)
e) INSERT INTO ALUNOS (NOME, DATA_NASCIMENTO, E_MAIL)
VALUES (MAGNO, 1959.11.12, magno@magno.com.br)

65

SQL - Mdulo I

6. Qual tipo de campo mais adequado para armazenar a quantidade


de pessoas que moram em uma casa?

a) CHAR(2)
b) INT
c) SMALLINT
d) TINYINT
e) NUMERIC(4,2)

7. Qual tipo de campo mais adequado para armazenar o preo de


um produto?

a) CHAR(8)
b) INT
c) NUMERIC(8)
d) NUMERIC(2,10)
e) NUMERIC(10,2)

66

Criando um banco de dados

8. Qual tipo de campo mais adequado para armazenar o CEP (cdigo


de endereamento postal)?

a) CHAR(8)
b) INT
c) VARCHAR(8)
d) NUMERIC(8)
e) NUMERIC(9)

67

Criando um banco
de dados
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Criando um banco de dados para administrar as vendas de uma empresa
1. Crie um banco de dados chamado PEDIDOS_VENDA e coloque-o em uso;
2. Nesse banco de dados, crie uma tabela chamada PRODUTOS com os seguintes
campos:
Cdigo do produto

inteiro, autonumerao
chave primria.

Nome do produto

alfanumrico

Cdigo da unid. de medida inteiro


Cdigo da categoria

inteiro

Quantidade em estoque

numrico

Quantidade mnima

numrico

Preo de custo

numrico

Preo de venda

numrico

Caractersticas tcnicas

texto longo

Fotografia

binrio longo

3. Crie a tabela UNIDADES para armazenar unidades de medida:


Cdigo da unidade

inteiro, autonumerao
chave primria.

Nome da unidade

alfanumrico

4. Na tabela UNIDADES, insira os seguintes dados: PEAS, METROS,


QUILOGRAMAS, DZIAS, PACOTE, CAIXA;
5. Crie a tabela CATEGORIAS para armazenar as categorias de produto:

70

Cdigo da categoria

inteiro, autonumerao
chave primria.

Nome da categoria

alfanumrico

Criando um banco de dados

6. Na tabela CATEGORIAS, insira os seguintes dados: MOUSE, PEN-DRIVE,


MONITOR DE VIDEO, TECLADO, C.P.U., CABO DE REDE;
7. Crie uma tabela para armazenar os dados cadastrais dos clientes. Neste caso,
voc pode definir quais sero os campos da tabela;

Dica: Para atendermos s formas normais, crie uma tabela chamada


CONTATOS para armazenar os dados de e-mail e telefone.

8. Crie uma tabela para armazenar os dados cadastrais dos vendedores. Neste
caso, voc pode definir quais sero os campos da tabela;
9. Agora voc precisa criar uma tabela para armazenar os pedidos de venda.
Neste caso, observe que um pedido possui um nico nmero (chave primria),
pertence a um nico cliente, emitido em uma nica data, mas pode possuir N
produtos. Para no violarmos a primeira forma normal, precisaremos dividir as
informaes em duas tabelas:
TABELA PEDIDOS

Nmero do pedido

inteiro, autonumerao e chave primria.

Cdigo do cliente

inteiro

Cdigo do vendedor

inteiro

Data de emisso

data e hora

Data de entrega

data e hora

Valor Total

numrico
Deve armazenar uma letra:
P para PENDENTE;

Situao

C para CANCELADO;
E para ENTREGUE.

Observaes

texto longo
71

SQL - Mdulo I

TABELA ITENSPEDIDO

Nmero do pedido

inteiro

Num. Item

inteiro: Este ser um nmero sequencial


dentro de cada pedido, se um pedido
possuir 5 produtos, este campo ser
preenchido com 1, 2, 3, 4, 5.

Cdigo do produto

inteiro

Quantidade

numrico

Preo Unitrio

numrico

Desconto

numrico

A chave primria ser formada pelos campos Nmero do pedido e


Num. Item.

72

Consultando dados

3
99 SELECT;
99 Ordenao de dados;
99 Filtragem de consultas;
99 Operadores relacionais;
99 Operadores lgicos;
99 Consulta de intervalos com BETWEEN;
99 Consulta com base em strings de caractere;
99 Consulta de valores em uma lista de elementos;
99 Valores nulos;
99 Substituio de valores nulos;
99 Manipulao de campos do tipo datetime;
99 Alterao do idioma a partir do SSMS.

SQL - Mdulo I

3.1.Introduo
Na linguagem SQL, o principal comando utilizado para a realizao de consultas
o SELECT. Por meio dele, torna-se possvel consultar dados pertencentes a
uma ou mais tabelas de um banco de dados.
No decorrer deste captulo, sero apresentadas as tcnicas de utilizao do
comando SELECT, bem como algumas diretrizes para a realizao de diferentes
tipos de consultas SQL.
Para que possamos fazer exemplos que demonstrem as tcnicas mais apuradas
de consulta, precisamos ter um banco de dados com um volume razovel de
informaes j cadastradas.
Siga os passos adiante:
1. No Object Explorer, aplique um clique com o boto direito do mouse sobre
o item Databases e selecione a opo Attach:

74

Consultando dados

2. Na prxima tela, clique no boto Add:

75

SQL - Mdulo I

3. Em seguida, procure a pasta Dados e selecione o arquivo PEDIDOS_TABELAS.MDF:

4. Confirme a operao clicando no boto OK.

76

Consultando dados

Observe que o banco de dados aparecer no Object Explorer. Neste banco,


foram criados dois diagramas que mostram as tabelas existentes nele. Voc
conseguir visualizar o diagrama executando um duplo-clique sobre o nome:
DIAGRAMA DE PEDIDOS

DIAGRAMA DE EMPREGADOS

77

SQL - Mdulo I

3.2.SELECT
O comando SELECT pertence ao grupo de comandos denominado DML (Data
Manipulation Language ou Linguagem de Manipulao de Dados), que
composto de comandos para consulta (SELECT), incluso (INSERT), alterao
(UPDATE) e excluso de dados de tabela (DELETE).
A sintaxe de SELECT, com seus principais argumentos e clusulas, exibida a
seguir:
SELECT [DISTINCT] [TOP (N) [PERCENT] [WITH TIES]] <lista_de_colunas> [INTO <nome_tabela>]
FROM tabela1 [JOIN tabela2 ON expressaoJoin [, JOIN tabela3 ON exprJoin
[,...]]]
[WHERE <condicaoFiltroLinhas>]
[GROUP BY <listaExprGrupo> [HAVING <condicaoFiltroGrupo>]]
[ORDER BY <campo1> {[DESC] | [ASC]} [, <campo2> {[DESC] | [ASC]}
[,...]]]

Em que:
[DISTINCT]: Palavra que especifica que apenas uma nica instncia de cada
linha faa parte do conjunto de resultados. DISTINCT utilizada com o
objetivo de evitar a existncia de linhas duplicadas no resultado da seleo;
[TOP (N) [PERCENT] [WITH TIES]]: Especifica que apenas um primeiro
conjunto de linhas ou uma porcentagem de linhas seja retornado. N pode
ser um nmero ou porcentagem de linhas;
<lista_de_colunas>: Colunas que sero selecionadas para o conjunto de
resultados. Os nomes das colunas devem ser separados por vrgulas. Caso
tais nomes no sejam especificados, todas as colunas sero consideradas
na seleo;
[INTO nome_tabela]: nome_tabela o nome de uma nova tabela a ser
criada com base nas colunas especificadas em <lista_de_colunas> e nas
linhas especificadas por meio da clusula WHERE;

78

Consultando dados

FROM tabela1 [JOIN tabela2 ON exprJoin [, JOIN tabela3 ON exprJoin


[,...]]]:
A clusula FROM define tabelas utilizadas no SELECT;
expressaoJoin a expresso necessria para relacionar as tabelas da
clusula FROM;
tabela1, tabela2,... so as tabelas que possuem os valores utilizados
na condio de filtragem <condicaoFiltroLinhas>.
[WHERE <condicaoFiltroLinhas>]: A clusula WHERE aplica uma condio
de filtro que determinar quais linhas faro parte do resultado. Essa condio
especificada em <condicaoFiltroLinhas>;
[GROUP BY <listaExprGrupo>:
A clusula GROUP BY agrupa uma quantidade de linhas em um conjunto
de linhas. Nele, as linhas so resumidas por valores de uma ou vrias
colunas ou expresses;
<listaExprGrupo> representa a expresso na qual ser realizada a
operao por GROUP BY.
[HAVING <condicaoFiltroGrupo>]]: A clusula HAVING define uma
condio de busca para o grupo de linhas a ser retornado por GROUP BY;
[ORDER BY <campo1> {[DESC] | [ASC]} [, <campo2> {[DESC] | [ASC]} [,...]]]:
A clusula ORDER BY utilizada para determinar a ordem em que os
resultados so retornados;
J campo1, campo2 so as colunas utilizadas na ordenao dos
resultados.
{[DESC]/[ASC]}: ASC determina que os valores das colunas especificadas
em campo1, campo2 sejam retornados em ordem ascendente, enquanto
DESC retorna esses valores em ordem descendente. As duas opes so
opcionais e a barra indica que so excludentes entre si, ou seja, no podem
ser utilizadas simultaneamente. As chaves indicam um grupo excludente
de opes. Se nenhuma delas for utilizada, ASC ser assumido.

79

SQL - Mdulo I
Para consultar uma lista de colunas de uma determinada tabela em um banco
de dados, basta utilizar a seguinte sintaxe:
SELECT <lista_de_colunas> FROM <tabela>

Em que:
<lista_de_colunas>: Representa o nome da coluna ou colunas a serem
selecionadas. Quando a consulta envolve mais de uma coluna, elas devero
ser separadas por vrgula;
<tabela>: o nome da tabela a partir de onde ser feita a consulta.
Para especificar o banco de dados de origem das tabelas, a partir do qual as
informaes sero consultadas, utilize a instruo USE seguida pelo nome do
banco de dados, da seguinte maneira:
USE <nome_banco_de_dados>

Essa instruo deve ser especificada na parte inicial da estrutura de cdigo,


anteriormente s instrues destinadas consulta. Os exemplos adiante
demonstraro como utiliz-la junto ao SELECT.

3.2.1.Consultando todas as colunas


O cdigo a seguir consulta todas as colunas da tabela EMPREGADOS do banco
de dados PEDIDOS:
USE PEDIDOS;
SELECT * FROM EMPREGADOS;

3.2.2.Consultando colunas especficas


Para consultar colunas especficas de uma tabela, deve-se especificar o(s)
nome(s) da(s) coluna(s), como mostrado adiante:
SELECT <Coluna1, Coluna2, ...> FROM <tabela>

80

Consultando dados

O cdigo a seguir consulta todas as colunas da tabela EMPREGADOS:

B
D

A - Efeito do comando USE PEDIDOS. Tambm possvel selecionar o banco


de dados por aqui;
B - Instruo que queremos executar. necessrio selecionar o comando
antes de executar;
C - Boto que executa o comando selecionado. importante saber que se
nada estiver selecionado, o SQL tentar executar todos os comandos do
script;
D - Resultado da execuo do comando SELECT.
Veja o seguinte exemplo, em que feita a consulta nas colunas CODFUN, NOME
e SALARIO da tabela EMPREGADOS:
SELECT CODFUN, NOME, SALARIO FROM EMPREGADOS;

Confira o resultado:

81

SQL - Mdulo I

O prximo exemplo efetua clculos gerando colunas virtuais (no existentes


fisicamente nas tabelas):
SELECT CODFUN, NOME, SALARIO, SALARIO * 1.10
FROM EMPREGADOS;

Veja o resultado:

Observe que no existe identificao para a coluna calculada.

3.2.3.Redefinindo os identificadores

de coluna com uso de alias
O nome de uma coluna ou tabela pode ser substitudo por uma espcie de
apelido, que criado para facilitar a visualizao. Esse apelido chamado de
alias.
Costuma-se utilizar a clusula AS a fim de facilitar a identificao do alias,
no entanto, no uma obrigatoriedade. A sintaxe para a utilizao de alias
descrita a seguir:
SELECT <Coluna1> [[AS] <nome_alias>],
<Coluna2> [[AS] <nome_alias>] [,...]
FROM <tabela>

82

Consultando dados

Veja os seguintes exemplos de consulta com uso de alias:


Definindo um ttulo para a coluna calculada
SELECT CODFUN, NOME, SALARIO,
SALARIO * 1.10 AS SALARIO_MAIS_10_POR_CENTO
FROM EMPREGADOS;

Confira o resultado:

Na verdade, qualquer coluna da tabela pode receber um alias:


SELECT CODFUN AS Codigo,
NOME AS Nome, SALARIO AS Salario
FROM EMPREGADOS;

Se o alias contiver caracteres como espao, ou outros caracteres especiais,


o SQL gera erro, a no ser que este nome seja delimitado por colchetes,
apstrofo ou aspas:
SELECT CODFUN AS Codigo, NOME
DATA_ADMISSAO AS [Data
FROM EMPREGADOS;
-- ou
SELECT CODFUN AS Codigo, NOME
DATA_ADMISSAO AS Data
FROM EMPREGADOS;
-- ou
SELECT CODFUN AS Codigo, NOME
DATA_ADMISSAO AS Data
FROM EMPREGADOS;

AS Nome, SALARIO AS Salario,


de Admisso]
AS Nome, SALARIO AS Salario,
de Admisso
AS Nome, SALARIO AS Salario,
de Admisso

-- Campo calculado
SELECT CODFUN AS Codigo,
NOME AS Nome,
SALARIO AS Salario,
SALARIO * 1.10 [Salrio com 10% de Aumento]
FROM EMPREGADOS

83

SQL - Mdulo I

3.3.Ordenando dados
Utilizamos a clusula ORDER BY em conjunto com o comando SELECT para
retornar os dados em uma determinada ordem.

3.3.1.Retornando linhas na ordem ascendente


A clusula ORDER BY pode ser utilizada com a opo ASC, que faz com que as
linhas sejam retornadas em ordem ascendente. Caso a opo ASC seja omitida,
o padro da ordenao ser ascendente.
Veja um exemplo:
SELECT
SELECT
SELECT
SELECT

*
*
*
*

FROM
FROM
FROM
FROM

EMPREGADOS
EMPREGADOS
EMPREGADOS
EMPREGADOS

ORDER
ORDER
ORDER
ORDER

BY
BY
BY
BY

NOME;
NOME ASC;
SALARIO;
SALARIO ASC;

SELECT * FROM EMPREGADOS ORDER BY DATA_ADMISSAO;

3.3.2.Retornando linhas na ordem descendente


A clusula ORDER BY pode ser utilizada com a opo DESC, a qual faz com que
as linhas sejam retornadas em ordem descendente.
Veja um exemplo:
SELECT * FROM EMPREGADOS ORDER BY NOME DESC;
SELECT * FROM EMPREGADOS ORDER BY SALARIO DESC;
SELECT * FROM EMPREGADOS ORDER BY DATA_ADMISSAO DESC;

Caso no especifiquemos ASC ou DESC, os dados da tabela sero


retornados em ordem ascendente.

84

Consultando dados

3.3.3.Ordenando por nome, alias ou posio


possvel utilizar a clusula ORDER BY para ordenar dados retornados. Para
isso, utilizamos como identificao da coluna a ser ordenada o seu prprio
nome fsico (caso exista), o seu alias ou a posio em que aparece na lista do
SELECT.
Usando o alias ou a posio da coluna como identificao do campo
ordenado
-- pela coluna SALARIO
SELECT CODFUN AS Cdigo,
NOME AS Nome,
SALARIO AS Salrio,
SALARIO * 1.10 [Salrio com 10% de Aumento]
FROM EMPREGADOS
ORDER BY Salrio;
-- idem anterior
SELECT CODFUN AS Cdigo,
NOME AS Nome,
SALARIO AS Salrio,
SALARIO * 1.10 [Salrio com 10% de Aumento]
FROM EMPREGADOS
ORDER BY 3;
-- pela coluna SALARIO * 1.10
SELECT CODFUN AS Cdigo,
NOME AS Nome,
SALARIO AS Salrio,
SALARIO * 1.10 [Salrio com 10% de Aumento]
FROM EMPREGADOS
ORDER BY [Salrio com 10% de Aumento];
-- Idem anterior
SELECT CODFUN AS Cdigo,
NOME AS Nome,
SALARIO AS Salrio,
SALARIO * 1.10 [Salrio com 10% de Aumento]
FROM EMPREGADOS
ORDER BY 4;

85

SQL - Mdulo I

Veja outro exemplo de retorno de dados de acordo com o nome da coluna:


SELECT CODFUN, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY SALARIO;
-SELECT CODFUN, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY DATA_ADMISSAO;

Ordenando por vrias colunas


Quando a coluna ordenada contm informao repetida, esta informao
formar grupos. Observe o exemplo:
SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO;

Neste caso, pode ser til ordenar outra coluna dentro do grupo formado pela
primeira:
SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO, NOME;

86

Consultando dados

Note que dentro de cada departamento os dados esto ordenados pela


coluna NOME:
-SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO, SALARIO;
-SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO, DATA_ADMISSAO;
-- Continua valendo o uso do alias ou da posio da
-- coluna
SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY 1, 3;

O uso da opo DESC (ordenao descendente) independente para cada


coluna no ORDER BY:
SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO DESC, SALARIO;
-SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO, SALARIO DESC;
-SELECT COD_DEPTO, NOME, DATA_ADMISSAO, SALARIO
FROM EMPREGADOS
ORDER BY COD_DEPTO DESC, SALARIO DESC;

87

SQL - Mdulo I

3.3.4.ORDER BY com TOP


A clusula TOP mostra as N primeiras linhas de um SELECT, no entanto, se
a usarmos sem a clusula ORDER BY, o resultado fica sem sentido. Veja o
exemplo:
-- Lista os 5 primeiros empregados de acordo com a chave
-- primria
SELECT TOP 5 * FROM EMPREGADOS;

No sabemos quem so esses cinco funcionrios listados. Provavelmente, so


os primeiros a serem inseridos na tabela EMPREGADOS, mas nem isso podemos
afirmar com certeza.
J nos exemplos a seguir, conseguimos compreender o resultado:
-- Lista os 5 empregados mais antigos
SELECT TOP 5 * FROM EMPREGADOS
ORDER BY DATA_ADMISSAO;
-- Lista os 5 empregados mais novos
SELECT TOP 5 * FROM EMPREGADOS
ORDER BY DATA_ADMISSAO DESC;
-- Lista os 5 empregados que ganham menos
SELECT TOP 5 * FROM EMPREGADOS
ORDER BY SALARIO;
-- Lista os 5 empregados que ganham mais
SELECT TOP 5 * FROM EMPREGADOS
ORDER BY SALARIO DESC;

88

Consultando dados

3.3.5.ORDER BY com TOP WITH TIES


TOP WITH TIES permitida apenas em instrues SELECT e quando uma
clusula ORDER BY especificada. Indica que se o contedo do campo ordenado
na ltima linha da clusula TOP se repetir em outras linhas, estas devero ser
exibidas tambm.
Observe a sequncia:
SELECT CODFUN, NOME, SALARIO
FROM EMPREGADOS
ORDER BY SALARIO DESC;

Este exemplo lista os empregados em ordem descendente de salrio. Note que


no stimo registro o salrio de 4500.00 e este valor se repete nos cinco
registros seguintes. Se aplicarmos a clusula TOP 7, qual dos seis funcionrios
com salrio de 4500.00 ser mostrado, j que o valor o mesmo?
-- Listar os 7 funcionrios que ganham mais
SELECT TOP 7 CODFUN, NOME, SALARIO
FROM EMPREGADOS
ORDER BY SALARIO DESC;

Por qual razo o SQL selecionou o funcionrio de CODFUN 7 como ltimo da


lista, se existem outros cinco funcionrios com o mesmo salrio? Porque ele
tem a menor chave primria.
89

SQL - Mdulo I
Na maioria das consultas, quando um fato como esse ocorre (empate na ltima
linha), o critrio para desempate, se houver, dificilmente ser pela menor chave
primria. Ento, seria interessante que a consulta mostrasse todas as linhas em
que o salrio fosse o mesmo da ltima:
-- Lista os 7 empregados que ganham mais inclusive
-- aqueles empatados com o ltimo
SELECT TOP 7 WITH TIES CODFUN, NOME, SALARIO FROM EMPREGADOS
ORDER BY SALARIO DESC;

Tambm podemos usar a clusula TOP com percentual. A tabela EMPREGADOS


possui sessenta linhas, ento, se pedirmos pra ver 10% das linhas, devero
aparecer seis. Confira:
-- Mostra 10% das linhas da tabela EMPREGADOS
SELECT TOP 10 PERCENT CODFUN, NOME, SALARIO FROM EMPREGADOS
ORDER BY SALARIO DESC;

So exibidas as seguintes linhas:

90

Consultando dados

3.4.Filtrando consultas
O exemplo a seguir demonstra o que vimos at aqui sobre a instruo SELECT:
SELECT [TOP (n) [PERCENT] [WITH TIES]]
<lista_de_colunas>|*
FROM <nome_da_tabela>
[WHERE <criterio_de_filtro>]
[ORDER BY <coluna1> [ASC|DESC] [,<coluna2> [ASC|DESC] [,...]]]

A clusula WHERE determina um critrio de filtro e que somente as linhas que


respeitem este critrio sejam exibidas. A expresso contida no critrio de filtro
deve retornar TRUE (verdadeiro) ou FALSE (falso).

3.5.Operadores relacionais
A tabela a seguir exibe os operadores relacionais:
Operador

Descrio

Compara, se igual.

<> ou !=

Compara, se diferentes.

>

Compara, se maior que.

<

Compara, se menos que.

>=

Compara, se maior que ou igual.

<=

Compara, se menor que ou igual.

Operadores relacionais sempre tero dois operandos, um esquerda


e sua direita.
Considere os seguintes exemplos:
Mostrando os funcionrios com SALRIO abaixo de 1000
SELECT CODFUN, NOME, COD_CARGO, SALARIO FROM EMPREGADOS
WHERE SALARIO < 1000
ORDER BY SALARIO;

91

SQL - Mdulo I
Mostrando os funcionrios com SALRIO acima de 5000
SELECT CODFUN, NOME, COD_CARGO, SALARIO FROM EMPREGADOS
WHERE SALARIO > 5000
ORDER BY SALARIO;

Mostrando os funcionrios com campo COD_DEPTO menor ou igual a 3


SELECT * FROM Empregados
WHERE COD_DEPTO <= 3
ORDER BY COD_DEPTO;

Mostrando os funcionrios com campo COD_DEPTO igual a 2


SELECT * FROM Empregados
WHERE COD_DEPTO = 2
ORDER BY COD_DEPTO;

Mostrando os funcionrios com campo COD_DEPTO diferente de 2


SELECT * FROM Empregados
WHERE COD_DEPTO <> 2
ORDER BY COD_DEPTO;

Embora parea estranho, os sinais relacionais tambm podem ser usados para
campos alfanumricos. Veja os seguintes exemplos:
Mostrando os funcionrios que tenham NOME alfabeticamente maior
que RAQUEL
SELECT CODFUN, NOME, SALARIO
FROM EMPREGADOS
WHERE NOME > RAQUEL
ORDER BY NOME;

92

Consultando dados

Mostrando os funcionrios que tenham NOME alfabeticamente menor


que ELIANA
SELECT CODFUN, NOME, SALARIO
FROM EMPREGADOS
WHERE NOME < ELIANA
ORDER BY NOME;

3.6.Operadores lgicos
A filtragem de dados em uma consulta tambm pode ocorrer com a utilizao dos
operadores lgicos AND, OR ou NOT, cada qual permitindo uma combinao
especfica de expresses, conforme apresentado adiante:
O operador AND combina duas expresses e exige que sejam verdadeiras,
ou seja, TRUE;
O operador OR verifica se pelo menos uma das expresses retornam TRUE;
O operador NOT inverte o resultado lgico da expresso sua direita, ou
seja, se a expresso verdadeira ele retorna falso e vice-versa.
Acompanhe os seguintes exemplos:
Mostrando funcionrios do departamento 2 que ganhem mais de 5000
SELECT * FROM EMPREGADOS
WHERE COD_DEPTO = 2 AND SALARIO > 5000;

93

SQL - Mdulo I
Mostrando funcionrios do departamento 2 ou aqueles que ganhem
mais de 5000
SELECT * FROM EMPREGADOS
WHERE COD_DEPTO = 2 OR SALARIO > 5000;

importante saber onde utilizar o AND e o OR. Vamos supor que foi pedido
para listar todos os funcionrios do COD_DEPTO igual a 2 e tambm igual a 5.
Se fossemos escrever o comando exatamente como foi pedido, digitaramos o
seguinte:
SELECT * FROM EMPREGADOS
WHERE COD_DEPTO = 2 AND COD_DEPTO = 5;

No entanto, essa consulta no vai produzir nenhuma linha de resultado. Isso


porque um mesmo empregado no est cadastrado nos departamentos 2 e 5
simultaneamente. Um empregado est cadastrado ou (OR) no departamento 2
ou (OR) no departamento 5.
Precisamos entender que a pessoa que solicita a consulta est visualizando
o resultado pronto e acaba utilizando e (AND) no lugar de ou (OR). Sendo
assim, importante saber que, na execuo do SELECT, ele avalia os dados
linha por linha. E ento, o correto o seguinte:
SELECT * FROM EMPREGADOS
WHERE COD_DEPTO = 2 OR COD_DEPTO = 5;

Veja outros exemplos da utilizao de AND e OR:


Mostrando funcionrios com SALARIO entre 3000 e 5000
SELECT * FROM EMPREGADOS
WHERE SALARIO >= 3000 AND SALARIO <= 5000
ORDER BY SALARIO;

94

Consultando dados

Mostrando funcionrios com SALARIO abaixo de 3000 ou acima de 5000


SELECT * FROM EMPREGADOS
WHERE SALARIO < 3000 OR SALARIO > 5000
ORDER BY SALARIO;
-- Tambm pode ser feito usando o operador NOT. Aqueles
-- que no esto entre 3000 e 5000, esto fora desta
-- faixa.
SELECT * FROM EMPREGADOS
WHERE NOT (SALARIO >= 3000 AND SALARIO <= 5000)
ORDER BY SALARIO;

3.7.Consultando intervalos com BETWEEN


A clusula BETWEEN permite filtrar dados em uma consulta tendo como base
uma faixa de valores, ou seja, um intervalo entre um valor menor e outro maior.
Podemos utiliz-la no lugar de uma clusula WHERE com vrias expresses
contendo os operadores >= e <= ou interligadas pelo operador OR.
A funcionalidade da clusula BETWEEN assemelha-se dos operadores AND,
>= e <=, no entanto, vale considerar que, por meio dela, a consulta torna-se
ainda mais simples de ser realizada.
Os dois comandos a seguir so equivalentes, exibem o mesmo resultado,
funcionrios com SALARIO entre 3000 e 5000:
SELECT * FROM EMPREGADOS
WHERE SALARIO >= 3000 AND SALARIO <= 5000
ORDER BY SALARIO;
SELECT * FROM EMPREGADOS
WHERE SALARIO BETWEEN 3000 AND 5000
ORDER BY SALARIO;

O operador BETWEEN tambm pode ser usado para dados do tipo data ou
alfanumricos:
SELECT * FROM EMPREGADOS
WHERE DATA_ADMISSAO BETWEEN 2000.1.1 AND 2000.12.31
ORDER BY DATA_ADMISSAO;

95

SQL - Mdulo I
Alm de BETWEEN, podemos utilizar NOT BETWEEN, que permite consultar os
valores que no se encontram em uma determinada faixa de valores. O exemplo
a seguir pesquisa valores no compreendidos no intervalo especificado:
SELECT * FROM EMPREGADOS
WHERE SALARIO < 3000 OR SALARIO > 5000
ORDER BY SALARIO;

Em vez de <, > e OR, podemos utilizar NOT BETWEEN mais o operador AND
para pesquisar os mesmo valores da consulta anterior:
SELECT * FROM EMPREGADOS
WHERE SALARIO NOT BETWEEN 3000 AND 5000
ORDER BY SALARIO;
-- OU ENTO
SELECT * FROM EMPREGADOS
WHERE NOT SALARIO BETWEEN 3000 AND 5000
ORDER BY SALARIO;

3.8.Consultando com base em strings



de caractere
O operador LIKE usado para fazer pesquisas em dados do tipo string (CHAR,
VARCHAR, NCHAR e NVARCHAR). til quando no sabemos de forma exata
o dado que queremos pesquisar. Por exemplo, sabemos que o nome da pessoa
comea com MARIA, mas no sabemos o restante do nome, ou sabemos que o
nome contm a palavra RAMOS, mas no sabemos o nome completo.
Veja os seguintes exemplos:
Nomes que comeam com MARIA
SELECT * FROM EMPREGADOS
WHERE NOME LIKE MARIA%;

O sinal % um curinga que equivale a uma quantidade qualquer de


caracteres, inclusive nenhum.

96

Consultando dados

Nomes que comeam com MA


SELECT * FROM EMPREGADOS
WHERE NOME LIKE MA%;

Nomes que comeam com M


SELECT * FROM EMPREGADOS
WHERE NOME LIKE M%;

Na verdade, esse recurso de consulta pode buscar palavras que estejam contidas
no texto, seja no incio, no meio ou no final dele. Acompanhe outros exemplos:
Nomes terminando com MARIA
SELECT * FROM EMPREGADOS
WHERE NOME LIKE %MARIA;

Nomes terminando com SOUZA


SELECT * FROM EMPREGADOS
WHERE NOME LIKE %SOUZA;

Nomes terminando com ZA


SELECT * FROM EMPREGADOS
WHERE NOME LIKE %ZA;

Nomes contendo a palavra MARIA


SELECT * FROM EMPREGADOS
WHERE NOME LIKE %MARIA%;

Nomes contendo a palavra SOUZA


SELECT * FROM EMPREGADOS
WHERE NOME LIKE %SOUZA%;

Outro caractere coringa que pode ser utilizado em consultas com LIKE o
subscrito (_), que equivale a um nico caractere qualquer. Veja alguns exemplos:

97

SQL - Mdulo I
Nomes iniciados por qualquer caractere, mas que o segundo caractere
seja a letra A
SELECT * FROM Empregados
WHERE NOME LIKE _A%;

Nomes cujo penltimo caractere seja a letra Z


SELECT * FROM Empregados
WHERE NOME LIKE %Z_;

Nomes terminados em LU e seguidos de 3 outras letras


SELECT * FROM Empregados
WHERE NOME LIKE %LU___;

Podemos, tambm, fornecer vrias opes para um determinado caractere da


chave de busca, como no exemplo a seguir, que busca nomes que contenham
SOUZA ou SOUSA:
SELECT * FROM EMPREGADOS
WHERE NOME LIKE %SOU[SZ]A%;

Veja outro exemplo, que busca nomes contendo JOS ou JOSE:


SELECT * FROM EMPREGADOS
WHERE NOME LIKE %JOS[E]%;

Alm disso, podemos utilizar o operador NOT LIKE, que atua de forma oposta
ao operador LIKE. Com NOT LIKE, obtemos como resultado de uma consulta
os valores que no possuem os caracteres ou slabas determinadas.
O exemplo a seguir busca nomes que no contenham a palavra MARIA:
SELECT * FROM EMPREGADOS
WHERE NOME NOT LIKE %MARIA%;

O exemplo a seguir busca nomes que no contenham a slaba MA:


SELECT * FROM EMPREGADOS
WHERE NOME NOT LIKE %MA%;

98

Consultando dados

3.9.Consultando valores pertencentes



ou no a uma lista de elementos
O operador IN, que pode ser utilizado no lugar do operador OR em determinadas
situaes, permite verificar se o valor de uma coluna est presente em uma lista
de elementos.
O operador NOT IN, por sua vez, ao contrrio de IN, permite obter como
resultado o valor de uma coluna que no pertence a uma determinada lista de
elementos.
O exemplo a seguir busca todos os empregados cujo cdigo do departamento
(COD_DEPTO) seja 1, 3, 4 ou 7:
SELECT * FROM EMPREGADOS
WHERE COD_DEPTO IN (1,3,4,7)
ORDER BY COD_DEPTO;

O exemplo adiante busca, nas colunas NOME e ESTADO da tabela CLIENTES,


os clientes dos estados do Amazonas (AM), Paran (PR), Rio de Janeiro (RJ) e
So Paulo (SP):
SELECT NOME, ESTADO FROM CLIENTES
WHERE ESTADO IN (AM, PR, RJ, SP);

J o prximo exemplo busca, nas colunas NOME e ESTADO da tabela CLIENTES,


os clientes que no so dos estados do Amazonas (AM), Paran (PR), Rio de
Janeiro (RJ) e So Paulo (SP):
SELECT NOME, ESTADO FROM CLIENTES
WHERE ESTADO NOT IN (AM, PR, RJ, SP);

99

SQL - Mdulo I

3.10.Lidando com valores nulos


Quando um INSERT no faz referncia a uma coluna existente em uma tabela,
o contedo desta coluna ficar nulo (NULL):
-- Este INSERT menciona apenas a coluna NOME,
-- as outras colunas da tabela ficaro
-- com seu contedo NULO
INSERT INTO EMPREGADOS (NOME)
VALUES (JOSE EMANUEL);
-- Veja o resultado
SELECT * FROM EMPREGADOS;

Confira o resultado:

Com relao a valores nulos, vale considerar as seguintes informaes:


No um valor zero, nem uma string vazia. NULL;
Valores nulos no aparecem quando o campo faz parte da clusula WHERE, a
no ser que a clusula deixe explcito que deseja visualizar tambm os nulos;
Se envolvido em clculos, retorna sempre um valor NULL.
Observe a consulta a seguir e note que o valor nulo que inserimos anteriormente
no aparece nem entre os menores salrios e nem entre os maiores:
SELECT CODFUN, NOME, SALARIO FROM EMPREGADOS
WHERE SALARIO < 800 OR SALARIO > 8000
ORDER BY SALARIO;

100

Consultando dados

Caso faa parte de clculo, o resultado sempre NULL:


SELECT CODFUN, NOME, SALARIO, PREMIO_MENSAL,
SALARIO + PREMIO_MENSAL AS RENDA_TOTAL
FROM EMPREGADOS
-- filtra somente os nulos
WHERE SALARIO IS NULL;

Para lidar com valores nulos, evitando problemas no resultado final da consulta,
pode-se empregar funes como IS NULL, IS NOT NULL, NULLIF e COALESCE,
as quais sero apresentadas nos tpicos subsequentes.
O exemplo a seguir busca, na tabela EMPREGADOS, os registros cujo COD_
CARGO seja nulo:
SELECT * FROM EMPREGADOS
WHERE COD_CARGO IS NULL;

Este exemplo busca, na tabela EMPREGADOS, os registros cuja DATA_


NASCIMENTO seja nula:

SELECT * FROM EMPREGADOS
WHERE DATA_NASCIMENTO IS NULL;

O exemplo adiante busca, na tabela EMPREGADOS, os registros cuja DATA_


NASCIMENTO no seja nula:
SELECT * FROM EMPREGADOS
WHERE DATA_NASCIMENTO IS NOT NULL;

101

SQL - Mdulo I

3.11.Substituindo valores nulos


Em sntese, as funes ISNULL e COALESCE permitem retornar outros valores
quando valores nulos so encontrados durante a filtragem de dados. Adiante,
apresentaremos a descrio dessas funes.

3.11.1.ISNULL
Esta funo permite definir um valor alternativo que ser retornado, caso o
valor de argumento seja nulo. Veja os exemplos adiante:
Exemplo 1
SELECT
CODFUN, NOME, SALARIO, PREMIO_MENSAL,
ISNULL(SALARIO,0) + ISNULL(PREMIO_MENSAL,0) AS RENDA_TOTAL
FROM EMPREGADOS
WHERE SALARIO IS NULL;

Exemplo 2
SELECT
CODFUN, NOME,
ISNULL(DATA_NASCIMENTO,1900.1.1) AS DATA_NASC
FROM EMPREGADOS;

102

Consultando dados

3.11.2.COALESCE
Esta funo responsvel por retornar o primeiro argumento no nulo em uma
lista de argumentos testados.
O cdigo a seguir tenta exibir o campo EST_COB dos clientes da tabela CLIENTES.
Caso esse campo seja NULL, o cdigo tenta exibir o campo ESTADO. Caso este
ltimo tambm seja NULL, ser retornado NC:
SELECT
CODCLI, NOME, COALESCE(EST_COB,ESTADO,NC) AS EST_COBRANCA
FROM CLIENTES
ORDER BY 3;

3.12.Manipulando campos do tipo


datetime
O tipo de dado datetime utilizado para definir valores de data e hora. Aceita
valores entre 1 de janeiro de 1753 at 31 de dezembro de 9999. O formato no
qual digitamos a data depende de configuraes do servidor ou usurio.
Veja algumas funes utilizadas para retornar dados desse tipo:
SET DATEFORMAT
utilizada para determinar a forma de digitao de data/hora durante uma
sesso de trabalho.
SET DATEFORMAT (ordem)

A ordem das pores de data definida por ordem, que pode ser um dos
valores da tabela adiante:
Valor

Ordem

mdy

Ms, dia e ano. (Formato padro americano)

dmy

Dia, ms e ano.

ymd

Ano, ms e dia.

ydm

Ano, dia e ms.

myd

Ms, ano e dia.

dym

Dia, ano e ms.


103

SQL - Mdulo I

O exemplo a seguir determina o formato ano/ms/dia para o valor de data a


ser retornado:
SET DATEFORMAT YMD;

GETDATE()
Retorna a data e hora atual do sistema, sem considerar o intervalo de fusohorrio. O valor derivado do sistema operacional do computador no qual o
SQL Server executado:
SELECT GETDATE() AS DATA_ATUAL;

Para sabermos qual ser a data daqui a 45 dias, utilizamos o seguinte cdigo:
SELECT GETDATE() + 45;

J no cdigo a seguir, GETDATE() utilizado para saber a quantos dias cada


funcionrio da tabela EMPREGADOS foi admitido:
SELECT CODFUN, NOME, CAST(GETDATE() - DATA_ADMISSAO AS INT) AS
DIAS_NA_EMPRESA
FROM EMPREGADOS

DAY()
Esta funo retorna um valor inteiro que representa o dia da data especificada
como argumento data na sintaxe adiante:
DAY(data)

O argumento data pode ser uma expresso, literal de string, varivel definida
pelo usurio ou expresso de coluna.

104

Consultando dados

Veja os exemplos a seguir:


-- Nmero do dia correspondente a data de hoje
SELECT DAY(GETDATE());
-- Todos os funcionrios admitidos no dia primeiro de
-- qualquer ms e qualquer ano
SELECT * FROM EMPREGADOS
WHERE DAY(DATA_ADMISSAO) = 1;

MONTH()
Esta funo retorna um valor inteiro que representa o ms da data especificada
como argumento data da sintaxe adiante:
MONTH(data)

O argumento data pode ser uma expresso, literal de string, varivel definida
pelo usurio ou expresso de coluna.
Veja os exemplos:
-- Nmero do ms correspondente a data de hoje
SELECT MONTH(GETDATE())
-- Empregados admitidos em dezembro
SELECT * FROM EMPREGADOS
WHERE MONTH(DATA_ADMISSAO) = 12

YEAR()
Esta funo retorna um valor inteiro que representa o ano da data especificada
como argumento data na sintaxe adiante:
YEAR(data)

O argumento data pode ser uma expresso, literal de string, varivel definida
pelo usurio ou expresso de coluna.
O exemplo a seguir retorna os empregados admitidos no ano 2000:
SELECT * FROM EMPREGADOS
WHERE YEAR(DATA_ADMISSAO) = 2000;

105

SQL - Mdulo I
J o exemplo a seguir retorna os empregados admitidos no ms de dezembro
do ano 2000:
SELECT * FROM EMPREGADOS
WHERE YEAR(DATA_ADMISSAO) = 2000 AND
MONTH(DATA_ADMISSAO) = 12;

DATEPART()
Esta funo retorna um valor inteiro que representa uma poro (especificada
no argumento parte) de data ou hora definida no argumento data da sintaxe
adiante:
DATEPART (parte, data)

O argumento data pode ser uma expresso, literal de string, varivel definida
pelo usurio ou expresso de coluna, enquanto parte pode ser um dos valores
descritos na prxima tabela:

106

Valor

Parte retornada

Abreviao

year

Ano

yy, yyyy

quarter

Trimestre (1/4 de ano)

qq, q

month

Ms

mm, m

dayofyear

Dia do ano

dy, y

day

Dia

dd, d

week

Semana

wk, ww

weekday

Dia da semana

dw

hour

Hora

hh

minute

Minuto

mi, n

second

Segundo

ss, s

millisecond

Milissegundo

ms

microsecond

Microssegundo

mcs

nanosecond

Nanossegundo

ns

TZoffset

Diferena de fuso-horrio

tz

ISO_WEEK

Retorna a numerao da semana associada


a um ano.

isowk, isoww

Consultando dados

Vale dizer que o resultado retornado ser o mesmo, independentemente de


termos especificado um valor ou a respectiva abreviao.
O exemplo a seguir utiliza DATEPART para retornar os empregados admitidos
em dezembro de 2000. Para isso, so especificadas as partes de ano (YEAR) e
ms (MONTH):
SELECT * FROM EMPREGADOS
WHERE DATEPART(YEAR, DATA_ADMISSAO) = 2000 AND
DATEPART(MONTH, DATA_ADMISSAO) = 12;

DATENAME()
Esta funo retorna como resultado uma string de caracteres que representa
uma poro da data ou hora definida no argumento data da sintaxe adiante:
DATENAME(parte, data)

O argumento data pode ser uma expresso, literal de string, varivel definida
pelo usurio ou expresso de coluna, enquanto parte, que representa a referida
poro, pode ser um dos valores descritos na tabela anterior.
O exemplo a seguir utilizado para obter os funcionrios que foram admitidos
em uma sexta-feira:
-- Funcionrios admitidos em uma sexta-feira
SELECT
CODFUN, NOME, DATA_ADMISSAO,
DATENAME(WEEKDAY,DATA_ADMISSAO) AS DIA_SEMANA,
DATENAME(MONTH,DATA_ADMISSAO) AS MES
FROM EMPREGADOS
WHERE DATEPART(WEEKDAY, DATA_ADMISSAO) = 6;

O resultado retornado por DATENAME() depender do idioma


configurado no servidor SQL.

107

SQL - Mdulo I
DATEADD()
Esta funo retorna um novo valor de datetime ao adicionar um intervalo a uma
poro da data ou hora definida no argumento data da sintaxe adiante:
DATEADD(parte, numero, data)

O argumento parte a poro de data ou hora que receber o acrscimo


definido em numero. O argumento data pode ser uma expresso, literal de
string, varivel definida pelo usurio ou expresso de coluna, enquanto parte
pode ser um dos valores descritos na tabela anterior, com exceo de TZoffset.
O cdigo a seguir retorna o dia de hoje mais 45 dias:
SELECT DATEADD( DAY, 45, GETDATE());

Este cdigo retorna o dia de hoje mais 6 meses:


SELECT DATEADD( MONTH, 6, GETDATE());

J o cdigo a seguir retorna o dia de hoje mais 2 anos:


SELECT DATEADD( YEAR, 2, GETDATE());

DATEDIFF()
Esta funo obtm como resultado um nmero de data ou hora referente aos
limites de uma poro de data ou hora, cruzados entre duas datas especificadas
nos argumentos data_inicio e data_final da seguinte sintaxe:
DATEDIFF(parte, data_inicio, data_final)

O argumento parte representa a poro de data_inicio e data_final que


especificar o limite cruzado.
O exemplo a seguir retorna a quantidade de dias vividos at hoje por uma
pessoa nascida em 12 de novembro de 1959:
SELECT DATEDIFF( DAY, 1959.11.12, GETDATE());

108

Consultando dados

O exemplo a seguir retorna a quantidade de meses vividos at hoje pela pessoa


citada no exemplo anterior:
SELECT DATEDIFF( MONTH, 1959.11.12, GETDATE());

O exemplo a seguir retorna a quantidade de anos vividos at hoje por essa


mesma pessoa:
SELECT DATEDIFF( YEAR, 1959.11.12, GETDATE());

Na utilizao de DATEDIFF() para obter a diferena em anos ou meses, o valor


retornado no exato. O cdigo a seguir retorna 1. No entanto, a diferena
somente seria 1 no dia 20 de fevereiro de 2009, veja:
SELECT DATEDIFF( MONTH, 2013.1.20, 2013.2.15);

No prximo exemplo, o resultado retornado tambm 1, mas a diferena


somente seria 1 no dia 20 de junho de 2009:
SELECT DATEDIFF( YEAR, 2012.12.20, 2013.1.15);

DATEFROMPARTS()
Esta funo retorna uma data (DATE) a partir dos parmetros ano, ms e dia
especificados nos argumentos da seguinte sintaxe:
DATEFROMPARTS (ano, ms, dia)

No exemplo a seguir, vamos retornar a data 25 de dezembro de 2013 a partir


dos seguintes parmetros:
SELECT DATEFROMPARTS (2013,12,25);

O resultado mostrado a seguir:

109

SQL - Mdulo I

TIMEFROMPARTS()
Esta funo retorna um horrio (TIME) a partir dos parmetros hora, minuto,
segundo, milissegundo e preciso dos milissegundos especificados nos
argumentos da seguinte sintaxe:
TIMEFROMPARTS (hora, minuto, segundo, milissegundo, preciso)

No exemplo a seguir, vamos retornar o horrio 10:25:15 a partir dos seguintes


parmetros:
SELECT TIMEFROMPARTS (10,25,15,0,0);

O resultado mostrado a seguir:

DATETIMEFROMPARTS()
Esta funo retorna um valor de data e hora (DATETIME) a partir dos parmetros
ano, ms, dia, hora, minuto, segundo e milissegundo da seguinte sintaxe:
DATETIMEFROMPARTS (ano, ms, dia, hora, minuto, segundo, milissegundo);

Caso algum valor esteja incorreto, a funo retornar um erro. Agora, se o


parmetro for nulo, a funo retornar valor nulo. No exemplo a seguir, vamos
retornar o valor 15 de setembro de 2013 s 14:00:15.0000:
SELECT DATETIMEFROMPARTS (2013,9,15,14,0,15,0);

O resultado mostrado a seguir:

110

Consultando dados

DATETIME2FROMPARTS()
Retorna um valor do tipo datetime2 a partir dos parmetros ano, ms, dia,
hora, minuto, segundo, frao de segundo e a preciso da frao de segundo
da seguinte sintaxe:
DATETIME2FROMPATS (ano, ms, dia, hora, minuto, segundo, frao,
preciso);

Caso a preciso receba o valor 0, necessrio que a indicao de milissegundos


tambm seja 0, seno a funo retornar um erro. No exemplo a seguir, vamos
retornar o valor 10 de outubro de 2013 s 21:00:59.0000:
SELECT DATETIME2FROMPARTS (2013,10,10,21,0,59,0,0);

O resultado mostrado a seguir:

SMALLDATETIMEFROMPARTS()
Esta funo retorna um valor do tipo smalldatetime a partir dos parmetros
ano, ms, dia, hora e minuto da seguinte sintaxe:
SMALLDATETIMEFROMPARTS (ano, ms, dia, hora, minuto);

No exemplo a seguir, vamos retornar a data 17 de setembro de 2013 s 10:25:00:


SELECT SMALLDATETIMEFROMPARTS (2013,9,17,10,25);

O resultado mostrado a seguir:

111

SQL - Mdulo I

DATETIMEOFFSETFROMPARTS()
Esta funo retorna um valor do tipo datetimeoffset representando um
deslocamento de fuso horrio a partir dos parmetros ano, ms, dia, hora,
minuto, segundo, frao, deslocamento de hora, deslocamento de minuto e a
preciso decimal dos segundos:
DATETIMEOFFSETFROMPARTS (ano, ms, dia, hora, minuto, segundo,
frao, desloc_hora, desloc_minuto, preciso);

No exemplo a seguir, vamos representar o deslocamento de 12 horas de fuso


sem fraes de segundos na data 17 de setembro de 2013 s 13:22:00:
SELECT DATETIMEOFFSETFROMPARTS (2013,9,17,13,22,0,0,12,0,0);

O resultado mostrado a seguir:

EOMonth()
Esta funo retorna o ltimo dia do ms a partir dos parmetros data_incio e
adicionar_ms (Opcional) da seguinte sintaxe:
EOMONTH (data_incio [, adicionar_ms]);

112

Consultando dados

O valor retornado do tipo data (DATE). No exemplo a seguir, vamos retornar


o ltimo dia do ms atual:
SELECT EOMONTH (GETDATE());

O resultado desse exemplo mostrado a seguir:

Para avanar 1 ms, adicione o valor 1 no parmetro adicionar_ms;

Para voltar 1 ms adicione o valor -1 no parmetro adicionar_ms;

113

SQL - Mdulo I

3.13.Alterando a configurao de

idioma a partir do SSMS
O resultado retornado pela funo DATENAME() depender do idioma do
servidor SQL. Ento, para que essa funo retorne o nome do ms ou do dia
da semana da maneira desejada, pode ser necessrio alterar o idioma do SQL
Server. Isso pode ser feito a partir do SQL Server Management Studio, como
descrito no passo-a-passo a seguir:
1. Clique com o boto direito do mouse no nome do servidor, selecionando
Properties no menu de contexto, como ilustrado a seguir:

114

Consultando dados

2. Na janela seguinte, selecione a opo Advanced, procure o item Default


Language e altere para o idioma que desejar:

O formato da data pode variar de acordo com o idioma escolhido:


Brazilian: Pode utilizar os formatos dd/mm/yy ou dd/mm/yyyy;
English: Pode utilizar os formatos mm/dd/yy, mm/dd/yyyy ou yyyy;mm.dd.
A configurao escolhida ser aplicada a todos os logins criados posteriormente.
Logins j existentes devero ser configurados novamente para que possuam o
novo formato.

115

SQL - Mdulo I

Para alterar a configurao de logins existentes, siga os passos adiante:


1. No navegador do SQL Server Management Studio, abra a pasta Security e,
em seguida, Logins;
2. Clique com o boto direito no login a ser alterado e selecione Properties no
menu de contexto, conforme ilustrado a seguir:

116

Consultando dados

Ser exibida a seguinte janela:

3. Na caixa de seleo Default Language, escolha o idioma desejado e clique


em OK.

Alterar a configurao de idioma do servidor SQL afetar no


apenas o valor retornado por DATENAME(), mas todos os aspectos
associados ao idioma, como mensagens de erro exibidas no SQL
Server Management Studio e o formato de digitao de datas.

117

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
Na linguagem SQL, o principal comando utilizado para a realizao de
consultas o SELECT. Pertencente categoria DML (Data Manipulation
Language), esse comando utilizado para consultar todos os dados de uma
fonte de dados ou apenas uma parte especfica deles;
s vezes, necessrio que o resultado da consulta de dados seja fornecido
em uma ordem especfica, de acordo com um determinado critrio. Para
isso, contamos com opes e clusulas. Uma delas a clusula ORDER BY,
que considera uma certa ordem para retornar dados de consulta;
A clusula WHERE utilizada para definir critrios com o objetivo de filtrar
o resultado de uma consulta. As condies definidas nessa clusula podem
ter diferentes propsitos, tais como a comparao de dados na fonte de
dados, a verificao de dados de determinadas colunas e o teste de colunas
nulas ou valores nulos;
O tipo de dado datetime utilizado para definir valores de data e hora.
Esse tipo baseado no padro norte-americano, ou seja, os valores devem
atender ao modelo mm/dd/aa (ms, dia e ano, respectivamente). Dispomos
de diversas funes para retornar dados desse tipo, tais como GETDATE(),
DAY(), MONTH() e YEAR().

118

Consultando dados
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Utilizando o banco de dados PEDIDOS e listando suas tabelas com base
em diferentes critrios
1. Coloque em uso o banco de dados PEDIDOS;
2. Liste a tabela PRODUTOS, mostrando as colunas COD_PRODUTO,
DESCRICAO, PRECO_CUSTO, PRECO_VENDA e calculando o lucro unitrio
(PRECO_VENDA PRECO_CUSTO);
3. Liste a tabela PRODUTOS, mostrando os campos COD_PRODUTO,
DESCRICAO e calculando o valor total investido no estoque daquele produto
(QTD_REAL * PRECO_CUSTO);
4. Liste a tabela ITENSPEDIDO, mostrando as colunas NUM_PEDIDO, NUM_ITEM,
COD_PRODUTO, PR_UNITARIO, QUANTIDADE, DESCONTO e calculando o
valor de cada item (PR_UNITARIO * QUANTIDADE * (1-DESCONTO/100));
5. Liste a tabela PRODUTOS, mostrando as colunas COD_PRODUTO,
DESCRICAO, PRECO_CUSTO, PRECO_VENDA e calculando lucro estimado em
reais (QTD_REAL * (PRECO_VENDA - PRECO_CUSTO));
6. Liste a tabela PRODUTOS, mostrando os campos COD_PRODUTO,
DESCRICAO, PRECO_CUSTO, PRECO_VENDA, calculando o lucro unitrio em
reais (PRECO_VENDA PRECO_CUSTO) e o lucro unitrio percentual ((100 *
(PRECO_VENDA - PRECO_CUSTO) / PRECO_CUSTO)).

Verifique que existe uma diviso na instruo. Deve-se garantir que no


ocorra diviso por zero, pois isso provoca erro ao executar o comando.

120

Consultando dados

Laboratrio 2
A Utilizando o banco de dados PEDIDOS e listando suas tabelas com base
em novos critrios
1. Coloque em uso o banco de dados PEDIDOS;
2. Liste tabela PRODUTOS, criando campo calculado (QTD_REAL - QTD_
MINIMA) e filtre os registros resultantes, mostrando somente aqueles que
tiverem a quantidade real abaixo da quantidade mnima;

Neste caso, o exerccio no cita as colunas que devem ser exibidas.


Sendo assim, basta utilizar o smbolo asterisco (*) ou, ento, colocar
as colunas que julgar importantes.

3. Liste a tabela PRODUTOS, mostrando os registros que tenham quantidade


real acima de 5000;
4. Liste produtos com preo de venda inferior a R$0,50;
5. Liste a tabela PEDIDOS com valor total (VLR_TOTAL) acima de R$ 50.000,00;
6. Liste produtos com QTD_REAL entre 500 e 1000 unidades;
7. Liste pedidos com valor total entre R$ 30.000,00 e R$ 50.000,00;
8. Liste produtos com quantidade real acima de 5000 e cdigo do tipo igual a 6;
9. Liste produtos com quantidade real acima de 5000 ou cdigo do tipo igual
a 6;
10. Liste pedidos com valor total inferior a R$100,00 ou acima de R$100.000,00;
11. Liste produtos com QTD_REAL menor que 500 ou maior que 1000.

121

SQL - Mdulo I

Laboratrio 3
A Utilizando o banco de dados PEDIDOS
1. Coloque em uso o banco de dados PEDIDOS;
2. Liste clientes do estado de So Paulo (SP);
3. Liste clientes dos estados de Minas Gerais e Rio de Janeiro (MG, RJ);
4. Liste clientes dos estados de So Paulo, Minas Gerais e Rio de Janeiro (SP, MG, RJ);
5. Liste os vendedores com o nome LEIA;
6. Liste todos os clientes que tenham NOME comeando com BRINDES;
7. Liste todos os clientes que tenham NOME terminando com BRINDES;
8. Liste todos os clientes que tenham NOME contendo BRINDES;
9. Liste todos os produtos com DESCRICAO comeando por CANETA;
10. Liste todos os produtos com DESCRICAO contendo SPECIAL;
11. Liste todos os produtos com DESCRICAO terminando por GOLD;
12. Liste todos os clientes que tenham a letra A como segundo caractere do
nome;
13. Liste todos os produtos que tenham 0 (ZERO) como segundo caractere do
campo COD_PRODUTO;
14. Liste todos os produtos que tenham a letra A como terceiro caractere do
campo COD_PRODUTO.

122

Consultando dados

Laboratrio 4
A Utilizando novamente o banco de dados PEDIDOS e listando suas tabelas
com base em outros critrios
1. Coloque em uso o banco de dados PEDIDOS;
2. Liste todos os pedidos com data de emisso anterior a Jan/2006;
3. Liste todos os pedidos com data de emisso no primeiro semestre de 2006;
4. Liste todos os pedidos com data de emisso em janeiro e junho de 2006;
5. Liste todos os pedidos do Vendedor Cdigo 1 em Jan/2006;
6. Liste os pedidos emitidos em Jan/2006 em uma sexta-feira.

123

Atualizando
e excluindo dados

99 UPDATE;
99 DELETE;
99 Transaes.

SQL - Mdulo I

4.1.Introduo
Os comandos da categoria Data Manipulation Language, ou DML, so
utilizados no apenas para consultar (SELECT) e inserir (INSERT) dados, mas
tambm para realizar alteraes e excluses de dados presentes em registros.
Os comandos responsveis por alteraes e excluses so, respectivamente,
UPDATE e DELETE.
Para executarmos diferentes comandos ao mesmo tempo, podemos escrevlos em um s script. Porm, esse procedimento dificulta a correo de
eventuais erros na sintaxe. Portanto, recomenda-se executar cada um dos
comandos separadamente.
importante lembrar que os apstrofos () devem ser utilizados entre as strings
de caracteres, com exceo dos dados numricos. Os valores de cada coluna,
por sua vez, devem ser separados por vrgulas.

4.2.UPDATE
Os dados pertencentes a mltiplas linhas de uma tabela podem ser alterados
por meio do comando UPDATE.
Quando utilizamos o comando UPDATE, necessrio especificar algumas
informaes, como o nome da tabela que ser atualizada e as colunas cujo
contedo ser alterado. Tambm, devemos incluir uma expresso ou um
determinado valor que realizar essa atualizao, bem como algumas condies
para determinar quais linhas sero editadas.
A sintaxe de UPDATE a seguinte:
UPDATE tabela
SET nome_coluna = expressao [, nome_coluna = expressao,...]
[WHERE condicao]

126

Atualizando e excluindo dados

Em que:
tabela: Define a tabela em que dados de uma linha ou grupo de linhas
sero alterados;
nome_coluna: Trata-se do nome da coluna a ser alterada;
expressao: Trata-se da expresso cujo resultado ser gravado em nome_
coluna. Tambm pode ser uma constante;
condicao: a condio de filtragem utilizada para definir as linhas de tabela
a serem alteradas.

Este captulo aborda a utilizao simples de UPDATE sem as clusulas


FROM e JOIN que foram omitidas da sintaxe do comando. Em um
captulo posterior, veremos como utilizar esse comando com as
clusulas FROM/JOIN.
Nas expresses especificadas com o comando UPDATE, costumamos utilizar
operadores aritmticos, os quais realizam operaes matemticas, e o operador
de atribuio =. A tabela a seguir descreve esses operadores:
Operador

Descrio

Adio

Subtrao

Multiplicao

Diviso

Retorna o resto
inteiro de uma
diviso.

Atribuio

127

SQL - Mdulo I
Tais operadores podem ser combinados, como descreve a prxima tabela:
Operadores

Descrio

+=

Soma e atribui.

-=

Subtrai e atribui.

*=

Multiplica
atribui.

/=

Divide e atribui.

%=

Obtm o resto
da diviso e
atribui.

Veja alguns exemplos da utilizao desses operadores:


-- Operadores
DECLARE @A INT
SET @A += 5;
PRINT @A;
SET @A -= 2;
PRINT @A;
SET @A *= 4;
PRINT @A;
SET @A /= 2;
PRINT @A;
GO

= 10;
-- O mesmo que SET @A = @A + 5;
-- O mesmo que SET @A = @A - 2;
-- O mesmo que SET @A = @A * 4;
-- O mesmo que SET @A = @A / 2;

4.2.1.Alterando dados de uma coluna


O exemplo a seguir descreve como alterar dados de uma coluna:
-- Alterando dados de uma coluna
USE PEDIDOS;
-- Aumenta o salrio de todos os funcionrios em 20%
UPDATE EMPREGADOS
SET SALARIO = SALARIO * 1.2;
-- OU
UPDATE EMPREGADOS
SET SALARIO *= 1.2;

128

Atualizando e excluindo dados

-- Soma 2 na quantidade de dependentes do funcionrio


-- codigo 5
UPDATE EMPREGADOS
SET NUM_DEPEND = NUM_DEPEND + 2
WHERE CODFUN = 5;
-- OU
UPDATE EMPREGADOS
SET NUM_DEPEND += 2
WHERE CODFUN = 5;

4.2.2.Alterando dados de diversas colunas


O exemplo a seguir descreve como alterar dados de vrias colunas. Ser corrigido
o endereo do cliente de cdigo 5:
SELECT * FROM CLIENTES WHERE CODCLI = 5;
-- Alterando os dados do cliente de cdigo 5
UPDATE CLIENTES
SET ENDERECO = AV. PAULISTA, 1009 - 10 AND,
BAIRRO
= CERQUEIRA CESAR,
CIDADE
= SO PAULO
WHERE CODCLI = 5;
-- A linha a seguir confere o resultado da alterao
SELECT * FROM CLIENTES WHERE CODCLI = 5;

No exemplo a seguir, sero corrigidos dados de um grupo de produtos:


SELECT * FROM PRODUTOS
WHERE COD_TIPO = 5;
-- Alterando os dados do grupo de produtos
UPDATE PRODUTOS SET QTD_ESTIMADA = QTD_REAL,
CLAS_FISC = 96082000,
IPI = 8
WHERE COD_TIPO = 5;
-- A linha a seguir confere o resultado da alterao
SELECT * FROM PRODUTOS
WHERE COD_TIPO = 5;

129

SQL - Mdulo I

4.3.DELETE
O comando DELETE deve ser utilizado quando desejamos excluir os dados de
uma tabela. Sua sintaxe a seguinte:
DELETE [FROM] tabela
[WHERE condicao]

Em que:
tabela: a tabela cuja linha ou grupo de linhas ser excludo;
condicao: a condio de filtragem utilizada para definir as linhas de tabela
a serem excludas.
Uma alternativa ao comando DELETE, sem especificao da clusula WHERE,
o uso de TRUNCATE TABLE, que tambm exclui todas as linhas de uma tabela.
No entanto, este ltimo apresenta as seguintes vantagens:
No realiza o log da excluso de cada uma das linhas, o que acaba por
consumir pouco espao no log de transaes;
A tabela no fica com pginas de dados vazias;
Os valores originais da tabela, quando ela foi criada, so restabelecidos,
caso haja uma coluna de identidade.
A sintaxe dessa instruo a seguinte:
TRUNCATE TABLE <nome_tabela>

130

Atualizando e excluindo dados

4.3.1.Excluindo todas as linhas de uma tabela


Podemos excluir todas as linhas de uma tabela com o comando DELETE. Nesse
caso, no utilizamos a clusula WHERE.
1. Primeiramente, gere uma cpia da tabela EMPREGADOS:
SELECT * INTO EMPREGADOS_TMP FROM EMPREGADOS;

2. Agora, exclua os empregados que ganham mais do que 5000:


SELECT * FROM EMPREGADOS_TMP WHERE SALARIO > 5000;
-DELETE FROM EMPREGADOS_TMP WHERE SALARIO > 5000;
--

A linha a seguir verifica se os empregados que ganham mais do que 50000


realmente foram excludos:
SELECT * FROM EMPREGADOS_TMP WHERE SALARIO > 5000;

3. A seguir, exclua empregados de cdigo 3, 5 e 7:


SELECT * FROM EMPREGADOS_TMP WHERE CODFUN IN (3,5,7);
-DELETE FROM EMPREGADOS_TMP WHERE CODFUN IN (3,5,7);

A linha a seguir verifica se os empregados dos referidos cdigos realmente


foram excludos:
SELECT * FROM EMPREGADOS_TMP WHERE CODFUN IN (3,5,7);

4. J com o cdigo adiante, elimine todos os registros da tabela EMPREGADOS_


TMP:
DELETE FROM EMPREGADOS_TMP;
-- OU
TRUNCATE TABLE EMPREGADOS_TMP;
--

A linha a seguir verifica se todos os registros foram da referida tabela foram


eliminados:
SELECT * FROM EMPREGADOS_TMP;

131

SQL - Mdulo I

4.4.Transaes
Quando uma conexo ocorre no MS-SQL, ela recebe um nmero de sesso.
Mesmo que a conexo ocorra a partir da mesma mquina e mesmo login, cada
conexo identificada por um nmero nico de sesso.
Observe a figura a seguir, em que temos trs conexes identificadas pelas
sesses 52, 54 e 55:

Sobre as transaes, importante considerar as seguintes informaes:


Um processo de transao aberto por uma sesso e deve tambm ser
fechado pela mesma sesso;
Durante o processo, as alteraes feitas no banco de dados podero ser
efetivadas ou revertidas quando a transao for finalizada;
Os comandos DELETE, INSERT e UPDATE abrem uma transao de forma
automtica. Se o comando no provocar erro, ele confirma as alteraes no
final, caso contrrio, descarta todas as alteraes.

132

Atualizando e excluindo dados

4.4.1.Transaes explcitas
As transaes explcitas so aquelas em que seu incio e seu trmino so
determinados de forma explcita. Para definir este tipo de transao, os scripts
Transact-SQL utilizam os seguintes comandos:
BEGIN TRANSACTION ou BEGIN TRAN
Inicia um processo de transao para a sesso atual.
COMMIT TRANSACTION, COMMIT WORK ou simplesmente COMMIT
Finaliza o processo de transao atual, confirmando todas as alteraes efetuadas
desde o incio do processo.
ROLLBACK TRANSACTION, ROLLBACK WORK ou ROLLBACK
Finaliza o processo de transao atual, descartando todas as alteraes efetuadas
desde o incio do processo.
Sobre as transaes explcitas, importante considerar as seguintes informaes:
Se uma conexo for fechada com uma transao aberta, um ROLLBACK
ser executado;
As operaes feitas por um processo de transao ficam armazenadas em
um arquivo de log (.ldf), que todo banco de dados possui;
Durante um processo de transao, as linhas das tabelas que foram alteradas
ficam bloqueadas para outras sesses.

133

SQL - Mdulo I

4.4.2.Clusula OUTPUT
Para verificar se o procedimento executado pelo comando INSERT, DELETE
ou UPDATE foi executado corretamente, podemos utilizar a clusula OUTPUT
existente nesses comandos. Esta clusula mostra os dados que o comando afetou.
Usaremos os prefixos deleted ou inserted para acessar os dados de antes ou
depois da operao:
COMANDO

deleted (antes)

inserted (depois)

DELETE

SIM

NO

INSERT

NO

SIM

UPDATE

SIM

SIM

A sintaxe a seguinte:
DELETE [FROM] <tabela> [OUTPUT deleted.<nomeCampo>|*[,...]]
WHERE <condio>
INSERT INTO <tabela> [OUTPUT inserted.<nomeCampo>|* [,...]]
[(listaDeCampos)]
VALUES(listaDeValores)|SELECT <listaDeCampos> <clausulasSELECT>
UPDATE <tabela> SET <campo1> = <expr1> [,...]
[OUTPUT deleted|inserted.<nomeCampo> [,...]]
[WHERE <condio>]

Veja alguns exemplos de OUTPUT:


-- Coloca o banco PEDIDOS em uso
USE PEDIDOS;
--=========================================== OUTPUT com INSERT
-- 1. Gerar uma cpia da tabela EMPREGADOS chamada EMP_TEMP
CREATE TABLE EMP_TEMP
( CODFUN
INT PRIMARY KEY,
NOME
VARCHAR(30),
COD_DEPTO INT,
COD_CARGO
INT,
SALARIO NUMERIC(10,2) )
GO

134

Atualizando e excluindo dados

-- 2. Inserir dados e exibir os registros inseridos


INSERT INTO EMP_TEMP OUTPUT INSERTED.*
SELECT CODFUN, NOME, COD_DEPTO, COD_CARGO, SALARIO
FROM EMPREGADOS;
GO

Os registros que acabaram de ser inseridos so exibidos pela clusula OUTPUT


do comando INSERT:
--=========================================== OUTPUT com DELETE
-- 3. Gera uma cpia da tabela EMPREGADOS chamada EMP_TEMP
DROP TABLE EMP_TEMP;
SELECT * INTO EMP_TEMP FROM EMPREGADOS;
-- 4. Deleta registros e mostra os registros deletados
DELETE FROM EMP_TEMP OUTPUT DELETED.*
WHERE COD_DEPTO = 2
GO

135

SQL - Mdulo I

J os registros excludos aparecem aps a excluso:


--=========================================== OUTPUT com UPDATE
-- 5. Gera uma cpia da tabela EMPREGADOS chamada EMP_TEMP
DROP TABLE EMP_TEMP;
SELECT * INTO EMP_TEMP FROM EMPREGADOS;
-- 6. Altera registros e mostra os dados antes e depois da
-alterao
UPDATE EMP_TEMP SET SALARIO *= 1.5
OUTPUT
INSERTED.CODFUN, INSERTED.NOME, INSERTED.COD_DEPTO,
DELETED.SALARIO AS SALARIO_ANTIGO,
INSERTED.SALARIO AS SALARIO_NOVO
WHERE COD_DEPTO = 3;
GO

136

Atualizando e excluindo dados

Observe que podemos conferir se a alterao foi feita de forma correta porque
possvel verificar se a condio est correta (COD_DEPTO = 3), e verificar o
campo SALARIO antes e depois da alterao.
Veja exemplos de transao:
-- Alterar os salrios dos funcionrios com COD_CARGO = 5
-- para R$ 950,00
-- Abrir processo de transao
BEGIN TRANSACTION;
-- Para verificar se existe processo de transao aberto,
-- podemos fazer:
SELECT @@TRANCOUNT;
-- Alterar os salrios do COD_CARGO = 5
UPDATE Empregados SET SALARIO = 950
OUTPUT INSERTED.CODFUN, INSERTED.NOME, INSERTED.COD_CARGO,
DELETED.SALARIO AS SALARIO_ANTIGO,
INSERTED.SALARIO AS SALARIO_NOVO
WHERE COD_CARGO = 5
-- Conferir os resultados na listagem gerada pela clusula
-- OUTPUT
-- Se estiver tudo OK...
COMMIT TRANSACTION
-- caso contrrio
ROLLBACK TRANSACTION

137

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
Os dados pertencentes a mltiplas linhas de uma tabela podem ser alterados
por meio do comando UPDATE;
O comando DELETE deve ser utilizado quando desejamos excluir os dados
de uma tabela;
Transaes so unidades de programao capazes de manter a consistncia
e a integridade dos dados. Devemos considerar uma transao como
uma coleo de operaes que executa uma funo lgica nica em uma
aplicao de banco de dado;
Todas as alteraes de dados realizadas durante a transao so submetidas
e tornam-se parte permanente do banco de dados caso a transao seja
executada com xito. No entanto, caso a transao no seja finalizada com
xito por conta de erros, so excludas quaisquer alteraes feitas sobre os
dados.

138

Atualizando e
excluindo dados
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Atualizando e excluindo dados
1. Coloque o banco de dados PEDIDOS em uso;
2. Aumente o preo de custo de todos os produtos do tipo 2 em 15%;

Utilize transao e a clusula OUTPUT para conferir os resultados.

3. Faa com que os preos de venda dos produtos do tipo 2 fiquem 30% acima
do preo de custo;
4. Altere o campo IPI de todos os produtos com COD_TIPO = 3 para 5%;
5. Reduza em 10% o campo QTD_MINIMA de todos os produtos (multiplique
QTD_MINIMA por 0.9);
6. Altere os seguintes campos do cliente de cdigo 11:

ENDERECO: AV. CELSO GARCIA, 1234;


BAIRRO: TATUAPE;
CIDADE: SAO PAULO;
ESTADO: SP;
CEP: 03407080.

7. Copie ENDERECO, BAIRRO, CIDADE, ESTADO e CEP do cliente cdigo


13 para os campos END_COB, BAI_COB, CID_COB, EST_COB e CEP_COB do
mesmo cliente;
8. Altere a tabela CLIENTES, mudando o contedo do campo ICMS de clientes
dos estados RJ, RO, AC, RR, MG, PR, SC, RS, MS, MT para 12;
9. Altere os campos ICMS de todos os clientes de SP para 18;
10. Altere o campo ICMS para 7 para clientes que no sejam dos estados RJ,
RO, AC, RR, MG, PR, SC, RS, MS, MT, SP;
140

Atualizando e excluindo dados

11. Altere para 7 o campo DESCONTO da tabela ITENSPEDIDO, mas somente


dos itens do produto com ID_PRODUTO = 8, com data de entrega em janeiro
de 2007 e com QUANTIDADE acima de 1000;
12. Zere o campo DESCONTO de todos os itens de pedido com quantidade
abaixo de 1000, com data de entrega posterior a 1-Junho-2007 e que tenham
desconto acima de zero;
13. Usando SELECT INTO, gere uma cpia da tabela VENDEDORES com o nome
de VENDEDORES_TMP;
14. Exclua de VENDEDORES_TMP os registros com CODVEN acima de 5;
15. Utilizando o comando SELECT...INTO, faa uma cpia da tabela PEDIDOS
chamada COPIA_PEDIDOS;
16. Exclua os registros da tabela COPIA_PEDIDOS que sejam do vendedor
cdigo 2;
17. Exclua os registros da tabela COPIA_PEDIDOS que sejam do primeiro
semestre de 2007;
18. Exclua todos os registros restantes da tabela COPIA_PEDIDOS;
19. Exclua a tabela COPIA_PEDIDOS do banco de dados.

141

Constraints
e ndices

99 Constraints;
99 ndices.

SQL - Mdulo I

5.1.Constraints
As constraints so objetos utilizados para impor restries e aplicar validaes
aos campos de uma tabela ou forma como duas tabelas se relacionam.
As constraints podem ser definidas no momento da criao da tabela ou
posteriormente, utilizando o comando ALTER TABLE.

5.1.1.Nulabilidade
Alm dos valores padro, tambm possvel atribuir valores nulos a uma coluna,
o que significa que ela no ter valor algum. O NULL (nulo) no corresponde a
nenhum dado, no vazio ou zero, nulo. Ao criarmos uma coluna em uma
tabela podemos acrescentar o atributo NULL (que j padro) para que aceite
valores nulos ou ento NOT NULL, quando no queremos que determinada
coluna aceite valores nulos.
Exemplo:
CREATE TABLE ALUNOS
( CODIGO INT NOT NULL,
NOME VARCHAR(30)
NOT NULL,

E_MAIL
VARCHAR(100) NULL
);

5.1.2.Modelo EntidadeRelacionamento (MER)


O MER (Modelo Entidade-Relacionamento) define os conceitos necessrios para
um projeto de banco de dados relacional.

5.1.2.1. Relacionamento entre tabelas


J vimos anteriormente que as informaes contidas em um banco de dados
devem estar distribudas em tabelas de acordo com as regras normais, com o
objetivo de impedir redundncia e tornar mais eficiente o acesso aos dados.
Sendo assim, para recuperar um conjunto de dados do banco e gerar uma
consulta para um usurio final, normalmente necessrio relacionar os dados
de vrias tabelas.
144

Constraints e ndices

Existem trs tipos bsicos de relacionamento entre tabelas:


Relacionamento um-para-um (pouco comum)
No relacionamento um-para-um (1:1), cada linha de uma tabela se relaciona
com apenas uma linha de outra tabela. Veja o exemplo:

Tabela
CLIENTES

Tabela
CONJUGE

Temos a tabela CLIENTES com os dados de cada cliente e uma outra tabela
CONJUGE contendo os dados das esposas e maridos de cada cliente. Como uma
pessoa no pode ter duas esposas ou dois maridos, o relacionamento entre
estas duas tabelas do tipo um pra um, em que a chave primria da tabela
CLIENTES se relaciona com a chave primria da tabela CONJUGE.

145

SQL - Mdulo I

Relacionamento um-para-muitos (muito frequente)


Neste tipo de relacionamento, um registro de uma tabela pode encontrar N
correspondncias em outra tabela (1:N). Acompanhe o exemplo:

Tabela
DEPARTAMENTOS

Tabela
EMPREGADOS

Neste caso, o campo COD_DEPTO da tabela DEPARTAMENTOS (chave


primria) encontra N correspondncias na tabela EMPREGADOS. A tabela
DEPARTAMENTOS chamada de tabela mestre porque o campo COD_DEPTO,
que se relaciona com EMPREGADOS, chave primria. J a tabela EMPREGADOS,
em que COD_DEPTO se repete, chamada de tabela detalhe. O relacionamento
1:N tambm chamado de mestre x detalhe.

146

Constraints e ndices

Relacionamento muitos-para-muitos
Neste tipo de relacionamento, uma TABELA1 pode encontrar N correspondncias
em uma TABELA2 e a TABELA2 tambm pode encontrar N correspondncias na
TABELA1.
Imagine a tabela PRODUTOS e a tabela FORNECEDORES, em que cada
produto pode ser comprado de vrios fornecedores e cada fornecedor pode
vender vrios produtos. Fica a caracterizado um relacionamento do tipo N:N.
Conceitualmente, este tipo de relacionamento no existe entre duas tabelas
diretamente. Para constru-lo, precisamos de uma tabela auxiliar para fazer a
ligao entre PRODUTOS e FORNECEDORES.

Tabela
PRODUTOS

Tabela
PRODUTOS_FORNECEDORES

Tabela
FORNECEDORES

Neste exemplo, observe que o produto com ID_PRODUTO igual a 1 pode


ser comprado dos fornecedores 103, 205 e 509. De forma semelhante, se
ordenarmos a coluna COD_FORNECEDOR de PRODUTOS_FORNECEDORES,
veremos todos os produtos que cada fornecedor vende.

147

SQL - Mdulo I

5.1.3.Tipos de constraints
So diversos os tipos de constraints que podem ser criados: primary key, unique,
check, default e foreign key. Adiante, cada uma das constraints ser descrita.

5.1.3.1. PRIMARY KEY (chave primria)


A chave primria identifica de forma nica cada uma das linhas de uma tabela.
Pode ser formada por apenas uma coluna ou por combinao de duas ou mais
colunas. A informao definida como chave primria de uma tabela no pode
ser duplicada dentro desta tabela.
Exemplos
Tabela CLIENTES
Tabela PRODUTOS

Cdigo do Cliente
Cdigo do Produto

As colunas que formam a chave primria no podem aceitar valores


nulos e devem ter o atributo NOT NULL.

Comando
CREATE TABLE tabela
(
CAMPO_PK tipo
NOT NULL,

...,

...,

CONSTRAINT NomeChavePrimria PRIMARY KEY (CAMPO_PK) )

Onde usamos o termo CAMPO_PK na criao da PRIMARY KEY


tambm poder ser uma combinao de campos separados
por vrgula.

148

Constraints e ndices

O comando ser o seguinte, depois de criada a tabela:


ALTER TABLE tabela ADD
CONSTRAINT NomeChavePrimria PRIMARY KEY (CAMPO_PK)

A conveno para dar nome a uma constraint do tipo chave primria PK_
NomeTabela, ou seja, PK (abreviao de PRIMARY KEY) seguido do nome da
tabela para a qual estamos criando a chave primria.

5.1.3.2. UNIQUE
Alm do(s) campo(s) que forma(m) a PRIMARY KEY, pode ocorrer de termos
outras colunas que no possam aceitar dados em duplicidade. Neste caso
usaremos a constraint UNIQUE.
As colunas nas quais so definidas constraints UNIQUE permitem a incluso de
valores nulos, desde que seja apenas um valor nulo por coluna.
Exemplos
Na tabela CLIENTES
Na tabela TIPOS_PRODUTO
Na tabela UNIDADES_MEDIDA

Campos C.P.F, R.G. e E-Mail


Descrio do tipo de produto
Descrio da unidade de medida

Comando
CREATE TABLE tabela
(
...
CAMPO_UNICO tipo
NOT NULL,

...,

...,
CONSTRAINT NomeUnique UNIQUE (CAMPO_UNICO) )

Onde usamos o termo CAMPO_UNICO na criao da UNIQUE tambm


poder ser uma combinao de campos separados por vrgula.

149

SQL - Mdulo I
O comando ser o seguinte, depois de criada a tabela:
ALTER TABLE tabela ADD
CONSTRAINT NomeUnique UNIQUE (CAMPO_UNICO)

O nome da constraint deve ser sugestivo, como UQ_NomeTabela_


NomeCampoUnico.

5.1.3.3. CHECK
Neste tipo de constraint, criamos uma condio (semelhante s usadas com
a clusula WHERE) para definir a integridade de um ou mais campos de uma
tabela.
Exemplo
Tabela CLIENTES
Data Nascimento < Data Atual
Data Incluso <= Data Atual
Data Nascimento < Data Incluso
Tabela PRODUTOS
Preo Venda >= 0
Preo Compra >= 0
Preo Venda >= Preo Compra
Data Incluso <= Data Atual
Comando
CREATE TABLE tabela
(

...,

...,

CONSTRAINT NomeCheck CHECK (Condio) )

O comando ser o seguinte, depois de criada a tabela:


ALTER TABLE tabela ADD
CONSTRAINT NomeCheck CHECK (Condio)

O nome da constraint deve ser sugestivo, como CH_NomeTabela_


DescrCondicao.

150

Constraints e ndices

5.1.3.4. DEFAULT
Normalmente, quando inserimos dados em uma tabela, as colunas para as
quais no fornecemos valor, tero como contedo NULL. Ao definirmos uma
constraint do tipo DEFAULT para uma determinada coluna, este valor ser
atribudo ela quando o INSERT no fornecer valor.
Exemplo
Tabela PESSOAS
Data Incluso DEFAULT Data Atual
Sexo
DEFAULT M
Comando
CREATE TABLE tabela
(

...,

CAMPO_DEFAULT

...,
)

tipo [NOT NULL] DEFAULT valorDefault,

O comando ser o seguinte, depois de criada a tabela:


ALTER TABLE tabela ADD
CONSTRAINT NomeDefault DEFAULT (valorDefault) FOR CAMPO_DEFAULT

151

SQL - Mdulo I
5.1.3.5. FOREIGN KEY (chave estrangeira)
chamado de chave estrangeira ou FOREIGN KEY o campo da tabela DETALHE
que se relaciona com a chave primria da tabela MESTRE.

Tabela Mestre
DEPARTAMENTOS

Tabela Detalhe
EMPREGADOS

Observando a figura, notamos que o campo COD_DEPTO da tabela EMPREGADOS


(detalhe) chave estrangeira, pois se relaciona com COD_DEPTO (chave primria)
da tabela DEPARTAMENTOS (mestre).
Podemos ter esta mesma estrutura sem termos criado uma chave estrangeira,
embora a chave estrangeira garanta a integridade referencial dos dados, ou seja,
com a chave estrangeira, ser impossvel existir um registro de EMPREGADOS
com um COD_DEPTO inexistente em DEPARTAMENTOS. Quando procurarmos
o COD_DEPTO do empregado em DEPARTAMENTOS, sempre encontraremos
correspondncia.

Se a tabela mestre no possuir uma chave primria, no ser possvel


criar uma chave estrangeira apontando para ela.

152

Constraints e ndices

Para criarmos uma chave estrangeira, temos que considerar as seguintes


informaes envolvidas:
A tabela detalhe;
O campo da tabela detalhe que se relaciona com a tabela mestre;
A tabela mestre;
O campo chave primria da tabela mestre.
O comando para a criao de uma chave estrangeira o seguinte:
CREATE TABLE tabelaDetalhe
(

...,

CAMPO_FK tipo [NOT NULL],

...,

CONSTRAINT NomeChaveEstrangeira FOREIGN KEY(CAMPO_FK)

REFERENCES tabelaMestre(CAMPO_PK_TABELA_MESTRE)
)

Ou utilize o seguinte comando depois de criada a tabela:


ALTER TABLE tabelaDetalhe ADD

CONSTRAINT NomeChaveEstrangeira FOREIGN KEY(CAMPO_FK)

REFERENCES tabelaMestre(CAMPO_PK_TABELA_MESTRE)

5.1.4.Criando constraints
A seguir, veremos como criar constraints com o uso de CREATE TABLE e ALTER
TABLE, bem como cri-las graficamente a partir da interface do SQL Server
Management Studio.

5.1.4.1. Criando constraints com CREATE TABLE


A seguir, temos um exemplo de criao de constraints com o uso de CREATE
TABLE. Primeiramente, crie o banco de dados TESTE_CONSTRAINT:
CREATE DATABASE TESTE_CONSTRAINT;
GO
USE TESTE_CONSTRAINT;

153

SQL - Mdulo I
Agora, crie a tabela TIPO_PRODUTO com os tipos (categorias) de produto:
-- Tabela de tipos (categorias) de produto
CREATE TABLE TIPO_PRODUTO
(
COD_TIPO
INT IDENTITY NOT NULL,
TIPO VARCHAR(30) NOT NULL,
-- Conveno de nome: PK_NomeTabela
CONSTRAINT PK_TIPO_PRODUTO PRIMARY KEY (COD_TIPO),
-- Conveno De nome: UQ_NomeTabela_NomeCampo
CONSTRAINT UQ_TIPO_PRODUTO_TIPO UNIQUE( TIPO ) );

Em seguida, teste a constraint UNIQUE criada:


-- Testando a CONSTRAINT UNIQUE
INSERT TIPO_PRODUTO VALUES (MOUSE);
INSERT TIPO_PRODUTO VALUES (PEN-DRIVE);
INSERT TIPO_PRODUTO VALUES (HARD DISK);
-- Vai dar erro porque VIOLA UNIQUE CONSTRAINT
INSERT TIPO_PRODUTO VALUES (HARD DISK);

O prximo passo criar a tabela de produtos (PRODUTOS):


-- Tabela de produtos
CREATE TABLE PRODUTOS
(
ID_PRODUTO
INT IDENTITY NOT NULL,
DESCRICAO
VARCHAR(50),
COD_TIPO
INT,
PRECO_CUSTO
NUMERIC(10,2),
PRECO_VENDA
NUMERIC(10,2),
QTD_REAL
NUMERIC(10,2),
QTD_MINIMA
NUMERIC(10,2),
DATA_CADASTRO
DATETIME DEFAULT GETDATE(),
SN_ATIVO
CHAR(1) DEFAULT S,
CONSTRAINT PK_PRODUTOS PRIMARY KEY( ID_PRODUTO ),
CONSTRAINT UQ_PRODUTOS_DESCRICAO UNIQUE( DESCRICAO ),
CONSTRAINT CK_PRODUTOS_PRECOS
CHECK( PRECO_VENDA >= PRECO_CUSTO ),
CONSTRAINT CK_PRODUTOS_DATA_CAD
CHECK( DATA_CADASTRO <= GETDATE() ),
CONSTRAINT CK_PRODUTOS_SN_ATIVO
CHECK( SN_ATIVO IN (N,S) ),
-- Conveno de nome: FK_TabelaDetalhe_TabelaMestre
CONSTRAINT FK_PRODUTOS_TIPO_PRODUTO
FOREIGN KEY (COD_TIPO)
REFERENCES TIPO_PRODUTO (COD_TIPO)
);

154

Constraints e ndices

Veja um modelo para a criao de chave estrangeira:


-- Criao de chave estrangeira
----

CONSTRAINT FK_TabelaDetalhe_TabelaMestre
FOREIGN KEY (campoTabelaDetalhe)
REFERENCES TabelaMestre( campoPK_TabelaMestre )

Feito isso, teste a constraint DEFAULT criada anteriormente. A sequncia de


cdigo adiante gera os valores para os campos DATA_CADASTRO e SN_ATIVO
que no foram mencionados no INSERT:
INSERT PRODUTOS
(DESCRICAO, COD_TIPO, PRECO_CUSTO, PRECO_VENDA,
QTD_REAL, QTD_MINIMA)
VALUES (TESTANDO INCLUSAO, 1, 10, 12, 10, 5 );
-SELECT * FROM PRODUTOS;

No cdigo seguinte, teste a constraint UNIQUE:


-- Vai dar erro porque viola a constraint UNIQUE
INSERT PRODUTOS
(DESCRICAO, COD_TIPO, PRECO_CUSTO, PRECO_VENDA,
QTD_REAL, QTD_MINIMA)
VALUES (TESTANDO INCLUSAO, 10, 10, 12, 10, 5 );

No prximo cdigo, teste a constraint FOREIGN KEY:


-- Vai dar erro porque viola a constraint FOREIGN KEY
INSERT PRODUTOS
(DESCRICAO, COD_TIPO, PRECO_CUSTO, PRECO_VENDA,
QTD_REAL, QTD_MINIMA)
VALUES (TESTANDO INCLUSAO 2, 10, 10, 12, 10, 5 );

Por fim, o cdigo adiante testa a constraint CHECK:


-- Vai dar erro porque viola constraint CHECK
-- (CK_PRODUTOS_PRECOS)
INSERT PRODUTOS
(DESCRICAO, COD_TIPO, PRECO_CUSTO, PRECO_VENDA,
QTD_REAL, QTD_MINIMA)
VALUES (TESTANDO INCLUSAO 2, 1, 14, 12, 10, 5 );

155

SQL - Mdulo I
5.1.4.2. Criando constraints com ALTER TABLE
O exemplo a seguir demonstra a criao de constraints utilizando ALTER TABLE:
USE TESTE_CONSTRAINT;
DROP TABLE PRODUTOS
GO
DROP TABLE TIPO_PRODUTO
GO
-- Criao da tabela TIPO_PRODUTO
CREATE TABLE TIPO_PRODUTO
(
COD_TIPO
INT IDENTITY NOT NULL,

TIPO
VARCHAR(30) NOT NULL );
-- Criando as CONSTRAINTS com ALTER TABLE
ALTER TABLE TIPO_PRODUTO ADD
CONSTRAINT PK_TIPO_PRODUTO PRIMARY KEY (COD_TIPO);
ALTER TABLE TIPO_PRODUTO ADD
CONSTRAINT UQ_TIPO_PRODUTO_TIPO UNIQUE( TIPO );
-- Criando a tabela PRODUTOS
CREATE TABLE PRODUTOS
(
ID_PRODUTO
INT IDENTITY NOT NULL,
DESCRICAO
VARCHAR(50),
COD_TIPO
INT,
PRECO_CUSTO
NUMERIC(10,2),
PRECO_VENDA
NUMERIC(10,2),
QTD_REAL
NUMERIC(10,2),
QTD_MINIMA
NUMERIC(10,2),
DATA_CADASTRO
DATETIME,
SN_ATIVO
CHAR(1) );
-- Criando as CONSTRAINTS com ALTER TABLE
ALTER TABLE PRODUTOS ADD
CONSTRAINT PK_PRODUTOS PRIMARY KEY( ID_PRODUTO );
ALTER TABLE PRODUTOS ADD
CONSTRAINT UQ_PRODUTOS_DESCRICAO UNIQUE( DESCRICAO );
-- Criando vrias CONSTRAINTS em um nico ALTER TABLE
ALTER TABLE PRODUTOS ADD
CONSTRAINT CK_PRODUTOS_PRECOS
CHECK( PRECO_VENDA >= PRECO_CUSTO ),

156

Constraints e ndices

CONSTRAINT CK_PRODUTOS_DATA_CAD
CHECK( DATA_CADASTRO <= GETDATE() ),
CONSTRAINT CK_PRODUTOS_SN_ATIVO
CHECK( SN_ATIVO IN (N,S) ),
CONSTRAINT FK_PRODUTOS_TIPO_PRODUTO
FOREIGN KEY (COD_TIPO)
REFERENCES TIPO_PRODUTO (COD_TIPO),
CONSTRAINT DF_SN_ATIVO DEFAULT (S) FOR SN_ATIVO,
CONSTRAINT DF_DATA_CADASTRO DEFAULT (GETDATE())
FOR DATA_CADASTRO;

5.1.4.3. Criando constraints graficamente


O exemplo a seguir demonstra a criao de constraints graficamente.
Primeiramente, crie as tabelas TIPO_PRODUTO e PRODUTOS no banco de
dados TESTE_CONSTRAINT:
USE TESTE_CONSTRAINT;
DROP TABLE PRODUTOS
GO
DROP TABLE TIPO_PRODUTO
GO
-- Criao da tabela TIPO_PRODUTO
CREATE TABLE TIPO_PRODUTO
(
COD_TIPO
INT IDENTITY NOT NULL,

TIPO
VARCHAR(30) NOT NULL );
-- Criando a tabela PRODUTOS
CREATE TABLE PRODUTOS
(
ID_PRODUTO
INT IDENTITY NOT NULL,
DESCRICAO
VARCHAR(50),
COD_TIPO
INT,
PRECO_CUSTO
NUMERIC(10,2),
PRECO_VENDA
NUMERIC(10,2),
QTD_REAL
NUMERIC(10,2),
QTD_MINIMA
NUMERIC(10,2),
DATA_CADASTRO
DATETIME,
SN_ATIVO
CHAR(1) );

157

SQL - Mdulo I
Depois, realize os seguintes passos:
1. No Object Explorer, selecione o banco de dados TESTE_CONSTRAINT e abra
os subitens do banco;
2. Aplique um clique com o boto direito do mouse no item Database Diagrams
e selecione a opo New Database Diagram;

3. Na caixa de dilogo exibida, clique em Yes (Sim);

158

Constraints e ndices

4. Uma janela com os nomes das tabelas existentes no banco de dados ser
exibida. Selecione as duas tabelas e clique em Add (Adicionar) e, depois, em
Close (Fechar). Note que as tabelas aparecero na rea de desenho do diagrama;

159

SQL - Mdulo I

5. Clique com o boto direito do mouse no campo COD_TIPO da tabela TIPO_


PRODUTO e selecione a opo Set As Primary Key (Definir Chave Primria);

6. Clique com o boto direito do mouse no campo ID_PRODUTO da tabela


PRODUTOS e selecione a opo Set As Primary Key (Definir Chave Primria).
Com isso, sero criadas as chaves primrias das duas tabelas;

160

Constraints e ndices

7. Para criar a chave nica (UNIQUE CONSTRAINT), selecione a tabela TIPO_


PRODUTO, aplique um clique com o boto direito do mouse sobre ela e clique
na opo Indexes/Keys... (ndices/Chaves...) para abrir a caixa de dilogo
ndices/Chaves;

8. Clique no boto Add (Adicionar);

161

SQL - Mdulo I

9. Altere as propriedades (A) Type (Tipo) para Unique Key (Chave Exclusiva)
e (B) Columns (Colunas) para TIPO;

162

Constraints e ndices

10. Altere as propriedades (C) Name (Nome) para UQ_TIPO_PRODUTO_TIPO.


Depois, clique em Close (Fechar);

11. Para criar as constraints CHECK, clique com o boto direito do mouse sobre
a tabela PRODUTOS e selecione a opo Check Constraints... (Restries de
Verificao...);

163

SQL - Mdulo I

12. Na seguinte caixa de dilogo que aberta, clique no boto Add e depois
altere as seguintes propriedades:

13. Para definir os valores default (padro) de cada campo, clique com o boto
direito do mouse na tabela PRODUTOS, selecione Table View (Exibio da
Tabela...) e depois Modify Custom View (Modificar Personalizao);

164

Constraints e ndices

14. Na janela aberta, selecione as colunas Condensed Type e Nullable e removaas clicando no boto <. Em seguida, adicione a coluna Default Value clicando
no boto >. Feche a janela clicando em OK;

15. Para exibir os valores padro, clique com o boto direito do mouse sobre
a tabela PRODUTOS, selecione Table View e clique na opo Custom. Por
fim, informe o valor padro ao lado do nome do campo DATA_CADASTRO e
SN_ATIVO;

165

SQL - Mdulo I
16. Para definir a chave estrangeira, selecione o campo COD_TIPO da tabela
PRODUTOS e arraste-o at o campo COD_TIPO da tabela TIPO_PRODUTO.

5.2.ndices
Os ndices tornam mais rpidos os procedimentos de ordenao e de busca na
tabela. Observe a figura:

166

Constraints e ndices

Duas estruturas diferentes de ndices podem ser utilizadas:


Clustered (clusterizado): Neste tipo de estrutura, a tabela ordenada
fisicamente. Por meio do ndice clusterizado, possvel otimizar a
performance de leituras baseadas na filtragem de dados de acordo com
uma faixa de valores. permitido o uso de apenas um ndice clusterizado
por tabela, j que as linhas de dados s podem ser ordenadas de uma
maneira;
NonClustered (no clusterizado): Neste tipo de estrutura, os dados de
uma tabela so ordenados de maneira lgica. Os ndices no clusterizados
possuem valores chave, sendo que um ponteiro para a linha de dados
encontrado em cada entrada desses valores. Esse ponteiro conhecido
como localizador de linha.

167

SQL - Mdulo I

5.2.1.Criando ndices
A criao de ndices se d por meio do comando CREATE INDEX. Sua sintaxe
exibida a seguir:
CREATE INDEX [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX <nome_do_indice>
ON <nome_tabela_ou_view> ( <nome_coluna> [ASC | DESC] [,...] )

Em que:
UNIQUE: A duplicidade do campo chave do ndice no ser permitida se
utilizarmos essa palavra;
CLUSTERED: Indica que as linhas da tabela estaro fisicamente ordenadas
pelo campo que a chave do ndice;
NONCLUSTERED: Indica que o ndice no interfere na ordenao das linhas
da tabela (default);
<nome_tabela_ou_view>: Nome da tabela ou view para a qual o ndice ser
criado;
<nome_coluna>: a coluna da tabela que ser a chave do ndice;
ASC: Esta palavra determina a ordenao ascendente (padro);
DESC: Esta palavra determina a ordenao descendente.

168

Constraints e ndices

5.2.2.Excluindo ndices
Para a excluso de ndices de um banco de dados, utilizamos o comando DROP
INDEX, cuja sintaxe a seguinte:
DROP INDEX <nome_tabela_ou_view>.<nome_indice>

Em que:
<nome_tabela_ou_view>: o nome da tabela ou view com a qual o ndice
a ser excludo est associado;
<nome_indice>: o nome do ndice a ser excludo.

169

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
As constraints so objetos utilizados com a finalidade de definir regras
referentes integridade e consistncia nas colunas das tabelas que fazem
parte de um sistema de banco de dados;
Para assegurar a integridade dos dados de uma tabela, o SQL Server oferece
cinco tipos diferentes de constraints: PRIMARY KEY, FOREIGN KEY, UNIQUE,
CHECK e DEFAULT;
Alm dos valores padro, tambm possvel atribuir valores nulos a uma
coluna, o que significa que ela no ter valor;
Quando trabalhamos com aplicaes construdas e administradas por
um sistema de gerenciamento de banco de dados, o relacionamento o
responsvel por unir duas ou mais tabelas de bancos de dados;
Cada uma das constraints possui regras de utilizao. Uma coluna que
definida como chave primria, por exemplo, no pode aceitar valores nulos.
Em cada tabela, pode haver somente uma constraint de chave primria;
Podemos criar constraints com uso de CREATE TABLE, ALTER TABLE ou
graficamente (a partir da interface do SQL Server Management Studio);
Informaes especficas de uma tabela ou de uma view podem ser localizadas
de maneira mais rpida com a utilizao de ndices. Um ndice (index)
uma coleo de pginas associadas com uma tabela ou view, a fim de
acelerar o retorno de suas linhas. O ndice contm chaves feitas de uma
ou mais colunas da tabela ou view e indicadores que mapeiam o local de
armazenamento do dado especificado.

170

Constraints
e ndices
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Criando constraints com ALTER TABLE
1. Abra o script chamado Cap05_CRIA_PEDIDOS_VAZIO.sql e execute todo
o cdigo. Isso ir criar um banco de dados chamado PEDIDOS_VAZIO, cuja
estrutura a mesma do banco de dados PEDIDOS j utilizado;
2. Coloque em uso o banco de dados PEDIDOS_VAZIO;
3. Crie chaves estrangeiras para a tabela PEDIDOS:
Com CLIENTES;
Com VENDEDORES.
4. Crie chaves estrangeiras para a tabela PRODUTOS:
Com TIPOPRODUTO;
Com UNIDADES.
5. Crie chaves estrangeiras para a tabela ITENSPEDIDO:
Com PEDIDOS;
Com PRODUTOS;
Com TABCOR.
6. Crie uma chave nica para o campo UNIDADE da tabela UNIDADES;
7. Crie uma chave nica para o campo TIPO da tabela TIPOPRODUTO;
8. Crie constraints CHECK para a tabela PRODUTOS, considerando os seguintes
aspectos:
O preo de venda no pode ser menor que o preo de custo;
O preo de custo precisa ser maior que zero;
O campo QTD_REAL no pode ser menor que zero.

172

Constraints e ndices

9. Crie constraints CHECK para a tabela ITENSPEDIDO, considerando os


seguintes aspectos:
O campo QUANTIDADE deve ser maior ou igual que um;
O campo PR_UNITARIO deve ser maior que zero;
O campo DESCONTO no pode ser menor que zero e maior que 10.
10. Crie valores default para PRODUTOS, considerando os seguintes aspectos:
Zero para PRECO_CUSTO e PRECO_VENDA;
Zero para QTD_REAL, QTD_MINIMA e QTD_ESTIMADA;
Zero para COD_TIPO e COD_UNIDADE.
11. Crie ndices para os seguintes campos da tabela CLIENTES:
Campo NOME;
Campo FANTASIA;
Campo ESTADO;
Campo CEP;
Campo CGC.
12. Crie ndices para os seguintes campos:
Campos NOME e FANTASIA da tabela VENDEDORES;
Campo DESCRICAO da tabela PRODUTOS;
Campo DATA_EMISSAO da tabela PEDIDOS.

173

SQL - Mdulo I

Laboratrio 2
A Criando constraints com CREATE TABLE
1. Crie o banco de dados CURSOS_INFORMATICA;
2. Coloque o banco CURSOS_INFORMATICA em uso;
3. Crie a tabela CAD_SALAS, de acordo com as seguintes condies:
ID_SALA: inteiro, autonumerao e chave primria;
NUM_SALA: alfanumrico tamanho 15;
QTD_LUGARES: inteiro;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

4. Crie a tabela CAD_PERIODOS, de acordo com as seguintes condies:


ID_PERIODO: inteiro, autonumerao e chave primria;
PERIODO: alfanumrico tamanho 20;
HORA_INICIO: hora;
HORA_FIM: hora;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

174

Constraints e ndices

5. Crie a tabela de CAD_ESTADOS, de acordo com as seguintes condies:


ID_ESTADO: inteiro, autonumerao e chave primria;
COD_ESTADO_IBGE: inteiro, no nulo, no pode duplicar;
ESTADO: alfanumrico tamanho 2, no pode duplicar;
NOME_ESTADO: alfanumrico tamanho 20, no pode duplicar;
ICMS: numrico tamanho 6 com 2 decimais;
SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.
6. Crie a tabela de CAD_MUNICIPIOS, de acordo com as seguintes condies:
ID_MUNICIPIO: inteiro, autonumerao e chave primria;
COD_MUNIC_IBGE: inteiro, no nulo, no pode duplicar;
ID_ESTADO: inteiro, no nulo e chave estrangeira para CAD_ESTADOS;

MUNICIPIO: alfanumrico tamanho 50;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

7. Crie a tabela CAD_PESSOAS, de acordo com as seguintes condies:


ID_PESSOA: inteiro, autonumerao e chave primria;
NOME: alfanumrico tamanho 40;
LOGRADOURO: alfanumrico tamanho 50;
NUMERO: alfanumrico tamanho 15;
COMPLEMENTO: alfanumrico tamanho 30;

175

SQL - Mdulo I
ID_MUNICIPIO: inteiro, no nulo e chave estrangeira para CAD_MUNICIPIOS;
CEP: alfanumrico tamanho 8;
FONE1: alfanumrico tamanho 14;
FONE2: alfanumrico tamanho 14;
E_MAIL: alfanumrico tamanho 100;
WEB_SITE: alfanumrico tamanho 100;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ALUNO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N;
SN_FUNCIONARIO: alfanumrico tamanho 1, no nulo, default N, aceita
somente S ou N;
SN_INSTRUTOR: alfanumrico tamanho 1, no nulo, default N, aceita
somente S ou N;
SN_ATIVO: alfanumrico tamanho 1, no nulo, default N, aceita somente
S ou N.

8. Crie a tabela CAD_DEPTOS, de acordo com as seguintes condies:


ID_DEPTO: inteiro, autonumerao, chave primria;
DEPTO: alfanumrico tamanho 30;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

176

Constraints e ndices

9. Crie a tabela CAD_CARGOS, de acordo com as seguintes condies:


ID_CARGO: inteiro, autonumerao, chave primria;
CARGO: alfanumrico tamanho 30;

SALARIO: numrico tamanho 10 com 2 decimais;


DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

10. Crie a tabela CAD_FUNCIONARIOS, de acordo com as seguintes condies:


ID_PESSOA_FUNC: inteiro, chave primria, chave estrangeira para CAD_
PESSOAS;
ID_DEPTO: inteiro, no nulo, chave estrangeira para CAD_DEPTOS;
ID_CARGO: inteiro, no nulo, chave estrangeira para CAD_CARGOS;
DATA_INCLUSAO: data e hora, no nulo, default data atual;
DATA_ALTERACAO: data e hora, no nulo, default data atual;
DATA_ADMISSAO: data e hora, no nulo, default data atual;
PORC_COMISSAO: nmero com tamanho 4 e 2 decimais, no nulo, deve
estar no intervalo de 0 at 10.
11. Crie a tabela CAD_INSTRUTORES_NIVEIS, de acordo com as seguintes
condies:
ID_NIVEL: inteiro, autonumerao, chave primria;
NIVEL: alfanumrico tamanho 20;

177

SQL - Mdulo I
DATA_INCLUSAO: data e hora, no nulo, default data atual;
DATA_ALTERACAO: data e hora, no nulo, default data atual;
SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.
12. Crie a tabela CAD_INSTRUTORES, de acordo com as seguintes condies:
ID_PESSOA_INSTR: inteiro, chave primria, chave estrangeira para CAD_
PESSOAS;
DATA_ADMISSAO: data e hora, no nulo, default data atual;
ESCOLARIDADE: alfanumrico tamanho 1, no nulo, aceita 1: primeiro
grau, 2: segundo grau, 3: superior incompleto, 4: superior completo,
5: ps graduado;
CURRICULUM: texto longo.
13. Crie a tabela CAD_TREINAMENTOS_AREAS, de acordo com as seguintes
condies:
ID_AREA: inteiro, autonumerao e chave primria;
AREA: alfanumrico tamanho 30;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual;


SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.

14. Crie a tabela CAD_TREINAMENTOS, de acordo com as seguintes condies:


ID_TREINAMENTO: inteiro, autonumerao e chave primria;
TREINAMENTO: alfanumrico tamanho 40;

178

Constraints e ndices

ID_AREA: inteiro, no nulo, chave estrangeira para CAD_AREAS_


TREINAMENTO;
CARGA_HORARIA: inteiro;
DATA_INCLUSAO: data e hora, no nulo, default data atual;
DATA_ALTERACAO: data e hora, no nulo, default data atual;
SN_ATIVO: alfanumrico tamanho 1, no nulo, default S, aceita somente
S ou N.
15. Crie a tabela CAD_INSTRUTORES_TREINAMENTOS, de acordo com as
seguintes condies:
ID_PESSOA_INSTR: inteiro, no nulo, chave estrangeira para CAD_PESSOAS;
ID_TREINAMENTO: inteiro, no nulo, chave estrangeira para CAD_
TREINAMENTOS;

DATA_INCLUSAO: data e hora, no nulo, default data atual;


VLR_HORA: numrico tamanho 6 com 2 decimais;
ID_NIVEL: inteiro, no nulo, chave estrangeira para CAD_INSTRUTORES_
NIVEIS.

A chave primria composta pelos dois campos.

16. Crie a tabela MOV_CURSOS, de acordo com as seguintes condies:


ID_CURSO: inteiro, autonumerao e chave primria;
ID_TREINAMENTO: inteiro, no nulo, chave estrangeira para CAD_
TREINAMENTOS;
ID_PESSOA_INSTR: inteiro, no nulo, chave estrangeira para CAD_PESSOAS;
179

SQL - Mdulo I
ID_SALA: inteiro, no nulo, chave estrangeira para CAD_SALAS;
ID_PERIODO: inteiro, no nulo, chave estrangeira para CAD_PERIODOS;
DATA_INICIO: data, no nulo;
DATA_FIM: data, no nulo;
DATA_INCLUSAO: data e hora, no nulo, default data atual;

DATA_ALTERACAO: data e hora, no nulo, default data atual,


STATUS: alfanumrico tamanho 1, 0: Pendente, 1: Em andamento, 2:
Finalizado.

17. Crie a tabela MOV_CURSOS_ALUNOS, de acordo com as seguintes condies:


ID_CURSO: inteiro;
ID_PESSOA_ALUNO: inteiro;
DATA_INCLUSAO: data e hora, no nulo, default data atual.

A chave primria composta por ID_CURSO e ID_PESSOA_ALUNO.

180

Associando tabelas

6
99 INNER JOIN;
99 OUTER JOIN;
99 CROSS JOIN.

SQL - Mdulo I

6.1.Introduo
A associao de tabelas, ou simplesmente JOIN entre tabelas, tem como principal
objetivo trazer, em uma nica consulta (um nico SELECT), dados contidos em
mais de uma tabela.
Normalmente, esta associao feita atravs da chave estrangeira de uma
tabela com a chave primria da outra. Mas isso no um pr-requisito para
o JOIN, de forma que qualquer informao comum entre duas tabelas servir
para associ-las.
Diferentes tipos de associao podem ser escritos com a ajuda das clusulas
JOIN e WHERE. Por exemplo, podemos obter apenas os dados relacionados
entre duas tabelas associadas. Tambm podemos combinar duas tabelas de
forma que seus dados relacionados e no relacionados sejam obtidos.
Basicamente, existem trs tipos de JOIN que sero vistos neste captulo: INNER
JOIN, OUTER JOIN e CROSS JOIN.

6.2.INNER JOIN
A clusula INNER JOIN compara os valores de colunas provenientes de tabelas
associadas, utilizando, para isso, operadores de comparao. Por meio desta
clusula, os registros de duas tabelas so utilizados para que sejam gerados os
dados relacionados de ambas.
A sintaxe de INNER JOIN a seguinte:
SELECT <lista_de_campos>
FROM <nome_primeira_tabela> [INNER] JOIN <nome_segunda_tabela>
[ON (condicao)]

182

Associando tabelas

Em que:
condicao: Define um critrio que relaciona as duas tabelas;
INNER: opcional, se colocarmos apenas JOIN, o INNER j subentendido.
EMPREGADO

TABELADEP

Observando as duas tabelas, possvel concluir que a funcionria de CODFUN


= 5 trabalha no departamento de COMPRAS, cujo cdigo 4.
A especificao desse tipo de associao pode ocorrer por meio das clusulas
WHERE ou FROM. Veja os exemplos a seguir:
SELECT EMPREGADOS.CODFUN, EMPREGADOS.NOME, TABELADEP.DEPTO
FROM EMPREGADOS JOIN TABELADEP
ON EMPREGADOS.COD_DEPTO = TABELADEP.COD_DEPTO;
SELECT EMPREGADOS.CODFUN, EMPREGADOS.NOME, TABELADEP.DEPTO
FROM EMPREGADOS, TABELADEP
WHERE EMPREGADOS.COD_DEPTO = TABELADEP.COD_DEPTO;

A respeito do INNER JOIN, importante considerar as seguintes informaes:


A principal caracterstica do INNER JOIN que somente trar registros
que encontrem correspondncia nas duas tabelas, ou seja, se existir um
empregado com COD_DEPTO igual a 99 e na tabela de departamentos no
existir um COD_DEPTO de mesmo nmero, este empregado no aparecer
no resultado final;

183

SQL - Mdulo I
O SELECT apontar um erro de sintaxe se existirem campos de mesmo
nome nas duas tabelas e no indicarmos de qual tabela vem cada campo.

Neste treinamento, faremos o JOIN sempre na clusula FROM


usando a palavra JOIN e o critrio com ON. Usar a clusula WHERE
para fazer o JOIN pode tornar o comando confuso e mais vulnervel
a erros de resultado.
Veja os seguintes exemplos:
Exemplo 1
SELECT CODFUN, NOME, DEPTO
FROM EMPREGADOS JOIN TABELADEP
ON EMPREGADOS.COD_DEPTO = TABELADEP.COD_DEPTO;

Este exemplo est correto, porque no h duplicidade nos campos CODFUN,


NOME e DEPTO.
Exemplo 2
SELECT CODFUN, NOME, DEPTO
FROM EMPREGADOS JOIN TABELADEP
ON COD_DEPTO = COD_DEPTO;

Este exemplo est errado, porque o campo COD_DEPTO existe nas duas tabelas,
obrigatrio indicar de qual tabela vamos pegar os campos.

Sempre use o nome da tabela antes do nome do campo, mesmo que


ele exista em apenas uma das tabelas.

Quando tivermos nomes de tabelas muito extensos, podemos simplificar a


escrita, dando apelidos s tabelas. Veja os exemplos:
SELECT E.CODFUN, E.NOME, D.DEPTO
FROM EMPREGADOS AS E JOIN TABELADEP AS D
ON E.COD_DEPTO = D.COD_DEPTO;

184

Associando tabelas

-- OU
SELECT E.CODFUN, E.NOME, D.DEPTO
FROM EMPREGADOS E JOIN TABELADEP D
ON E.COD_DEPTO = D.COD_DEPTO;

O que acabamos de demonstrar um JOIN, ou associao. Quando relacionamos


duas tabelas, preciso informar qual campo permite essa ligao. Normalmente,
o relacionamento se d entre a chave estrangeira de uma tabela e a chave
primria da outra, mas isso no uma regra.
Na figura a seguir, voc pode notar um cone de chave na posio horizontal
localizado na linha que liga as tabelas EMPREGADOS e TABELADEP. Essa chave
est ao lado da tabela TABELADEP, o que indica que a chave primria dessa
tabela (COD_DEPTO), e se relaciona com a tabela EMPREGADOS, que tambm
possui um campo COD_DEPTO, que a chave estrangeira.
H, tambm, um JOIN entre as tabelas EMPREGADOS e TABELACAR. Podemos
perceber a existncia de uma chave horizontalmente posicionada na linha que
liga essas tabelas, e ela est ao lado de TABELACAR. Ento, a chave primria
de TABELACAR (COD_CARGO) que se relaciona com a tabela EMPREGADOS.
Em EMPREGADOS, tambm temos um campo COD_CARGO.

Normalmente, os campos que relacionam duas tabelas possuem o


mesmo nome nas duas tabelas. Porm, isso no uma condio
necessria para que o JOIN funcione.

185

SQL - Mdulo I

Quando executamos um SELECT, a primeira clusula lida FROM, antes de


qualquer coisa. Depois que as outras clusulas so processadas. No cdigo a seguir,
temos dois erros: E.CODIGO_DEPTO (que no existe) e FROM EMPREGADS
(erro de digitao):
SELECT
E.CODFUN, E.NOME, E.CODIGO_DEPTO, E.COD_CARGO, D.DEPTO
FROM EMPREGADS E
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO;

Executado o cdigo anterior, a seguinte mensagem de erro ser exibida:


Mensagem 208, Nvel 16, Estado 1, Linha 1
Invalid object name EMPREGADS

O primeiro erro acusado na execuo do cdigo foi na clusula FROM, o que


prova que ela processada antes.
A seguir, temos outro exemplo de JOIN:
-- EMPREGADOS e TABELACAR (cargos)
SELECT E.CODFUN, E.NOME, C.CARGO
FROM EMPREGADOS E JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- OU
SELECT E.CODFUN, E.NOME, C.CARGO
FROM TABELACAR C JOIN EMPREGADOS E ON E.COD_CARGO = C.COD_CARGO;

186

Associando tabelas

No prximo exemplo, temos o uso de JOIN para consultar trs tabelas:


-- Consultando 3 tabelas
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO, C.CARGO
FROM EMPREGADOS E
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- OU
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO, C.CARGO
FROM TABELADEP D
JOIN EMPREGADOS E ON E.COD_DEPTO = D.COD_DEPTO
JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- OU
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO, C.CARGO
FROM TABELACAR C
JOIN EMPREGADOS E ON E.COD_CARGO = C.COD_CARGO
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO;

Na consulta a seguir, temos dois erros. O primeiro que no h JOIN entre


TABELADEP e TABELACAR, como mostrado no diagrama de tabelas do SSMS.
O segundo que no podemos fazer referncia a uma tabela (E.COD_CARGO),
antes de abri-la:
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO, C.CARGO
FROM TABELACAR C
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
--<< (1)
JOIN EMPREGADOS E ON E.COD_CARGO = C.COD_CARGO;

187

SQL - Mdulo I

A seguir, temos mais um exemplo da utilizao de JOIN, desta vez com seis
tabelas:
/*

Join com 6 tabelas. Vai exibir:


ITENSPEDIDO.NUM_PEDIDO
ITENSPEDIDO.NUM_ITEM
ITENSPEDIDO.COD_PRODUTO
PRODUTOS.DESCRICAO
ITENSPEDIDO.QUANTIDADE
ITENSPEDIDO.PR_UNITARIO
TIPOPTODUTO.TIPO
UNIDADES.UNIDADE
TABCOR.COR
PEDIDOS.DATA_EMISSAO
Filtrando pedidos emitidos em Janeiro de 2007

*/
SELECT
I.NUM_PEDIDO, I.NUM_ITEM, I.COD_PRODUTO, PR.DESCRICAO,
I.QUANTIDADE, I.PR_UNITARIO, T.TIPO, U.UNIDADE, CR.COR,
PE.DATA_EMISSAO
FROM ITENSPEDIDO I
JOIN PRODUTOS PR
ON I.ID_PRODUTO
= PR.ID_PRODUTO
JOIN TABCOR CR
ON I.CODCOR
= CR.CODCOR
JOIN TIPOPRODUTO T ON PR.COD_TIPO
= T.COD_TIPO
JOIN UNIDADES U
ON PR.COD_UNIDADE = U.COD_UNIDADE
JOIN PEDIDOS PE
ON I.NUM_PEDIDO
= PE.NUM_PEDIDO
WHERE PE.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31;

possvel, tambm, associar valores em duas colunas no idnticas. Nesta


operao, utilizamos os mesmos operadores e predicados utilizados em qualquer
INNER JOIN. A associao de colunas s funcional quando associamos uma
tabela a ela mesma, o que conhecido como autoassociao ou self-join.
Em uma autoassociao, utilizamos a mesma tabela duas vezes na consulta,
porm, especificamos cada instncia da tabela por meio de aliases, que so
utilizados para especificar os nomes das colunas durante a consulta.

188

Associando tabelas

Observe que, na tabela EMPREGADOS, temos o campo CODFUN (cdigo do


funcionrio) e temos tambm o campo COD_SUPERVISOR, que corresponde
ao cdigo do funcionrio que supervisor de cada empregado. Portanto, se
quisermos consultar o nome do funcionrio e do seu supervisor, precisaremos
fazer um JOIN, da seguinte forma:
SELECT E.CODFUN, E.NOME AS FUNCIONARIO, S.NOME AS SUPERVISOR
FROM EMPREGADOS E JOIN EMPREGADOS S
ON E.COD_SUPERVISOR = S.CODFUN;

6.3.OUTER JOIN
A clusula INNER JOIN, vista anteriormente, tem como caracterstica retornar
apenas as linhas em que o campo de relacionamento exista em ambas as tabelas.
Se o contedo do campo chave de relacionamento existe em uma tabela, mas
no na outra, esta linha no ser retornada pelo SELECT. Vejamos um exemplo
de INNER JOIN:
-- INNER JOIN
SELECT * FROM EMPREGADOS; -- retorna 61 linhas
-SELECT -- retorna 58 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E
INNER JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- OU (a palavra INNER opcional)
SELECT -- retorna 58 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E
JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
/*

*/

Existem 61 linhas na tabela EMPREGADOS, mas quando fazemos


INNER JOIN com TABELACAR retorna apenas com 58 linhas.
A explicao para isso que existem 3 linhas em EMPREGADOS
com COD_CARGO invlido, inexistente em TABELADEP.

189

SQL - Mdulo I

Uma clusula OUTER JOIN retorna todas as linhas de uma das tabelas
presentes em uma clusula FROM. Dependendo da tabela (ou tabelas) cujos
dados so retornados, podemos definir alguns tipos de OUTER JOIN, como
veremos a seguir.
LEFT JOIN
A clusula LEFT JOIN ou LEFT OUTER JOIN permite obter no apenas os
dados relacionados de duas tabelas, mas tambm os dados no relacionados
encontrados na tabela esquerda da clusula JOIN. Ou seja, a tabela esquerda
sempre ter todos seus dados retornados em uma clusula LEFT JOIN. Caso
no existam dados relacionados entre as tabelas esquerda e direita de JOIN,
os valores resultantes de todas as colunas de lista de seleo da tabela direita
sero nulos.
Veja exemplos da utilizao de LEFT JOIN:
/*

OUTER JOIN: Exibe tambm as linhas que no tenham correspondncia.


No exemplo a seguir mostramos TODAS as lihas da tabela
que est a esquerda da palavra JOIN (EMPREGADOS)
*/
-SELECT -- retorna 61 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E
LEFT OUTER JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- OU (a palavra OUTER opcional)
SELECT -- retorna 61 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E
LEFT JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO;
-- Observe o resultado e veja que existem 3 empregados
-- com CARGO = NULL porque o campo COD_CARGO no foi preenchido

190

Associando tabelas

O SELECT a seguir verifica, na tabela EMPREGADOS, os empregados que no


possuem um cdigo de departamento (COD_DEPTO) vlido:
-- Filtrando somente os registros no correspondentes
SELECT -- retorna 3 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E
LEFT JOIN TABELACAR C ON E.COD_CARGO = C.COD_CARGO
WHERE C.COD_CARGO IS NULL;

RIGHT JOIN
Ao contrrio da LEFT OUTER JOIN, a clusula RIGHT JOIN ou RIGHT OUTER
JOIN retorna todos os dados encontrados na tabela direita de JOIN. Caso no
existam dados associados entre as tabelas esquerda e direita de JOIN, sero
retornados valores nulos.
Veja o seguinte uso de RIGHT JOIN. Da mesma forma que existem empregados
que no possuem um COD_DEPTO vlido, podemos verificar se existe algum
departamento sem nenhum empregado cadastrado. Neste caso, deveremos
exibir todos os registros da tabela que est direita (RIGHT) da palavra JOIN,
ou seja, da tabela TABELADEP:
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO
FROM EMPREGADOS E RIGHT JOIN TABELADEP D ON E.COD_DEPTO = D.COD_
DEPTO;
-- O resultado ter 2 departamentos que
-- no retornaram dados de empregados.
-- Filtrando somente os registros no correspondentes
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO
FROM EMPREGADOS E RIGHT JOIN TABELADEP D ON E.COD_DEPTO = D.COD_
DEPTO
WHERE E.COD_DEPTO IS NULL;

191

SQL - Mdulo I

FULL JOIN
Todas as linhas da tabela esquerda de JOIN e da tabela direita sero retornadas
pela clusula FULL JOIN ou FULL OUTER JOIN. Caso uma linha de dados no
esteja associada a qualquer linha da outra tabela, os valores das colunas da lista
de seleo sero nulos. Caso contrrio, os valores obtidos sero baseados nas
tabelas utilizadas como referncia.
A seguir, exemplificada a utilizao de FULL JOIN:
-- FULL JOIN une o LEFT e o RIGHT JOIN
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E FULL JOIN TABELACAR C ON E.COD_CARGO = C.COD_
CARGO;
-- Observe o resultado e veja que existem 2 departamentos que
-- no retornaram dados de empregados.
-- Filtrando somente os registros no correspondentes
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, C.CARGO
FROM EMPREGADOS E FULL JOIN TABELACAR C ON E.COD_CARGO = C.COD_
CARGO
WHERE E.COD_CARGO IS NULL OR C.COD_CARGO IS NULL;

192

Associando tabelas

6.4.CROSS JOIN
Todos os dados da tabela esquerda de JOIN so cruzados com os dados da
tabela direita de JOIN, ao utilizarmos CROSS JOIN. As possveis combinaes
de linhas em todas as tabelas so conhecidas como produto cartesiano. O
tamanho do produto cartesiano ser definido pelo nmero de linhas na primeira
tabela multiplicado pelo nmero de linhas na segunda tabela. possvel cruzar
informaes de duas ou mais tabelas.
Quando CROSS JOIN no possui uma clusula WHERE, gera um produto
cartesiano das tabelas envolvidas. Se adicionarmos uma clusula WHERE,
CROSS JOIN se comportar como uma INNER JOIN.
A seguir, temos um exemplo da utilizao de CROSS JOIN:
-- CROSS JOIN
SELECT -- retorna 854 linhas
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.DEPTO
FROM EMPREGADOS E CROSS JOIN TABELADEP D;

A CROSS JOIN deve ser utilizada apenas quando for realmente


necessrio um produto cartesiano, j que o resultado gerado pode
ser muito grande.

193

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
A associao de tabelas pode ser realizada, por exemplo, para converter
em informao os dados encontrados em duas ou mais tabelas. As tabelas
podem ser combinadas atravs de uma condio ou um grupo de condies
de juno;
importante ressaltar que as tabelas devem ser associadas em pares, embora
seja possvel utilizar um nico comando para combinar vrias tabelas. Um
procedimento muito comum a associao da chave primria da primeira
tabela com a chave estrangeira da segunda tabela;
JOIN uma clusula que permite a associao entre vrias tabelas, com
base na relao existente entre elas. Por meio dessa clusula, os dados
de uma tabela so utilizados para selecionar dados pertencentes outra
tabela;
H diversos tipos de JOIN: INNER JOIN, OUTER JOIN (LEFT JOIN, RIGHT
JOIN e FULL JOIN) e CROSS JOIN.

194

Associando tabelas
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Utilizando o comando JOIN para associar tabelas
Considere o seguinte diagrama relacional de banco de dados para associar
tabelas:

1. Coloque em uso o banco de dados PEDIDOS;


2. Liste os campos NUM_PEDIDO, DATA_EMISSAO e VLR_TOTAL de PEDIDOS,
seguidos de NOME do vendedor;
3. Liste os campos NUM_PEDIDO, DATA_EMISSAO e VLR_TOTAL de PEDIDOS,
seguidos de NOME do cliente;
4. Liste os pedidos com o nome do vendedor e o nome do cliente;
196

Associando tabelas

5. Liste os itens de pedido (ITENSPEDIDO) com o nome do produto (PRODUTOS.


DESCRICAO);
6. Liste os campos COD_PRODUTO e DESCRICAO da tabela PRODUTOS,
seguidos da descrio do tipo de produto (TIPOPRODUTO.TIPO);
7. Liste os campos COD_PRODUTO e DESCRICAO da tabela PRODUTOS,
seguidos da descrio do tipo de produto (TIPOPRODUTO.TIPO) e do nome da
unidade de medida (UNIDADES.UNIDADE);
8. Liste os campos NUM_PEDIDO, NUM_ITEM, COD_PRODUTO, QUANTIDADE
e PR_UNITARIO da tabela ITENSPEDIDO, e os campos COD_PRODUTO e
DESCRICAO da tabela PRODUTOS, seguidos da descrio do tipo de produto
(TIPOPRODUTO.TIPO) e do nome da unidade de medida (UNIDADES.UNIDADE);
9. Liste os campos NUM_PEDIDO, NUM_ITEM, COD_PRODUTO, QUANTIDADE
e PR_UNITARIO da tabela ITENSPEDIDO, e os campos COD_PRODUTO e
DESCRICAO da tabela PRODUTOS, seguidos da descrio do tipo de produto
(TIPOPRODUTO.TIPO), do nome da unidade de medida (UNIDADES.UNIDADE)
e do nome da cor (TABCOR.COR);
10. Liste todos os pedidos (PEDIDOS) do vendedor MARCELO em Jan/2007;

Este exerccio no especifica quais campos devem ser exibidos.


Escolha voc os campos que devem ser mostrados.

11. Liste os nomes dos clientes (CLIENTES.NOME) que efetuaram compras em


janeiro de 2007;
12. Liste os nomes de produtos (PRODUTOS.DESCRICAO) que foram vendidos
em janeiro de 2007;
13. Liste NUM_PEDIDO, VLR_TOTAL (PEDIDOS) e NOME (CLIENTE). Mostre
apenas pedidos de janeiro de 2007 e clientes que tenham NOME iniciado
com MARCIO;

197

SQL - Mdulo I

14. Liste NUM_PEDIDO, QUANTIDADE vendida e PR_UNITARIO (de


ITENSPEDIDO), DESCRICAO (de PRODUTOS), NOME do vendedor que vendeu
cada item de pedido (de VENDEDORES);
15. Liste todos os itens de pedido com desconto superior a 7%. Mostre NUM_
PEDIDO, DESCRICAO do produto, NOME do cliente, NOME do vendedor e
QUANTIDADE vendida;
16. Liste os itens de pedido com o nome do produto, a descrio do tipo, a
descrio da unidade e o nome da cor, mas apenas os itens vendidos em janeiro
de 2007 na cor LARANJA;
17. Liste NOME e FONE1 dos fornecedores que venderam o produto CANETA
STAR I;
18. Liste a DESCRICAO dos PRODUTOS comprados do fornecedor cujo NOME
comea com LINCE;
19. Liste NOME e FONE1 dos fornecedores, bem como DESCRICAO dos produtos
com QTD_REAL abaixo de QTD_MINIMA;
20. Liste todos os PRODUTOS comprados do fornecedor cujo nome inicia-se
com FESTO.

198

Consultas com
subqueries

99 Principais caractersticas das subqueries;


99 Subqueries introduzidas com IN e NOT IN;
99 Subqueries introduzidas com sinal de
igualdade;
99 Subqueries correlacionadas;
99 Diferenas entre subqueries e associaes;
99 Diferenas entre subqueries e tabelas
temporrias.

SQL - Mdulo I

7.1.Introduo
Uma consulta aninhada em uma instruo SELECT, INSERT, DELETE ou UPDATE
chamada de subquery (subconsulta). Isso ocorre quando usamos um SELECT
dentro de um SELECT, INSERT, UPDATE ou DELETE. Tambm comum chamar
uma subquery de query interna. J a instruo em que est inserida a subquery
pode ser chamada de query externa.
O limite mximo de aninhamento de uma subquery de 32 nveis, limite este
que varia de acordo com a complexidade das outras instrues que compem
a consulta e com a quantidade de memria disponvel.

7.2.Principais caractersticas das


subqueries
A seguir, temos a descrio das principais caractersticas das subqueries:
As subqueries podem ser escalares (retornam apenas uma linha) ou tabulares
(retornam linhas e colunas);
possvel obter apenas uma coluna por subquery;
Uma subquery, que pode ser includa dentro de outra subquery, deve estar
entre parnteses, o que a diferenciar da consulta principal;
Em instrues SELECT, UPDATE, INSERT e DELETE, uma subquery
utilizada nos mesmos locais em que poderiam ser utilizadas expresses;
Pelo fato de podermos trabalhar com consultas estruturadas, as subqueries
permitem que partes de um comando sejam separadas das demais partes;
Se uma instruo permitida em um local, este local aceita a utilizao de
uma subquery;
Alguns tipos de dados no podem ser utilizados na lista de seleo de uma
subquery. So eles: nvarchar(max), varchar(max) e varbinary(max);
Um nico valor ser retornado ao utilizarmos o sinal de igualdade (=) no
incio da subquery;
200

Consultas com subqueries

As palavras-chave ALL, ANY e SOME podem ser utilizadas para modificar


operadores de comparao que introduzem uma subquery. Podemos fazer
as seguintes consideraes a respeito delas:
ALL realiza uma comparao entre um valor escalar e um conjunto
de valores de uma coluna. Ento, retornar TRUE nos casos em que a
comparao for verdadeira para todos os pares;
SOME (padro ISO que equivale a ANY) e ANY realizam uma comparao
entre um valor escalar e um conjunto de valores de uma coluna. Ento,
retornaro TRUE nos casos em que a comparao for verdadeira para
qualquer um dos pares.
Quando utilizamos um operador de comparao (=, < >, >, > =, <, ! >, ! <
ou < =) para introduzir uma subquery, sua lista de seleo poder incluir
apenas um nome de coluna ou expresso, a no ser que utilizemos IN na
lista ou EXISTS no SELECT;
As clusulas GROUP BY e HAVING no podem ser utilizadas em subqueries
introduzidas por um operador de comparao que no seja seguido pelas
palavras-chave ANY ou ALL;
A utilizao da clusula ORDER BY s possvel caso a clusula TOP seja
especificada;
Alternativamente, possvel formular muitas instrues do Transact-SQL
com subqueries como associaes;
O nome de coluna que, ocasionalmente, estiver presente na clusula WHERE
de uma query externa deve ser associvel com a coluna da lista de seleo
da subquery;
A qualificao dos nomes de colunas de uma instruo feita pela tabela
referenciada na clusula FROM;
Subqueries que incluem GROUP BY no aceitam a utilizao de DISTINCT;
Uma view no pode ser atualizada caso ela tenha sido criada com uma
subquery;

201

SQL - Mdulo I

Uma subquery aninhada na instruo SELECT externa formada por uma


clusula FROM regular com um ou mais nomes de view ou tabela, por uma
consulta SELECT regular junto dos componentes da lista de seleo regular
e pelas clusulas opcionais WHERE, HAVING e GROUP BY;
Subqueries podem ser utilizadas para realizar testes de existncia de linhas.
Nesse caso, adotado o operador EXISTS;
Por oferecer diversas formas de obter resultados, as subqueries eliminam
a necessidade de utilizao das clusulas JOIN e UNION de maior
complexidade;
Uma instruo que possui uma subquery no apresenta muitas diferenas de
performance em relao a uma verso semanticamente semelhante que no
possui a subquery. No entanto, uma JOIN apresenta melhor desempenho
nas situaes em que necessrio realizar testes de existncia;
As colunas de uma tabela no podero ser includas na sada, ou seja, na
lista de seleo da query externa, caso essa tabela aparea apenas em uma
subquery e no na query externa.
A seguir, temos os formatos normalmente apresentados pelas instrues que
possuem uma subquery:
WHERE expressao [NOT] IN (subquery);
WHERE expressao operador_comparacao [ANY | ALL] (subquery);
WHERE [NOT] EXISTS (subquery).

202

Consultas com subqueries

Veja um exemplo de subquery que verifica a existncia de clientes que compraram


no ms de janeiro de 2007:
SELECT * FROM CLIENTES
WHERE EXISTS (SELECT * FROM PEDIDOS
WHERE CODCLI = CLIENTES.CODCLI AND
DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31);
-- OU
SELECT * FROM CLIENTES
WHERE CODCLI IN (SELECT CODCLI FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31);

No prximo exemplo, verificada a existncia de clientes que no compraram


em janeiro de 2007:
SELECT * FROM CLIENTES
WHERE NOT EXISTS (SELECT * FROM PEDIDOS
WHERE CODCLI = CLIENTES.CODCLI AND
DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31);
-- OU
SELECT * FROM CLIENTES
WHERE CODCLI NOT IN (SELECT CODCLI FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31);

7.3.Subqueries introduzidas com IN



e NOT IN
Uma subquery ter como resultado uma lista de zero ou mais valores caso
tenha sido introduzida com a utilizao de IN ou NOT IN. O resultado, ento,
ser utilizado pela query externa.
Os exemplos adiante demonstram subqueries introduzidas com IN e NOT IN:

Exemplo 1
-- Lista de empregados cujo cargo tenha salrio inicial
-- inferior a 5000
SELECT * FROM EMPREGADOS
WHERE COD_CARGO IN (SELECT COD_CARGO FROM TABELACAR
WHERE SALARIO_INIC < 5000);

203

SQL - Mdulo I

Exemplo 2
-- Lista de departamentos em que no existe nenhum
-- funcionrio cadastrado
SELECT * FROM TABELADEP
WHERE COD_DEPTO NOT IN
(SELECT DISTINCT COD_DEPTO FROM EMPREGADOS
WHERE COD_DEPTO IS NOT NULL)
-- O mesmo que
SELECT
E.CODFUN, E.NOME, E.COD_DEPTO, E.COD_CARGO, D.COD_DEPTO,
D.DEPTO
FROM EMPREGADOS E RIGHT JOIN TABELADEP D ON E.COD_DEPTO = D.COD_
DEPTO
WHERE E.COD_DEPTO IS NULL

Exemplo 3
-- Lista de cargos em que no existe nenhum
-- funcionrio cadastrado
SELECT * FROM TABELACAR
WHERE COD_CARGO NOT IN
(SELECT DISTINCT COD_CARGO FROM EMPREGADOS
WHERE COD_CARGO IS NOT NULL)
-- O mesmo que
SELECT
C.COD_CARGO, C.CARGO
FROM EMPREGADOS E RIGHT JOIN TABELACAR C ON E.COD_CARGO = C.COD_
CARGO
WHERE E.COD_CARGO IS NULL

204

Consultas com subqueries

7.4.Subqueries introduzidas com



sinal de igualdade (=)
Veja exemplos de como utilizar o sinal de igualdade (=) para inserir subqueries:
Exemplo 1
-- Funcionrio(s) que ganha(m) menos
SELECT * FROM EMPREGADOS
WHERE SALARIO = (SELECT MIN(SALARIO) FROM Empregados)
-- o mesmo que
SELECT TOP 1 WITH TIES * FROM EMPREGADOS
WHERE SALARIO IS NOT NULL
ORDER BY SALARIO

Exemplo 2
-- Funcionrio mais novo na empresa
SELECT * FROM EMPREGADOS
WHERE DATA_ADMISSAO = (SELECT MAX(DATA_ADMISSAO) FROM EMPREGADOS);
-- O mesmo que
SELECT TOP 1 WITH TIES * FROM EMPREGADOS
ORDER BY DATA_ADMISSAO DESC;

7.5.Subqueries correlacionadas
Quando uma subquery possui referncia a uma ou mais colunas da query
externa, ela chamada de subquery correlacionada. uma subquery repetitiva,
pois executada uma vez para cada linha da query externa. Assim, os valores
das subqueries correlacionadas dependem da query externa, o que significa
que, para construir uma subquery desse tipo, ser necessrio criar tanto a query
interna como a externa.

205

SQL - Mdulo I

Tambm possvel que subqueries correlacionadas incluam, na clusula FROM,


funes definidas pelo usurio, as quais retornam valores de tipo de dado table.
Para isso, basta que colunas de uma tabela na query externa sejam referenciadas
como argumento de uma funo desse tipo. Ento, ser feita a avaliao dessa
funo de acordo com a subquery para cada linha da query externa.
Veja o exemplo a seguir, que grava, no campo SALARIO de cada funcionrio, o
valor de salrio inicial contido na tabela de cargos:
UPDATE EMPREGADOS SET SALARIO = (SELECT SALARIO_INIC FROM TABELACAR
WHERE COD_CARGO = EMPREGADOS.COD_CARGO);

7.5.1.Subqueries correlacionadas com EXISTS


Subqueries correlacionadas introduzidas com a clusula EXISTS no retornam
dados, mas apenas TRUE ou FALSE. Sua funo executar um teste de existncia
de linhas, portanto, se houver qualquer linha em uma subquery, ser retornado
TRUE.
Sobre EXISTS, importante atentarmos para os seguintes aspectos:
Antes de EXISTS no deve haver nome de coluna, constante ou expresso;
Quando EXISTS introduz uma subquery, sua lista de seleo ser,
normalmente, um asterisco.
Por meio do cdigo a seguir, possvel saber se temos clientes que no realizaram
compra no ms de janeiro de 2007:
SELECT * FROM CLIENTES
WHERE NOT EXISTS (SELECT * FROM PEDIDOS
WHERE CODCLI = CLIENTES.CODCLI AND
DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31);

206

Consultas com subqueries

7.6.Diferenas entre subqueries



e associaes
Ao comparar subqueries e associaes (JOINS), possvel constatar que as
associaes so mais indicadas para verificao de existncia, pois apresentam
desempenho melhor nesses casos. Tambm podemos verificar que, ao
contrrio das subqueries, as associaes no atuam em listas com um operador
de comparao modificado por ANY ou ALL, ou em listas que tenham sido
introduzidas com IN ou EXISTS.
Em alguns casos, pode ser que lidemos com questes muito complexas para
serem respondidas com associaes, ento, ser mais indicado usar subqueries.
Isso porque a visualizao do aninhamento e da organizao da query mais
simples em uma subquery, enquanto que, em uma consulta com diversas
associaes, a visualizao pode ser complicada. Alm disso, nem sempre as
associaes podem reproduzir os efeitos de uma subquery.
O cdigo a seguir utiliza JOIN para calcular o total vendido por cada vendedor
no perodo de janeiro de 2007 e a porcentagem de vendas em relao ao total
de vendas realizadas no mesmo ms:
SELECT P.CODVEN, V.NOME,
SUM(P.VLR_TOTAL) AS TOT_VENDIDO,
100 * SUM(P.VLR_TOTAL) / (SELECT SUM(VLR_TOTAL)
FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31) AS
PORCENTAGEM
FROM PEDIDOS P JOIN VENDEDORES V ON P.CODVEN = V.CODVEN
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY P.CODVEN, V.NOME;

207

SQL - Mdulo I

J o cdigo a seguir utiliza subqueries para calcular, para cada departamento,


o total de salrios dos funcionrios sindicalizados e o total de salrios dos no
sindicalizados:
SELECT COD_DEPTO,
(SELECT SUM(E.SALARIO) FROM Empregados E
WHERE E.SINDICALIZADO = S AND
E.COD_DEPTO = Empregados.COD_DEPTO) AS TOT_SALARIO_SIND,
(SELECT SUM(E.SALARIO) FROM Empregados E
WHERE E.SINDICALIZADO = N AND
E.COD_DEPTO = Empregados.COD_DEPTO) AS TOT_SALARIO_NAO_
SIND
FROM EMPREGADOS
GROUP BY COD_DEPTO;

7.7.Diferenas entre subqueries



e tabelas temporrias
Embora as tabelas temporrias sejam parecidas com as permanentes, elas
so armazenadas em tempdb e excludas automaticamente aps terem sido
utilizadas.
As tabelas temporrias locais apresentam antes do nome o smbolo # e so
visveis somente durante a conexo atual. Quando o usurio desconecta-se da
instncia do SQL Server, ela excluda.
J as tabelas temporrias globais apresentam antes do nome dois smbolos ## e
so visveis para todos os usurios. Uma tabela desse tipo ser excluda apenas
quando todos os usurios que a referenciam se desconectarem da instncia do
SQL Server.

208

Consultas com subqueries

A escolha da utilizao de tabelas temporrias ou de subqueries depender de


cada situao e de aspectos como desempenho do sistema e at mesmo das
preferncias pessoais de cada usurio. O fato que, por conta das diferenas
existentes entre elas, o uso de uma, para uma situao especfica, acaba sendo
mais indicado do que o emprego de outra.
Assim, quando temos bastante RAM, as subqueries so preferveis, pois
ocorrem na memria. J as tabelas temporrias, como necessitam dos recursos
disponibilizados pelo disco rgido para serem executadas, so indicadas nas
situaes em que o(s) servidor(es) do banco de dados apresenta(m) bastante
espao no disco rgido.
H, ainda, uma importante diferena entre tabela temporria e subquery:
normalmente, esta ltima mais fcil de manter. No entanto, se a subquery
for muito complexa, a melhor medida a ser tomada pode ser fragment-la em
diversas tabelas temporrias, criando, assim, blocos de dados de tamanho
menor.
Veja o exemplo a seguir, que utiliza subqueries para retornar os pedidos da
vendedora LEIA para clientes de SP que no compraram em janeiro de 2007,
mas compraram em dezembro de 2006:
SELECT * FROM PEDIDOS
WHERE CODVEN IN (SELECT CODVEN FROM VENDEDORES WHERE NOME =
LEIA)
AND CODCLI IN (
SELECT CODCLI FROM CLIENTES
WHERE CODCLI NOT IN (SELECT CODCLI FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN
2007.1.1 AND 2007.1.31)
AND
CODCLI IN (SELECT CODCLI FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN
2006.12.1
AND 2006.12.31)
AND ESTADO = SP );

209

SQL - Mdulo I

J no prximo cdigo, em vez de subqueries, utilizamos tabelas temporrias


para obter o mesmo resultado do cdigo anterior:
-- Tabela temporria 1 - Cdigo da vendedora LEIA
SELECT CODVEN INTO #VEND_LEIA FROM VENDEDORES WHERE NOME = LEIA;
-- Tabela temporria 2 - Clientes que compraram em Jan/2007
SELECT CODCLI INTO #CLI_COM_PED_JAN_2007 FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31;
-- Tabela temporria 3 - Clientes que compraram em Dez/2006
SELECT CODCLI INTO #CLI_COM_PED_DEZ_2006 FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2006.12.1 AND 2006.12.31;
-- Tabela temporria 4 - Clientes de SP que compraram em
Dez/2006, mas
-- no compraram em Jan de 2007
SELECT CODCLI INTO #CLI_FINAL FROM CLIENTES
WHERE CODCLI NOT IN (SELECT CODCLI FROM #CLI_COM_PED_JAN_2007)
AND
CODCLI IN (SELECT CODCLI FROM #CLI_COM_PED_DEZ_2006)
AND
ESTADO = SP;
-- SELECT de PEDIDOS
SELECT * FROM PEDIDOS
WHERE CODVEN IN (SELECT CODVEN FROM #VEND_LEIA)
AND
CODCLI IN (SELECT CODCLI FROM #CLI_FINAL);

210

Consultas com subqueries

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
Uma consulta aninhada em uma instruo SELECT, INSERT, DELETE ou
UPDATE denominada subquery (subconsulta). As subqueries so tambm
referidas como queries internas. J a instruo em que est inserida a
subquery pode ser chamada de query externa;
Vejamos algumas das diversas caractersticas das subqueries: podem ser
escalares (retornam apenas uma linha) ou tabulares (retornam linhas e
colunas). Elas, que podem ser includas dentro de outras subqueries, devem
estar entre parnteses, o que as diferenciar da consulta principal;
Uma subquery retornar uma lista de zero ou mais valores caso tenha sido
introduzida com a utilizao de IN ou NOT IN. O resultado, ento, ser
utilizado pela query externa;
O sinal de igualdade (=) pode ser utilizado para inserir subqueries;
Quando uma subquery possui referncia a uma ou mais colunas da query
externa, ela chamada de subquery correlacionada. Trata-se de uma
subquery repetitiva, pois executada uma vez para cada linha da query
externa. Desta forma, os valores das subqueries correlacionadas dependem
da query externa, o que significa que, para construir uma subquery desse
tipo, ser necessrio criar tanto a query interna como a externa;
Ao comparar subqueries e associaes (JOINS), possvel constatar que
as associaes so mais indicadas para verificao de existncia, pois
apresentam desempenho melhor nesses casos;
A visualizao do aninhamento e da organizao da query mais simples em
uma subquery, enquanto que, em uma consulta com diversas associaes,
a visualizao pode ser complicada;

211

SQL - Mdulo I
Tabelas temporrias so armazenadas no
automaticamente aps terem sido utilizadas;

tempdb

excludas

As tabelas temporrias locais apresentam antes do nome o smbolo # e so


visveis somente durante a conexo atual. Quando o usurio desconecta-se
da instncia do SQL Server, ela excluda. J as tabelas temporrias globais
apresentam antes do nome dois smbolos ## e so visveis para todos os
usurios. Uma tabela desse tipo ser excluda apenas quando todos os
usurios que a referenciam se desconectarem da instncia do SQL Server;
A escolha da utilizao de tabelas temporrias ou subqueries depender de
cada situao e de aspectos como desempenho do sistema e at mesmo
das preferncias pessoais de cada usurio.

212

Consultas com
subqueries
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Trabalhando com JOIN e subquery
1. Coloque em uso o banco de dados CURSOS_INFORMATICA. Em seguida,
insira os dados presentes nos arquivos Cap07_Lab01_INSERT_MUNIC.sql e
Cap07_Lab01_INSERTS;
2. Apresente todas as salas de aula para as quais no h nenhum curso marcado;
3. Apresente todos os treinamentos para os quais no h instrutor;
4. Apresente os alunos (CAD_PESSOAS) que no tm e nem tiveram cursos
agendados;
5. Apresente os departamentos que no possuem funcionrios cadastrados;
6. Apresente os cargos para os quais no existem funcionrios cadastrados;
7. Apresente as pessoas que sejam de estados cujo ICMS seja menor que 7;
8. Apresente os dados do instrutor que possui o maior valor hora (VLR_HORA);
9. Apresente os dados do instrutor que possui o menor valor hora (VLR_HORA).

214

Atualizando e
excluindo dados
em associaes
e subqueries

99 UPDATE com subqueries;


99 DELETE com subqueries;
99 UPDATE com JOIN;
99 DELETE com JOIN.

SQL - Mdulo I

8.1.UPDATE com subqueries


Ao utilizarmos a instruo UPDATE em uma subquery, ser possvel atualizar
linhas de uma tabela com informaes provenientes de outra tabela. Para isso,
na clusula WHERE da instruo UPDATE, em vez de usar como critrio para
a operao de atualizao a origem explcita da tabela, basta utilizar uma
subquery.
Veja os dois cdigos a seguir. Ambos utilizam UPDATE com subquery. No
primeiro cdigo, o comando para aumentar em 10% os salrios dos empregados
do departamento C.P.D. No segundo, o preo de venda atualizado para que
fique 20% acima do preo de custo de todos os produtos do tipo REGUA:
UPDATE EMPREGADOS
SET SALARIO = SALARIO * 1.10
WHERE COD_DEPTO = (SELECT COD_DEPTO FROM TABELADEP
WHERE DEPTO = C.P.D.);
UPDATE PRODUTOS SET PRECO_VENDA = PRECO_CUSTO * 1.2
WHERE COD_TIPO = (SELECT COD_TIPO FROM TIPOPRODUTO
WHERE TIPO = REGUA);

8.2.DELETE com subqueries


Podemos utilizar subqueries para remover dados de uma tabela. Basta definir
a clusula WHERE da instruo DELETE como uma subquery. Isso ir excluir
linhas de uma tabela base conforme os dados armazenados em outra tabela.
Veja o prximo exemplo, que elimina os pedidos do vendedor MARCELO que
foram emitidos na primeira quinzena de dezembro de 2006:
DELETE FROM PEDIDOS
WHERE DATA_EMISSAO BETWEEN 2006.12.1 AND 2006.12.15 AND
CODVEN = (SELECT CODVEN FROM VENDEDORES WHERE NOME = MARCELO);

216

Atualizando e excluindo dados em associaes e subqueries

8.3.UPDATE com JOIN


Podemos usar uma associao em tabelas para determinar quais colunas sero
atualizadas por meio de UPDATE. No exemplo a seguir, aumentaremos em 10%
os salrios dos empregados do departamento C.P.D.:
UPDATE Empregados
SET SALARIO *= 1.10
FROM EMPREGADOS E JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
WHERE D.DEPTO = C.P.D.;

J o prximo cdigo atualiza o preo de venda para 20% acima do preo de


custo de todos os produtos do tipo REGUA:
UPDATE PRODUTOS SET PRECO_VENDA = PRECO_CUSTO * 1.2
FROM PRODUTOS P JOIN TIPOPRODUTO T ON P.COD_TIPO = T.COD_TIPO
WHERE T.TIPO = REGUA;

8.4.DELETE com JOIN


Os dados provenientes de tabelas associadas podem ser eliminados por meio
da clusula JOIN junto ao comando DELETE. Veja o seguinte exemplo, que
exclui os pedidos do vendedor MARCELO emitidos na primeira quinzena de
dezembro de 2006:
DELETE FROM PEDIDOS
FROM PEDIDOS P JOIN VENDEDORES V ON P.CODVEN = V.CODVEN
WHERE P.DATA_EMISSAO BETWEEN 2006.12.1 AND 2006.12.15 AND
V.NOME = MARCELO;

217

SQL - Mdulo I

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
O uso da instruo UPDATE em uma subquery permite atualizar linhas de
uma tabela com informaes provenientes de outra tabela;
Subqueries podem ser utilizadas com o intuito de remover dados de uma
tabela. Basta definirmos a clusula WHERE da instruo DELETE como
uma subquery para excluir linhas de uma tabela base conforme os dados
armazenados em uma outra tabela;
Podemos utilizar uma associao (JOIN) em tabelas para determinar quais
colunas sero atualizadas por meio de UPDATE;
Os dados de tabelas associadas podem ser eliminados por meio da clusula
JOIN com o comando DELETE.

218

Atualizando
e excluindo dados
em associaes
e subqueries
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Atualizando tabelas com associaes e subqueries
1. Coloque em uso o banco e dados PEDIDOS;
2. Altere a tabela TABELACAR, mudando o salrio inicial do cargo OFFICE BOY
para 600,00;
3. Altere a tabela de cargos, estipulando 10% de aumento para o campo
SALARIO_INIC de todos os cargos;
4. Transfira para o campo SALARIO da tabela EMPREGADOS o salrio inicial
cadastrado no cargo correspondente da TABELACAR;
5. Reajuste os preos de venda de todos os produtos de modo que fiquem 30%
acima do preo de custo (PRECO_VENDA = PRECO_CUSTO * 1.3);
6. Reajuste os preos de venda dos produtos com COD_TIPO = 5, de modo que
fiquem 20% acima do preo custo;
7. Reajuste os preos de venda dos produtos com descrio do tipo igual
REGUA, de modo que fiquem 40% acima do preo custo. Para isso, considere
as seguintes informaes:
PRECO_VENDA = PRECO_CUSTO * 1.4;
Para produtos com TIPOPRODUTO.TIPO = REGUA;
necessrio fazer um JOIN de PRODUTOS com TIPOPRODUTO */.
8. Altere a tabela ITENSPEDIDO de modo que todos os itens com produto
indicado como VERMELHO passem a ser LARANJA. Considere somente os
pedidos com data de entrega em Outubro de 2007;
9. Altere o campo ICMS tabela CLIENTES para 12. Considere apenas clientes
dos estados: RJ, RO, AC, RR, MG, PR, SC, RS, MS e MT;

220

Atualizando e excluindo dados em associaes e subqueries

10. Altere o campo ICMS para 18, apenas para clientes de SP;
11. Altere o campo ICMS da tabela CLIENTES para 7. Considere apenas clientes
que no sejam dos estados: RJ, RO, AC, RR, MG, PR, SC, RS, MS, MT e SP;
12. Crie a tabela ESTADOS com os respectivos campos:
COD_ESTADO: Inteiro, autonumerao e chave primria;
SIGLA: Char(2);
ICMS: Numrico, tamanho 4 com 2 decimais.
13. Copie os dados coletados do seguinte comando SELECT para a tabela
ESTADOS utilizando um comando INSERT:
SELECT DISTINCT ESTADO, ICMS FROM CLIENTES
WHERE ESTADO IS NOT NULL

O SELECT deve retornar 21 linhas e no repetir o Estado. Se o resultado


for diferente, porque os UPDATES de ICMS esto incorretos.

14. Crie o campo COD_ESTADO na tabela CLIENTES;


15. Copie para CLIENTES.COD_ESTADO o cdigo do Estado gerado na tabela
ESTADOS.

221

Agrupando dados

99 Funes de agregao;
99 Funes de cadeia de caracteres;
99 GROUP BY.

SQL - Mdulo I

9.1.Introduo
Neste captulo, voc aprender como a clusula GROUP BY pode ser utilizada
para agrupar vrios dados, tornando mais prtica sua sumarizao. Tambm
ver como utilizar funes de agregao para sumarizar dados e como a clusula
GROUP BY pode ser usada com a clusula HAVING e com os operadores ALL,
WITH ROLLUP e CUBE.

9.2.Funes de agregao
As funes de agregao fornecidas pelo SQL Server permitem sumarizar dados.
Por meio delas, podemos somar valores, calcular mdia e contar a quantidade
de linhas sumarizadas. Os clculos feitos pelas funes de agregao so feitos
com base em um conjunto ou grupo de valores, mas retornam um nico valor.

Para obter os valores sobre os quais poder realizar os clculos, as funes de
agregao geralmente so utilizadas com a clusula GROUP BY. Quando no
h uma clusula GROUP BY, os grupos de valores podem ser obtidos de uma
tabela inteira filtrada pela clusula WHERE.
Ao utilizar funes de agregao, preciso prestar ateno a valores NULL. A
maioria das funes ignora esses valores, o que pode gerar resultados inesperados.

Alm de utilizar as funes de agregao fornecidas pelo SQL Server,


h a possibilidade de criar funes personalizadas.

224

Agrupando dados

9.2.1.Tipos de funo de agregao


A seguir, so descritas as principais funes de agregao fornecidas pelo SQL
Server:
AVG ( [ ALL | DISTINCT ] expresso)
Esta funo calcula o valor mdio do parmetro expresso em determinado
grupo, ignorando valores NULL. Os parmetros opcionais ALL e DISTINCT so
utilizados para especificar se a agregao ser executada em todos os valores
do campo (ALL) ou aplicada apenas sobre valores distintos (DISTINCT);
Veja um exemplo:
USE PEDIDOS;
-- neste caso, o grupo corresponde a toda a tabela EMPREGADOS
SELECT AVG(SALARIO) AS SALARIO_MEDIO
FROM EMPREGADOS;
-- neste caso o grupo corresponde aos empregados com --- COD_DEPTO = 2
SELECT AVG(SALARIO) AS SALARIO_MEDIO FROM EMPREGADOS
WHERE COD_DEPTO = 2;

COUNT ( { [ ALL | DISTINCT ] expresso | * } )


Esta funo utilizada para retornar a quantidade de registros existentes no
nulos em um grupo. Ao especificar o parmetro ALL, a funo no retornar
valores nulos. Os parmetros de COUNT tm a mesma funo dos parmetros
de AVG.

225

SQL - Mdulo I

Veja um exemplo:
-- neste caso, o grupo corresponde a toda a tabela EMPREGADOS
SELECT COUNT(*) AS QTD_EMPREGADOS
FROM EMPREGADOS;
-- neste caso o grupo corresponde aos empregados com --- COD_DEPTO = 2
SELECT COUNT(COD_DEPTO) AS QTD_EMPREGADOS FROM EMPREGADOS
WHERE COD_DEPTO = 2;

Se colocarmos o nome de um campo como argumento da funo


COUNT, no sero contados os registros em que o contedo desse
campo seja NULL.

MIN ( [ ALL | DISTINCT ] expresso)


Esta funo retorna o menor valor no nulo de expresso existente em um
grupo. Os parmetros de MIN tm a mesma funo dos parmetros de AVG.
Veja um exemplo:
-- neste caso, o grupo corresponde a toda a tabela EMPREGADOS
SELECT MIN(SALARIO) AS MENOR_SALARIO FROM EMPREGADOS;
-- neste caso o grupo corresponde aos empregados com --- COD_DEPTO = 2
SELECT MIN(SALARIO) AS MENOR_SALARIO FROM EMPREGADOS
WHERE COD_DEPTO = 2

226

Agrupando dados

MAX ( [ ALL | DISTINCT ] expresso


Esta funo retorna o maior valor no nulo de expresso existente em um
grupo. Os parmetros de MAX tm a mesma funo dos parmetros de AVG.
Veja um exemplo:
-- neste caso, o grupo corresponde a toda a tabela EMPREGADOS
SELECT MAX(SALARIO) AS MAIOR_SALARIO
FROM EMPREGADOS;
-- neste caso o grupo corresponde aos empregados com --- COD_DEPTO = 2
SELECT MAX(SALARIO) AS MAIOR_SALARIO FROM EMPREGADOS
WHERE COD_DEPTO = 2

SUM ( [ ALL | DISTINCT ] expresso)


Esta funo realiza a soma de todos os valores no nulos na expresso em
um determinado grupo. Os parmetros de SUM tm a mesma funo dos
parmetros de AVG.
Veja um exemplo:
-- neste caso, o grupo corresponde a toda a tabela EMPREGADOS
SELECT SUM(SALARIO) AS SOMA_SALARIOS
FROM EMPREGADOS;
-- neste caso o grupo corresponde aos empregados com --- COD_DEPTO = 2
SELECT SUM(SALARIO) AS SOMA_SALARIOS FROM EMPREGADOS
WHERE COD_DEPTO = 2

227

SQL - Mdulo I

9.3.Funes de cadeia de caracteres


Estas funes executam operaes em um valor de entrada de cadeia de
caracteres e retornam o mesmo dado trabalhado. Por exemplo, podemos
concatenar, replicar ou inverter os dados de entrada. A seguir, vamos apresentar
as funes de cadeia de caracteres principais fornecidas pelo SQL Server:
LEN (expresso_string)
Esta funo retorna o nmero de caracteres especificado no parmetro
expresso_string.
Veja um exemplo:
SELECT LEN (Brasil);

REPLICATE (expresso_string, mult)


Esta funo repete os caracteres do parmetro expresso_string pelo nmero
de vezes especificado no parmetro mult.
Veja um exemplo:
SELECT REPLICATE (Teste,4);

228

Agrupando dados

REVERSE (expresso_string)
Esta funo retorna a ordem inversa do parmetro expresso_string.
Veja um exemplo:
SELECT REVERSE (amina);

STR ( nmero [, tamanho [, decimal] ] )


Esta funo retorna dados do tipo string a partir de dados numricos.
Veja um exemplo:
SELECT STR (213);

SUBSTRING (expresso, incio, tamanho)


Esta funo retorna uma parte dos caracteres do parmetro expresso a partir
dos valores de incio e tamanho.
Veja um exemplo:
SELECT SUBSTRING (Paraleleppedo,3,7);

229

SQL - Mdulo I

CONCAT (expr1, expr2 [, exprN])


Esta funo concatena as expresses retornando um string. As expresses
podem ser de qualquer tipo.
Veja um exemplo:
SELECT CONCAT (SQL ,mdulo ,I);

FORMAT (expresso, formato)


Formata uma expresso numrica ou date/time no formato definido por um
string de formatao.
A seguir, temos alguns exemplos de caracteres usados na formatao de strings:
Caracteres para formatao de nmeros:

0 (zero)

Define uma posio numrica.


Se no existir nmero na
posio, aparece o zero.

Define uma posio numrica.


Se no existir nmero na
posio, fica vazio.

. (ponto)

Separador de decimal.

, (vrgula)

Separador de milhar.

Mostra o sinal e o nmero


multiplicado por 100.

Qualquer outro caractere inserido na mscara de formatao ser


exibido normalmente na posio em que foi colocado.

230

Agrupando dados

Caracteres para formatao de data:


d

Dia com 1 ou 2 dgitos.

dd

Dia com 2 dgitos.

ddd

Abreviao do dia da semana.

dddd

Nome do dia da semana.

Ms com 1 ou 2 dgitos.

MM

Ms com 2 dgitos.

MMM

Abreviao do nome do ms.

MMMM

Nome do ms.

yy

Ano com 2 dgitos.

yyyy

Ano com 4 dgitos.

hh

Hora de 1 a 12.

HH

Hora de 0 a 23.

mm

Minutos.

ss

Segundos.

fff

milsimos de segundo.

Veja um exemplo:
SELECT FORMAT (GETDATE(), dd/MM/yyyy);

231

SQL - Mdulo I

9.4.GROUP BY
Utilizando a clusula GROUP BY, possvel agrupar diversos registros com
base em uma ou mais colunas da tabela.
Esta clusula responsvel por determinar em quais grupos devem ser colocadas
as linhas de sada. Caso a clusula SELECT contenha funes de agregao, a
clusula GROUP BY realiza um clculo a fim de chegar ao valor sumrio para
cada um dos grupos.
Quando especificar a clusula GROUP BY, deve ocorrer uma das seguintes
situaes: a expresso GROUP BY deve ser correspondente expresso da
lista de seleo ou cada uma das colunas presentes em uma expresso no
agregada na lista de seleo deve ser adicionada lista de GROUP BY.
Ao utilizar uma clusula GROUP BY, todas as colunas na lista SELECT que no
so parte de uma expresso agregada sero usadas para agrupar os resultados
obtidos. Para no agrupar os resultados em uma coluna, no se deve coloc-los
na lista SELECT. Valores NULL so agrupados todos em uma mesma coluna, j
que so considerados iguais.
Quando utilizamos a clusula GROUP BY, mas no empregamos a clusula
ORDER BY, o resultado obtido so os grupos em ordem aleatria, visto que
essencial o uso de ORDER BY para determinar a ordem de apresentao dos
dados.
Observe, a seguir, a sintaxe da clusula GROUP BY:
[ GROUP BY [ ALL ] expressao_group_by [ ,...n ]
[HAVING <condicaoFiltroGrupo>]]

Em que:
ALL a palavra que determina a incluso de todos os grupos e conjuntos
de resultados. Vale destacar que valores nulos so retornados s colunas
resultantes dos grupos que no correspondem aos critrios de busca quando
ALL especificada;

232

Agrupando dados

expressao_group_by: Tambm conhecida como coluna agrupada, uma


expresso na qual o agrupamento realizado. Pode ser especificada como
uma coluna ou como uma expresso no agregada que faz referncia
coluna que a clusula FROM retornou, mas no possvel especific-la
como um alias de coluna determinado na lista de seleo. Alm disso, no
podemos utilizar em expressao_group_by as colunas de um dos seguintes
tipos: image, text e ntext;
[HAVING <condicaoFiltroGrupo>]: Determina uma condio de busca para
um grupo ou um conjunto de registros. Essa condio especificada em
<condicaoFiltroGrupo>.
Observe o resultado da instruo:
SELECT COD_DEPTO, SALARIO FROM EMPREGADOS ORDER BY COD_DEPTO;

Veja que o campo COD_DEPTO se repete e, portanto, forma grupos. Em uma


situao dessas, podemos gerar totalizaes para cada um dos grupos utilizando
a clusula GROUP BY.

233

SQL - Mdulo I

A seguir, veja exemplos da utilizao de GROUP BY:


Exemplo 1
-- Total de salrio de cada departamento
SELECT COD_DEPTO, SUM( SALARIO ) AS TOT_SAL
FROM EMPREGADOS
GROUP BY COD_DEPTO
ORDER BY TOT_SAL;

Exemplo 2
-- GROUP BY + JOIN
SELECT E.COD_DEPTO, D.DEPTO, SUM( E.SALARIO ) AS TOT_SAL
FROM EMPREGADOS E
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
GROUP BY E.COD_DEPTO, D.DEPTO
ORDER BY TOT_SAL;

Exemplo 3
-- Consulta do tipo RANKING utilizando TOP n + ORDER BY
-- Os 5 departamentos que mais gastam com salrios
SELECT TOP 5 E.COD_DEPTO, D.DEPTO, SUM( E.SALARIO ) AS TOT_SAL
FROM EMPREGADOS E
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
GROUP BY E.COD_DEPTO, D.DEPTO
ORDER BY TOT_SAL DESC;

Exemplo 4
-- Os 10 clientes que mais compraram em Janeiro de 2007
SELECT TOP 10 C.CODCLI, C.NOME, SUM(P.VLR_TOTAL) AS TOT_COMPRADO
FROM PEDIDOS P JOIN CLIENTES C ON P.CODCLI = C.CODCLI
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY C.CODCLI, C.NOME
ORDER BY TOT_COMPRADO DESC;

234

Agrupando dados

9.4.1.Utilizando ALL
ALL inclui todos os grupos e conjuntos de resultados. A seguir, veja um exemplo
da utilizao de ALL:
-- Clientes que compraram em janeiro de 2007. Veremos que
-- todas as linhas do resultado tero um total no nulo.
SELECT C.CODCLI, C.NOME, SUM(P.VLR_TOTAL) AS TOT_COMPRADO
FROM PEDIDOS P JOIN CLIENTES C ON P.CODCLI = C.CODCLI
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY C.CODCLI, C.NOME;
-- Neste caso, aparecero tambm os clientes que no
-- compraram. Totais estaro nulos
SELECT C.CODCLI, C.NOME, SUM(P.VLR_TOTAL) AS TOT_COMPRADO
FROM PEDIDOS P JOIN CLIENTES C ON P.CODCLI = C.CODCLI
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY ALL C.CODCLI, C.NOME;

9.4.2.Utilizando HAVING
A clusula HAVING determina uma condio de busca para um grupo ou um
conjunto de registros, definindo critrios para limitar os resultados obtidos a
partir do agrupamento de registros. Ela utilizada para estreitar um conjunto de
resultados por meio de critrios e valores agregados e para filtrar linhas aps o
agrupamento ter sido feito e antes dos resultados serem retornados ao cliente.
importante lembrar que essa clusula s pode ser utilizada em parceria com
GROUP BY. Se uma consulta feita sem GROUP BY, a clusula HAVING pode
ser usada como clusula WHERE.

A clusula HAVING diferente da clusula WHERE. Esta ltima


restringe os resultados obtidos aps a aplicao da clusula FROM,
ao passo que a clusula HAVING filtra o retorno do agrupamento.

235

SQL - Mdulo I

O cdigo do exemplo a seguir utiliza a clusula HAVING para consultar os


departamentos que totalizam mais de R$ 100.000,00 em salrios:
SELECT E.COD_DEPTO, D.DEPTO, SUM( E.SALARIO ) AS TOT_SAL
FROM EMPREGADOS E
JOIN TABELADEP D ON E.COD_DEPTO = D.COD_DEPTO
GROUP BY E.COD_DEPTO, D.DEPTO HAVING SUM(E.SALARIO) > 100000
ORDER BY TOT_SAL;

O prximo cdigo consulta os clientes que compraram mais de R$ 5.000,00


em janeiro de 2007:
SELECT C.CODCLI, C.NOME, SUM(P.VLR_TOTAL) AS TOT_COMPRADO
FROM PEDIDOS P JOIN CLIENTES C ON P.CODCLI = C.CODCLI
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY C.CODCLI, C.NOME HAVING SUM(P.VLR_TOTAL) > 5.000
ORDER BY TOT_COMPRADO;

J o prximo cdigo consulta os clientes que no realizaram compras em janeiro


de 2007:
SELECT C.CODCLI, C.NOME, SUM(P.VLR_TOTAL) AS TOT_COMPRADO
FROM PEDIDOS P JOIN CLIENTES C ON P.CODCLI = C.CODCLI
WHERE P.DATA_EMISSAO BETWEEN 2007.1.1 AND 2007.1.31
GROUP BY ALL C.CODCLI, C.NOME HAVING SUM(P.VLR_TOTAL) IS NULL;

9.4.3.Utilizando WITH ROLLUP


Esta clusula determina que, alm das linhas normalmente retornadas por
GROUP BY, tambm sejam obtidas como resultado as linhas de sumrio. O
sumrio dos grupos feito em uma ordem hierrquica, a partir do nvel mais
baixo at o mais alto. A ordem que define a hierarquia do grupo determinada
pela ordem na qual so definidas as colunas agrupadas. Caso essa ordem seja
alterada, a quantidade de linhas produzidas pode ser afetada.
Utilizada em parceria com a clusula GROUP BY, a clusula WITH ROLLUP
acrescenta uma linha na qual so exibidos os subtotais e totais dos registros j
distribudos em colunas agrupadas.

236

Agrupando dados

Suponha que est trabalhando em um banco de dados com as seguintes


caractersticas:
O cadastro de produtos est organizado em categorias (tipos);
H vrios produtos que pertencem a uma mesma categoria;
As categorias de produtos so armazenadas na tabela TIPOPRODUTO.
O SELECT a seguir mostra as vendas de cada categoria de produto
(TIPOPROODUTO) que os vendedores (tabela VENDEDORES) realizaram para
cada cliente (tabela CLIENTES) no primeiro semestre de 2006:
SELECT
V.NOME AS VENDEDOR, C.NOME AS CLIENTE,
T.TIPO AS TIPO_PRODUTO, SUM( I.QUANTIDADE ) AS QTD_TOT
FROM
PEDIDOS Pe JOIN CLIENTES C ON Pe.CODCLI = C.CODCLI
JOIN VENDEDORES V ON Pe.CODVEN = V.CODVEN
JOIN ITENSPEDIDO I ON Pe.NUM_PEDIDO = I.NUM_PEDIDO
JOIN PRODUTOS Pr ON I.ID_PRODUTO = Pr.ID_PRODUTO
JOIN TIPOPRODUTO T ON Pr.COD_TIPO = T.COD_TIPO
WHERE Pe.DATA_EMISSAO BETWEEN 2006.1.1 AND 2006.6.30
GROUP BY V.NOME , C.NOME, T.TIPO;

Suponha que o resultado retornado seja o seguinte:

Note que um dos vendedores CELSON MARTINS e que alguns de seus clientes
so 3R (ARISTEU.ADALTON) e ALLAN HEBERT RELOGIOS E PRESENTES.
Tambm perceber, por exemplo, que o cliente 3R (ARISTEU.ADALTON) comprou
111 unidades de produtos do tipo ACES.CHAVEIRO do vendedor CELSON
MARTINS, enquanto ALLAN HEBERT RELOGIOS E PRESENTES comprou 153
produtos do tipo CANETA do mesmo vendedor.
237

SQL - Mdulo I
Terminados os registros de vendas do CELSON MARTINS, iniciam-se os registros
de venda do prximo vendedor, e assim por diante, como voc pode ver a seguir:

Agora, acrescente a clusula WITH ROLLUP aps a linha de GROUP BY. O cdigo
anterior ficar assim:
SELECT
V.NOME AS VENDEDOR, C.NOME AS CLIENTE,
T.TIPO AS TIPO_PRODUTO, SUM( I.QUANTIDADE ) AS QTD_TOT
FROM
PEDIDOS Pe JOIN CLIENTES C ON Pe.CODCLI = C.CODCLI
JOIN VENDEDORES V ON Pe.CODVEN = V.CODVEN
JOIN ITENSPEDIDO I ON Pe.NUM_PEDIDO = I.NUM_PEDIDO
JOIN PRODUTOS Pr ON I.ID_PRODUTO = Pr.ID_PRODUTO
JOIN TIPOPRODUTO T ON Pr.COD_TIPO = T.COD_TIPO
WHERE Pe.DATA_EMISSAO BETWEEN 2006.1.1 AND 2006.6.30
GROUP BY V.NOME , C.NOME, T.TIPO
WITH ROLLUP;

O resultado ser o seguinte:

Observe na figura anterior que, aps a ltima linha do vendedor CELSON


MARTINS, existe um NULL na coluna TIPO_PRODUTO, o que significa que
o valor apresentado na coluna QTD_TOT corresponde ao total vendido pelo
esse vendedor para o cliente 3R (ARISTEU.ADALTON), ou seja, a coluna TIPO_
PRODUTO (NULL) no foi considerada para a totalizao. Isso se repetir at o
ltimo cliente que comprou de CELSON MARTINS.
238

Agrupando dados

Antes de iniciar as totalizaes do vendedor seguinte, existe uma linha na


qual apenas o nome do vendedor no NULL, o que significa que o total
apresentado na coluna QTD_TOT representa o total vendido pelo vendedor
CELSON MARTINS, ou seja, 55912 produtos, independentemente do cliente e
do tipo de produto:

Na ltima linha do resultado, temos NULL nas 3 primeiras colunas. O


total corresponde ao total vendido (1022534) no perodo mencionado,
independentemente do vendedor, do cliente ou do tipo de produto:

9.4.4.Utilizando WITH CUBE


A clusula WITH CUBE tem a finalidade de determinar que as linhas de sumrio
sejam inseridas no conjunto de resultados. A linha de sumrio retornada para
cada combinao possvel de grupos e de subgrupos no conjunto de resultados.
Visto que a clusula WITH CUBE responsvel por retornar todas as combinaes
possveis de grupos e de subgrupos, a quantidade de linhas no est relacionada
ordem em que so determinadas as colunas de agrupamento, sendo, portanto,
mantida a quantidade de linhas j apresentada.
A quantidade de linhas de sumrio no conjunto de resultados especificada
de acordo com a quantidade de colunas includas na clusula GROUP BY. Cada
uma dessas colunas vinculada sob o valor NULL do agrupamento, o qual
aplicado a todas as outras colunas.
A clusula WITH CUBE, em conjunto com GROUP BY, gera totais e subtotais,
apresentando vrios agrupamentos de acordo com as colunas definidas com
GROUP BY.

239

SQL - Mdulo I
Para explicar o que faz WITH CUBE, considere o exemplo utilizado para WITH
ROLLUP. No lugar desta ltima clusula, utilize WITH CUBE. O cdigo ficar
assim:
SELECT
V.NOME AS VENDEDOR, C.NOME AS CLIENTE,
T.TIPO AS TIPO_PRODUTO, SUM( I.QUANTIDADE ) AS QTD_TOT
FROM
PEDIDOS Pe JOIN CLIENTES C ON Pe.CODCLI = C.CODCLI
JOIN VENDEDORES V ON Pe.CODVEN = V.CODVEN
JOIN ITENSPEDIDO I ON Pe.NUM_PEDIDO = I.NUM_PEDIDO
JOIN PRODUTOS Pr ON I.ID_PRODUTO = Pr.ID_PRODUTO
JOIN TIPOPRODUTO T ON Pr.COD_TIPO = T.COD_TIPO
WHERE Pe.DATA_EMISSAO BETWEEN 2006.1.1 AND 2006.6.30
GROUP BY V.NOME , C.NOME, T.TIPO
WITH CUBE;

O resultado o seguinte:

Esse tipo de resultado no existia com a opo WITH ROLLUP. Neste caso,
a coluna VENDEDOR NULL e o total corresponde ao total de produtos do
tipo ABRIDOR comprado pelo cliente ABILIO (20 produtos). J ALAMBRINDES
GRAFICA EDITORA LTDA comprou 2200 produtos do tipo ABRIDOR. WITH
CUBE inclui todas as outras subtotalizaes possveis no resultado.
Neste outro trecho do mesmo resultado retornado, as colunas VENDEDOR e
CLIENTE so nulas e o total corresponde ao total vendido de produtos do tipo
CANETA, ou seja, 526543:

Seguindo a mesma regra, se apenas o CLIENTE no nulo, o total corresponde


ao total comprado por este cliente, independentemente de vendedor ou de
produto:

240

Agrupando dados

Pontos principais
Atente para os tpicos a seguir. Eles devem ser estudados com muita
ateno, pois representam os pontos mais importantes do captulo.
As funes de agregao fornecidas pelo SQL Server permitem sumarizar
dados. Por meio delas, possvel somar valores, calcular mdia e contar
resultados. Os clculos feitos pelas funes de agregao so feitos com
base em um conjunto ou grupo de valores, porm retornam um nico
valor. Para obter os valores sobre os quais voc poder realizar os clculos,
geralmente so utilizadas as funes de agregao com a clusula GROUP
BY;
Utilizando a clusula GROUP BY, possvel agrupar diversos registros com
base em uma ou mais colunas da tabela.

241

Agrupando dados
Mos obra!

SQL - Mdulo I

Laboratrio 1
A Realizando consultas e ordenando dados
1. Coloque em uso o banco de dados PEDIDOS;
2. Calcule a mdia de preo de venda (PRECO_VENDA) do cadastro de
PRODUTOS;
3. Calcule a quantidade de pedidos cadastrados em janeiro de 2007 (o maior e
o menor valor total, VLR_TOTAL);
4. Calcule o valor total vendido (soma de PEDIDOS.VLR_TOTAL) em janeiro
de 2007;
5. Calcule o valor total vendido pelo vendedor de cdigo 1 em janeiro de 2007;
6. Calcule o valor total vendido pela vendedora LEIA em janeiro de 2007;
7. Calcule o valor total vendido pelo vendedor MARCELO em janeiro de 2007;
8. Calcule o valor da comisso (soma de PEDIDOS.VLR_TOTAL * VENDEDORES.
PORC_COMISSAO/100) que a vendedora LEIA recebeu em janeiro de 2007;
9. Calcule o valor da comisso que o vendedor MARCELO recebeu em janeiro
de 2007;
10. Liste os totais vendidos por cada vendedor (mostrar VENDEDOR.NOME
e a soma de PEDIDOS.VLR_TOTAL) em janeiro de 2007. Deve exibir o nome
do vendedor;
11. Liste o total comprado por cada cliente em janeiro de 2007. Deve mostrar
o nome do cliente;

244

Agrupando dados

12. Liste o valor e a quantidade total vendida de cada produto em janeiro


de 2007;
13. Liste os totais vendidos por cada vendedor em janeiro de 2007. Deve exibir
o nome do vendedor e mostrar apenas os vendedores que venderam mais de
R$ 800.000,00;
14. Liste o total comprado por cada cliente em janeiro de 2007. Deve mostrar o
nome do cliente e somente os clientes que compraram mais de R$ 50.000,00;
15. Liste o total vendido de cada produto em janeiro de 2007. Deve mostrar
apenas os produtos que venderam mais de R$ 100.000,00;
16. Liste o total comprado por cada cliente em janeiro de 2007. Deve mostrar
o nome do cliente e somente os 10 primeiros do ranking;
17. Liste o total vendido de cada produto em janeiro de 2007. Deve mostrar os
10 produtos que mais venderam;
18. Liste o total vendido em cada um dos meses de 2006.

245

Apndice
Outros recursos
99 Funo CASE;
99 UNION.

SQL - Mdulo I

1.1.Funo CASE
Os valores pertencentes a uma coluna podem ser testados por meio da clusula
CASE em conjunto com o comando SELECT. Dessa maneira, possvel aplicar
diversas condies de validao em uma consulta.
No exemplo a seguir, CASE utilizado para verificar se os funcionrios da tabela
EMPREGADOS so ou no sindicalizados:
SELECT NOME, SALARIO, CASE SINDICALIZADO
WHEN S THEN Sim
WHEN N THEN No
ELSE N/C
END AS [Sindicato?]
DATA_ADMISSAO
FROM EMPREGADOS;

J no prximo exemplo, verificamos em qual dia da semana os empregados


foram admitidos:
SELECT NOME, SALARIO, DATA_ADMISSAO,
CASE DATEPART(WEEKDAY,DATA_ADMISSAO)
WHEN 1 THEN Domingo
WHEN 2 THEN Segunda-Feira
WHEN 3 THEN Tera-Feira
WHEN 4 THEN Quarta-Feira
WHEN 5 THEN Quinta-Feira
WHEN 6 THEN Sexta-Feira
WHEN 7 THEN Sbado
END AS DIA_SEMANA
FROM EMPREGADOS;

248

Apndice Outros recursos

1.2.UNION
A clusula UNION combina resultados de duas ou mais queries em um conjunto
de resultados simples, incluindo todas as linhas de todas as queries combinadas.
Ela utilizada quando preciso recuperar todos os dados de duas tabelas, sem
fazer associao entre elas.
Para utilizar UNION, necessrio que o nmero e a ordem das colunas nas
queries sejam iguais, bem como os tipos de dados sejam compatveis. Se os
tipos de dados forem diferentes em preciso, escala ou extenso, as regras
para determinar o resultado sero as mesmas das expresses de combinao.
O operador UNION, por padro, elimina linhas duplicadas do conjunto de
resultados.
Veja o seguinte exemplo:
SELECT
Fornecedor -> AS TIPO, NOME, FONE1
FROM FORNECEDORES
UNION -- UNE AS LINHAS DE 2 SELECTs
SELECT
Cliente -> AS TIPO, NOME, FONE1
FROM CLIENTES
ORDER BY NOME;

249

SQL - Mdulo I

1.2.1.Utilizando UNION ALL


A UNION ALL a clusula responsvel por unir informaes obtidas a partir
de diversos comandos SELECT. Para obter esses dados, no h necessidade de
que as tabelas que os possuem estejam relacionadas.
Para utilizar a clusula UNION ALL considerar as seguintes regras:
O nome (alias) das colunas, quando realmente necessrio, deve ser includo
no primeiro SELECT;
A incluso de WHERE pode ser feita em qualquer comando SELECT;
possvel escrever qualquer SELECT com JOIN ou subquery caso seja
necessrio;
necessrio que todos os comandos SELECT utilizados apresentem o
mesmo nmero de colunas;
necessrio que todas as colunas dos comandos SELECT tenham os mesmos
tipos de dados em sequncia. Por exemplo, uma vez que a segunda coluna
do primeiro SELECT baseia-se no tipo de dado decimal, preciso que as
segundas colunas dos outros SELECT tambm apresentem um tipo de dado
decimal;
Para que tenhamos dados ordenados, o ltimo SELECT deve ter uma clusula
ORDER BY adicionada em seu final;
Devemos utilizar a clusula UNION sem ALL para a exibio nica de dados
repetidos em mais de uma tabela.
Enquanto UNION, por padro, elimina linhas duplicadas do conjunto de
resultados, UNION ALL inclui todas as linhas nos resultados e no remove as
linhas duplicadas. A seguir, veja um exemplo da utilizao de UNION ALL:
SELECT
Fornecedor -> AS TIPO, NOME, FONE1
FROM FORNECEDORES
UNION ALL -- UNE AS LINHAS DE 2 SELECTs
SELECT
Cliente -> AS TIPO, NOME, FONE1
FROM CLIENTES
ORDER BY NOME;

250

Apndice

Resumo de objetos de
um banco de dados do
SQL Server 2012
99 Objetos de banco de dados.

SQL - Mdulo I

2.1.Objetos de banco de dados


Os objetos que fazem parte de um sistema de banco de dados do SQL Server
so criados dentro do objeto database, que uma estrutura lgica formada por
dois tipos de arquivo: um arquivo responsvel por armazenar os dados e outro,
por armazenar as transaes realizadas. Veja, a seguir, quais so os objetos de
banco de dados do SQL Server.

2.1.1.Tabela
Os dados do sistema so armazenados em objetos de duas dimenses
denominados tabelas (tables), formadas por linhas e colunas. As tabelas contm
todos os dados de um banco de dados do SQL Server e so a principal forma
para coleo de dados.

2.1.2.ndice
Quando realizamos uma consulta de dados, o SQL Server 2012 faz uso dos
ndices (index) para buscar, de forma fcil e rpida, informaes especficas em
uma tabela ou view indexada.

2.1.3. Constraint
So objetos cuja finalidade estabelecer regras de integridade e consistncia
nas colunas das tabelas de um banco de dados. So cinco os tipos de constraints
oferecidos pelo SQL Server: PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK e
DEFAULT.

252

Apndice Resumo de objetos de um


banco de dados do SQL Server 2012

2.1.4.View
Definimos uma view (visualizao) como uma tabela virtual composta por linhas
e colunas de dados, os quais so provenientes de tabelas referenciadas em uma
query que define essa tabela.
Este objeto oferece uma visualizao lgica dos dados de uma tabela, de modo
que diversas aplicaes possam compartilh-la.
Essas linhas e colunas so geradas de forma dinmica no momento em que
feita uma referncia a uma view.
Veja um exemplo de criao de view:
CREATE VIEW V_ITENSPEDIDO
AS
SELECT I.NUM_PEDIDO, I.NUM_ITEM, I.ID_PRODUTO,
I.QUANTIDADE, I.PR_UNITARIO, I.DESCONTO,
I.QUANTIDADE * I.PR_UNITARIO *
( 1 - I.DESCONTO / 100 ) AS VALOR,
P.DESCRICAO, T.TIPO, U.UNIDADE, C.COR
FROM ITENSPEDIDO I JOIN PRODUTOS P
ON I.ID_PRODUTO = P.ID_PRODUTO
JOIN TIPOPRODUTO T
ON P.COD_TIPO = T.COD_TIPO
JOIN UNIDADES U
ON P.COD_UNIDADE = U.COD_UNIDADE
JOIN TABCOR C ON I.CODCOR = C.CODCOR
JOIN PEDIDOS PE ON I.NUM_PEDIDO=PE.NUM_PEDIDO;

Para testar o exemplo anterior, utilize o seguinte cdigo:


SELECT NUM_PEDIDO, QUANTIDADE, VALOR, DESCRICAO
FROM V_ITENSPEDIDO;

253

SQL - Mdulo I
A seguir, veja outro exemplo de criao de view:
CREATE VIEW V_MAIOR_PEDIDO
AS
SELECT MONTH(DATA_EMISSAO) AS MES,
YEAR(DATA_EMISSAO) AS ANO,
MAX(VLR_TOTAL) AS VLR_DO_MAIOR_PEDIDO
FROM PEDIDOS
GROUP BY MONTH(DATA_EMISSAO), YEAR(DATA_EMISSAO);

O cdigo a seguir testa a view que acabamos de criar:


SELECT V.MES, V.ANO, V.VLR_DO_MAIOR_PEDIDO, P.NUM_PEDIDO
FROM V_MAIOR_PEDIDO V JOIN PEDIDOS P
ON V.MES = MONTH(P.DATA_EMISSAO) AND
V.ANO = YEAR(P.DATA_EMISSAO) AND
V.VLR_DO_MAIOR_PEDIDO = P.VLR_TOTAL
ORDER BY 2,1

2.1.5.Procedure
Neste objeto encontramos um bloco de comandos T-SQL, responsvel por uma
determinada tarefa. Sua lgica pode ser compartilhada por diversas aplicaes.
A execuo de uma procedure realizada no servidor de dados. Por isso, seu
processamento ocorre de forma rpida, visto que seu cdigo tende a ficar
compilado na memria.
Veja um exemplo de stored procedure, que calcula a comisso de vendedores:
CREATE PROCEDURE SP_COMISSAO @DT1 DATETIME, @DT2 DATETIME
AS BEGIN
SELECT V.CODVEN, V.NOME,
SUM(P.VLR_TOTAL) AS TOT_VENDIDO,
SUM(P.VLR_TOTAL * V.PORC_COMISSAO/100) AS COMISSAO
FROM
PEDIDOS P JOIN VENDEDORES V ON P.CODVEN=V.CODVEN
WHERE
P.DATA_EMISSAO BETWEEN @DT1 AND @DT2
GROUP BY V.CODVEN, V.NOME;
END

254

Apndice Resumo de objetos de um


banco de dados do SQL Server 2012

Para testar o exemplo anterior, utilize o seguinte cdigo:


EXEC SP_COMISSAO 2006.6.1, 2006.6.30;

Veja outro exemplo de stored procedure, que realiza um reajuste de preos:


CREATE PROCEDURE SP_REAJUSTA_PRECOS
@FATOR NUMERIC(4,2), @TIPO1 INT = 0, @TIPO2 INT =
999
AS BEGIN
UPDATE PRODUTOS
SET PRECO_VENDA = PRECO_CUSTO * @FATOR
WHERE COD_TIPO BETWEEN @TIPO1 AND @TIPO2;
END

Para testar o exemplo anterior, utilize o seguinte cdigo:


EXEC SP_REAJUSTA_PRECOS 1.3;

2.1.6.Function
Neste objeto, encontramos um bloco de comandos T-SQL responsvel por uma
determinada tarefa, isto , a funo (function) executa um procedimento e
retorna um valor. Sua lgica pode ser compartilhada por diversas aplicaes.
No exemplo a seguir, a funo MONTH retorna o nmero referente ao ms de
uma determinada data:
MONTH(DATA);

255

SQL - Mdulo I

O exemplo a seguir cria uma funo que retorna o nome do dia da semana de
uma data:
CREATE FUNCTION FN_NOME_DIA_SEMANA(@DT DATETIME)
RETURNS VARCHAR(15)
AS BEGIN
DECLARE @NUM_DS INT; -- para o nmero do dia da semana
DECLARE @RESULT VARCHAR(15); -- para o nome do dia da semana
SET @NUM_DS = DATEPART(WEEKDAY, @DT);
IF @NUM_DS = 1 SET
IF @NUM_DS = 2 SET
IF @NUM_DS = 3 SET
IF @NUM_DS = 4 SET
IF @NUM_DS = 5 SET
IF @NUM_DS = 6 SET
IF @NUM_DS = 7 SET
RETURN (@RESULT);
END

@RESULT
@RESULT
@RESULT
@RESULT
@RESULT
@RESULT
@RESULT

=
=
=
=
=
=
=

DOMINGO;
SEGUNDA-FEIRA;
TERA-FEIRA;
QUARTA-FEIRA;
QUINTA-FEIRA;
SEXTA-FEIRA;
SBADO;

No cdigo anterior, destacamos as seguintes linhas:


CREATE FUNCTION FN_NOME_DIA_SEMANA( @DT DATETIME ): Cria uma
funo de nome FN_NOME_DIA_SEMANA e define o tipo de dado a ser
recebido;
RETURNS VARCHAR(15): Define o tipo de dado que a funo retornar;
DECLARE @NUM_DS INT: Declara uma varivel para o nmero do dia da
semana;
DECLARE @RESULT VARCHAR(15): Declara uma varivel para o nome do
dia da semana.

256

Apndice Resumo de objetos de um


banco de dados do SQL Server 2012

Para testar a funo criada com o cdigo anterior, digite as seguintes linhas:
SELECT NOME, DATA_ADMISSAO, DATENAME(WEEKDAY,DATA_ADMISSAO),
DBO.FN_NOME_DIA_SEMANA(DATA_ADMISSAO)
FROM EMPREGADOS;

Veja mais um exemplo, que cria uma funo para retornar somente a primeira
palavra de um nome:
CREATE FUNCTION FN_PRIMEIRA_PALAVRA(@NOME VARCHAR(200))
RETURNS VARCHAR(200)
AS BEGIN
DECLARE @CONT INT, @RET VARCHAR(200), @C CHAR(1);
SET @RET = ;
SET @CONT = 1;
SET @NOME = LTRIM( @NOME );
WHILE @CONT <= LEN( @NOME )
BEGIN
SET @C = SUBSTRING( @NOME, @CONT, 1 );
IF @C = BREAK;
SET @RET = @RET + @C;
SET @CONT = @CONT + 1;
END -- WHILE
RETURN @RET;
END

Para testar a funo anterior, digite o seguinte cdigo:


SELECT DBO.FN_PRIMEIRA_PALAVRA(CARLOS

MAGNO);

257

SQL - Mdulo I

2.1.7.Trigger
Este objeto tambm possui um bloco de comandos Transact-SQL. O trigger
criado sobre uma tabela e ativado automaticamente no momento da execuo
dos comandos UPDATE, INSERT ou DELETE.
Quando atualizamos, inserimos ou exclumos dados em uma tabela, o trigger
automaticamente grava em uma tabela temporria os dados do registro
atualizado, inserido ou excludo. A tabela adiante descreve esse procedimento:
Comando
que ativa o
trigger

Tabela
temporria
gerada

Dados da tabela
temporria gerada

DELETE

DELETED

Dados do registro
excludo.

INSERT

INSERTED

Dados do registro
inserido.

DELETED

Dados do registro
anteriores alterao.

INSERTED

Dados do registro
posteriores alterao.

UPDATE

Veja o seguinte exemplo de criao de um trigger para recalcular o valor total


dos pedidos:

O exemplo a seguir foi criado de forma simplificada e tem como


objetivo apenas mostrar as caractersticas bsicas de um trigger.
CREATE TRIGGER RECALC_VLR_TOTAL ON ITENSPEDIDO
FOR DELETE, INSERT, UPDATE
AS BEGIN

Depois disso, criamos duas variveis, uma para armazenar o nmero do pedido
alterado e outra para armazenar o novo valor total:
DECLARE @NUM_PEDIDO INT;
DECLARE @VLR_TOTAL NUMERIC(15,2);

258

Apndice Resumo de objetos de um


banco de dados do SQL Server 2012

Criadas as duas variveis, vamos detectar o nmero do pedido alterado:


SELECT @NUM_PEDIDO = NUM_PEDIDO FROM INSERTED
IF @NUM_PEDIDO IS NULL
SELECT @NUM_PEDIDO = NUM_PEDIDO FROM DELETED;

Em seguida, digitaremos as linhas a seguir para recalcular o valor total do pedido:


SELECT @VLR_TOTAL = SUM( QUANTIDADE * PR_UNITARIO * (1-DESCONTO/100) )
FROM ITENSPEDIDO WHERE NUM_PEDIDO = @NUM_PEDIDO;

Para gravar o novo valor total na tabela PEDIDOS:


UPDATE PEDIDOS SET VLR_TOTAL = @VLR_TOTAL
WHERE NUM_PEDIDO = @NUM_PEDIDO;
END

Para testarmos toda a sequncia de cdigos anterior, podemos, por exemplo,


consultar o pedido de nmero 1000:
SELECT * FROM PEDIDOS WHERE NUM_PEDIDO = 1000; -- VLR_TOTAL =
3800

J para consultarmos os itens desse pedido, devemos digitar a seguinte linha:


SELECT * FROM ITENSPEDIDO WHERE NUM_PEDIDO = 1000;

Para alterarmos para 2 o preo unitrio (PR_UNITARIO) do pedido nmero


1000, devemos digitar a seguinte linha:
UPDATE ITENSPEDIDO SET PR_UNITARIO = 2
WHERE NUM_PEDIDO = 1000;

259

Вам также может понравиться