Beruflich Dokumente
Kultur Dokumente
SQL
Structure Query Language Luis Fernando Calbria Erick Franklin Leonardo Bandeira
Sumrio
1. INTRODUO 1.1. 1.2. 1.3. 1.4. 1.5. 2. 2.1. 2.2. 2.3. SOBRE SQL VISO GERAL DE UM BANCO DE DADOS RELACIONAL COLUNAS E LINHAS ENTIDADES E CHAVE PRIMRIA CHAVE PRIMRIA COMPOSTA CRIANDO UMA TABELA IDENTIFICADORES E ATRIBUTOS TIPOS DE DADOS 2.3.1. DADOS CARACTERES STRINGS 2.3.2. DADOS NUMRICOS 2.3.3. DADOS DATA E HORA INCLUINDO DADOS CLUSULAS SELECT E FROM CLUSULA WHERE 3.2.1. PREDICADOS RELACIONAIS 3.2.2. OUTROS PREDICADOS RELACIONAIS 3.2.3. VINCULANDO VRIOS PREDICADOS: AND E OR OPERADORES ARITMTICOS FUNES 4.2.1. FUNES AGREGADAS 4.2.2. FUNES NO AGREGADAS 4.2.3. FUNES DE SEQNCIAS DE CARACTERES 4.2.4. FUNES DE DATA E HORA CLUSULA GROUP BY CLUSULA HAVING CLUSULA ORDER BY EQUIJUNES JUNES EXTERNAS AUTO-JUNES OUTROS TIPOS DE JUNES DECLARAO UNION UTILIZANDO QUERIES PARA INCLUIR DADOS 3 3 3 4 4 5 6 6 7 7 7 7 8 8 9 9 10 11 11 13 14 14 15 15 15 16 16 17 17 17 18 19 20 21 21 23 23 23 23
A LINGUAGEM SQL
4.
5.
6.
JUNES: QUERIES QUE ENVOLVEM MAIS DE UMA TABELA 6.1. 6.2. 6.3. 6.4.
7.
Pgina 1
8.
ALTERANDO TABELAS E DADOS 8.1. ALTERANDO OS DADOS 8.1.1. ATUALIZANDO DADOS EM UMA LINHA 8.1.2. ELIMINANDO LINHAS 8.1.3. GRAVANDO E DESFAZENDO ALTERAES ALTERANDO UMA TABELA 8.2.1. ELIMINANDO UMA COLUNA 8.2.2. INCLUINDO UMA COLUNA 8.2.3. MODIFICANDO UMA COLUNA 8.2.4. TROCANDO O NOME DE UMA TABELA OU COLUNA 8.2.5. ELIMINANDO UMA TABELA UTILIZANDO UM NDICE UTILIZANDO UM NDICE NICO UTILIZANDO UM NDICE CONCATENADO APAGANDO UM NDICE PORQUE SQL EMBUTIDA UTILIZANDO A FERRAMENTA ACCESS
24 24 24 25 25 25 26 26 27 27 27 28 28 28 29 29 30 30 30
8.2.
9.
10.
Pgina 2
1.Introduo
1.1. Sobre SQL
Um banco de dados como um arquivo eletrnico, ou seja, tem a mesma funo que qualquer outro arquivo armazenar registros. A nica diferena que no banco de dados os registros so armazenados eletronicamente. Para termos acesso aos registros armazenados ou mesmo cadastrar novos registros, precisamos de um sistema que gerencie o banco de dados. Este sistema gerenciador de banco de dados que torna possveis as operaes com o contedo do arquivo, como Traga-me este arquivo, Atualize este registro. Existem vrios tipos de sistemas de gerenciamento de banco de dados (SGBD ou DBMS), representando diversas abordagens relativas s tarefas de acesso s informaes contidas no banco de dados, preservao da integridade dos dados, acompanhamento dos usurios e manuteno da segurana. Para o nosso estudo, porm, podemos classificar todos os sistemas em dois tipos: relacionais e no relacionais, embora seja visvel o predomnio da abordagem relacional nos novos sistemas do mercado. Em um sistema relacional, os dados so armazenados e representados exclusivamente em tabelas. Em nenhum momento faz-se necessrio recorrer a outras estruturas, como rvores hierrquicas, para ter acesso aos dados. A linguagem SQL o nome a sigla de Structured Query Language (Linguagem de Query Estruturada) uma linguagem para gerenciar um sistema de banco de dados relacional. No s uma linguagem, como tambm tem sido to utilizada que pode ser considerada um padro. Consiste de uma srie de declaraes, adotadas de comum acordo, que nos permitem realizar diversas operaes. Temos que usar a expresso comum acordo porque, embora uma SQL padro tenha sido criada pelo Instituto de Padres Nacionais Americanos (ANSI), todas as implementaes particulares da SQL personalizam a linguagem de vrias formas. Tais implementaes complementam a linguagem padro com novos tipos de declaraes ou expresses e muitas vezes adaptam as declaraes padronizadas s necessidades especficas.
1.2.
Pgina 3
1.3.
Colunas e Linhas
Qualquer informao refere-se a qualquer coisa, e talvez o primeiro princpio da abordagem relacional seja o de todas as informaes contidas em uma tabela devem estar sempre relacionadas a exemplos de um tipo de coisa. Este princpio destingue o uso relacional de tabelas. Por exemplo, a tabela HOSPEDES abaixo contm informaes sobre os scios de um clube de tratamento da forma fsica, selecionado, conceituado e imaginrio chamado Visual Spa (fig. 1.1).
Fig. 1.1 - HOSPEDES
NOME JOS AUGUSTO MAURCIO DE SOUZA BIANCA OLIVEIRA JANE FYUNDAI STELLA SHIELDS ROGRIO NUNES
SEXO M M F F F M
BIOTIPO M M G G M M
A tabela possui quatro colunas NOME, SEXO, BIOTIPO e ALTURA e 6 linhas. Contm informaes sobre os hspedes do Spa; cada coluna vertical possui dados referentes a uma caracterstica ou atributo dos hspedes. Os atributos em que estamos interessados so nome, sexo, biotipo e altura de cada hspede; por isso destinamos uma coluna a cada um deles. Esta a funo das colunas verticais de uma tabela: conter informaes sobre os atributos das entidades a que se refere a tabela. Cada linha horizontal da tabela HOSPEDE contm as informaes sobre todos os atributos referentes a um determinado hspede. Portanto, enquanto a coluna NOME exibe os nomes de todos os hspedes da tabela e a coluna SEXO o sexo de todos os hspedes e assim por diante em relao s outras colunas, a linha em que aparece o nome Jos Augusto contm informaes apenas referentes aos atributos do hspede chamado Jos Augusto. Mais adiante introduziremos um novo conceito relacional: o de chave primria.
1.4.
Pgina 4
Em outras palavras, temos que procurar por uma coluna (ou grupo de colunas) que apresente um contedo diferente em cada linha dados que so duplicados em duas linhas. Esta caracterstica ento servir para identificar a linha da mesma forma que usamos um nome para identificar uma pessoa. Volte tabela HSPEDE (fig. 1.1). Observe que nem todos os atributos, ou colunas, so igualmente suficientes para identificar as linhas. Por exemplo, no basta saber apenas o sexo de um hspede que voc queira identificar se este atributo compartilhado por metade dos seus hspedes. Da mesma forma, se soubermos o biotipo de um hspede teremos um grupo mais reduzido mas no conseguiremos localizar um hspede em particular. O problema que as colunas SEXO e BIOTIPO contm valores duplicados. Quando duas linhas contm o mesmo atributo, este atributo no pode ser usado para distinguir as linhas entre si. Concluindo, a nica coluna que pode servir de atributo identificador a coluna NOME. Como no contm valores duplicados, as informaes nela contidas so por si s suficientes para distinguir a linha de um hspede na tabela. Descrevemos, na realidade, uma diferena entre os dois tipos de colunas. O primeiro tipo est baseado em um atributo que identifique univocamente ou defina uma linha. O segundo tipo baseia-se em atributos descritivos que fornecem informaes, mas no so suficientes para identificar uma linha ou entidade. A coluna (ou grupo de colunas) baseada em um atributo identificador de uma linha chamada de Chave ou Chave Primria. A chave de uma tabela lhe permite identificar as linhas individualmente, definindo tambm as entidades s quais a tabela se refere. Um banco de dados relacional todas as tabelas tem que ter uma chave primria que identifique cada linha.
1.5.
NOME JANE FYUNDAI MARCELO FREITAS ALEXANDRE GOMES JOS AUGUSTO MAURCIO DE SOUZA BIANCA OLIVEIRA JANE FYUNDAI STELLA SHIELDS ALEXANDRE GOMES
QUARTO 4 2 1 3 5 6 7 8 9
TCNICO JLIO BRUNA RICARDO JLIO RICARDO BRUNA SERENA SERENA BRUNA
CHEGADA 15-08-1997 26-08-1997 14-08-1997 15-08-1997 25-08-1997 15-08-1997 24-08-1997 25-08-1997 17-08-1997
23-08-1997
Nenhuma das colunas por si s poder funcionar como chave primria, pois todas elas possuem valores duplicados, inclusive NOME: Alexandre Gomes e Jane Fyundai estiveram hospedados duas vezes e por isso aparecem duas vezes na lista. Para estabelecermos uma chave para esta tabela, teremos que usar duas ou mais colunas conjuntamente. Este tipo de chave, envolvendo duas ou mais colunas, denomina-se chave composta ou chave primria composta. No exemplo (Fig. 1.2) as colunas que melhor se candidatam a formar chave composta so NOME e CHEGADA. O NOME e a CHEGADA combinados lhe permite distinguir uma linha da outra, ou seja, no h linhas com os valores de NOME e CHEGADA iguais.
Pgina 5
2.1.
Pgina 6
2.2.
Identificadores e Atributos
Observe os dois traos sublinhados ( ___ ) ligando as trs palavras que compes o nome da tabela LISTA_DE_HOSPEDES. O trao sublinhado um meio convencional para representar o espao nos nomes de tabelas ou colunas que contm mais de uma palavra. Ele tm por finalidade ligar uma palavra outra, fazendo com que formem apenas um conjunto de caracteres, podendo se reconhecidas portanto como partes integrantes de um nico nome.
2.3.
Tipos de Dados
A SQL padro da ANSI reconhece dois tipos genricos de dados seqncias (strings) de caracteres de dados numricos , e oferece vrios tipos particulares com diferentes caractersticas para atender s necessidades de cada coluna. Estes incluem CHAR (ou CHARACTER), para seqncias de caracteres, e os tipos NUMERIC, DECIMAL, INTEGER, SMALLINT, FLOAT, REAL, DOUBLE PRECISION, para dados numricos. Existem diversos tipos de dados implementados para duas outras categorias de dados. Uma delas abrange os dados tipo data e hora, representados em SQL Base pelos tipos DATE, TIME, TIMESTAMP; a outra o tipo de dado LONG VARCHAR ou LONG, tipo genrico que pode armazenar qualquer categoria de dados, inclusive dados binrios. Em SQL Base, os dados do tipo LONG podem ter um tamanho virtual qualquer (bilhes de bytes); em outras implementaes, o limite normalmente de 64 Kbytes.
Pgina 7
Nome Organizaes de Padres Intern. Padro IBM EUA (USA) Padro IBM Europa (EUR) Padro Industrial Japons (JIS)
Nome Organizaes de Padres Intern. Padro IBM EUA (USA) Padro IBM Europa (EUR) Padro Industrial Japons (JIS)
2.4.
Incluindo Dados
A declarao CREATE TABLE mostrada no incio apenas criou as tabelas HOSPEDES e LISTA_DE_HOSPEDES, sem preench-las com dados. Para incluir dados nas tabelas, usamos uma outra declarao ou comando. Na linguagem SQL a nica forma de incluir dados atravs da declarao INSERT, que normalmente inclui uma nica linha de cada vez. S pode ser utilizada para incluir vrias linhas se nela for inserida uma query que recupere de outra tabela os dados a serem includos. A declarao SQL abaixo ilustra a incluso de uma nica linha de dados na tabela LISTA_DE_HOSPEDES. A linha consiste de seis itens de dados, separados por vrgulas um item para cada uma das seis colunas da tabela LISTA_DE_HOSPEDES. O primeiro item de dados includo na primeira coluna da tabela, o segundo item na segunda coluna, e assim por diante, como se segue: INSERT INTO LISTA_DE_HOSPEDES (NOME, QUARTO, TECNICO, CHEGADA, SAIDA, DESCONTO) VALUES (CLOVIS ALMEIDA, 3, JULIO, 13-08-1997, 17-08-1997, .2;
Pgina 8
Como estamos incluindo dados em todas as colunas da tabela LISTA_DE_HOSPEDES, poderamos omitir a lista dos nomes das colunas aps o nome da tabela. Esta lista s indispensvel caso estejamos incluindo dados em apenas algumas colunas e no em todas; temos ento que indicar os nomes das colunas que recebero dados. Nomeamos todas as colunas neste exemplo simplesmente para facilitar anlise da declarao. Observe que os dados referentes s colunas NOME, QUARTO e TECNICO esto entre apstrofes (). Isto se deve ao fato de que os dados das trs colunas so do tipo VARCHAR. Dados CHAR ou VARCHAR usados em declaraes SQL devem aparecer entre apstrofes.
3.1.
A query acima solicita todas as linhas de dados para todas as colunas da tabela LISTA_DE_HOSPEDES. No acrescentamos qualificaes, e, portanto, o resultado contm todos os dados destas colunas.
Pgina 9
Incidentemente, podemos usar um asterisco (*) em vez de nomes de colunas na clusula SELECT. O asterisco representa os valores de todas as colunas. Usar o asterisco o mesmo que nomear todas as colunas de uma tabela ou mais tabelas, na sua ordem original. Portanto, ao invs de digitar todos os nomes de colunas como fizemos no exemplo anterior, poderamos ter obtido o mesmo resultado codificando a query assim: SELECT * FROM LISTA_DE_HOSPEDES; Podemos selecionar de apenas algumas colunas e omitir outras. A query a seguir obtm os dados somente da coluna NOME: SELECT NOME FROM LISTA_DE_HOSPEDES; Podemos evitar que dados sejam exibidos duplicados, usando a palavra-chave DISTINCT imediatamente aps a palavra SELECT na clusula SELECT para suprimir as linhas duplicadas do resultado. No exemplo abaixo a palavra-chave DISTINCT foi acrescentada na query anterior: SELECT DISTINCT NOME FROM LISTA_DE_HOSPEDES; A palavra-chave DISTINCT suprime apenas as linhas duplicadas do resultado, e no valores duplicados.
3.2.
Clusula WHERE
A clusula WHERE reduz o escopo da query focalizando apenas determinadas linhas. Ao invs de retornar os valores das expresses da clusula SELECT de todas as linhas, uma query com uma clusula WHERE retorna apenas os valores das linhas que atendam s condies especificadas na clusula WHERE. Em outras palavras, uma query contendo a clusula WHERE tem essencialmente o seguinte formato: SELECT o valor das expresses FROM estas tabelas somente nas linhas WHERE estas condies foram atendidas. As condies da clusula WHERE so chamadas de condies de pesquisa. O exemplo abaixo seleciona dados das colunas NOME e TECNICO da tabela LISTA_DE_HOSPEDES somente nas linhas em que o tcnico for a Bruna. Em outras palavras, a query lista os nomes (e tcnicos) de todas as pessoas cujo o tcnico seja a Bruna: SELECT NOME, TECNICO FROM LISTA_DE_HOSPEDES WHERE TECNICO = BRUNA; NOME MARCELO FREITAS BIANCA OLIVEIRA ALEXANDRE GOMES TCNICO BRUNA BRUNA BRUNA
No obrigatrio citar na clusula WHERE somente colunas que apaream na clusula SELECT. A query anterior funcionaria da mesma forma se eliminssemos a coluna TECNICO da clusula SELECT. SELECT NOME FROM LISTA_DE_HOSPEDES WHERE TECNICO = BRUNA;
Pgina 10
Podemos solicitar tambm os nomes e as datas de sada de todos os hspedes que saram do Spa entre 19 e 24 de agosto:
Pgina 11
SELECT NOME, SAIDA FROM LISTA_DE_HOSPEDES WHERE SAIDA BETWEEN 19-08-1997 AND 24-08-1997; NOME JOSE AUGUSTO BIANCA OLIVEIRA ALEXANDRE GOMES SAIDA 19-08-1997 20-08-1997 23-08-1997
O operador IS NULL nos permite selecionar as linhas em que o valor de um determinado campo seja desconhecido. Por exemplo, as linhas de vrios hspedes ficaram com a SAIDA em branco. Podemos selecionar os nomes destes hspedes utilizando o operador IS NULL. SELECT NOME, SAIDA FROM LISTA_DE_HOSPEDES WHERE SAIDA IS NULL; NOME MARCELO FREITAS JANE FYUNDAI STELLA SHIELDS SAIDA
O operador LIKE nos permite utilizar caracteres mscara para comparar dados em uma condio de pesquisa. Em vez de os dados terem que ser idnticos, podemos especificar que sejam apenas semelhantes em algum aspecto. Podemos usar os dois caracteres mscara abaixo com o operador LIKE: _ (sublinhado) * (asterisco) Vale por qualquer caractere nico Vale por qualquer seqncia de caracteres
No contexto de um LIKE, o caractere de sublinhado ( _ ) funciona analogamente ao ponto de interrogao (?) do MS-DOS, que serve de caractere mscara em nomes de arquivos, e o smbolo de percentual (%) funciona analogamente ao asterisco (*). O exemplo de query abaixo usa o operador LIKE e um caractere mscara para selecionar todos os nomes que comecem com a seqncia de caracteres MA%; SELECT NOME FROM LISTA_DE_HOSPEDES WHERE NOME LIKE MA%; NOME MARCELO FREITAS MAURICIO DE SOUZA A prxima query seleciona todos os nomes que tenham a letra J na primeira posio e N na quarta, no importando quais sejam os outros caracteres. SELECT NOME FROM LISTA_DE_HOSPEDES WHERE NOME LIKE J__N; NOME JANE FYUNDAI Mais um exemplo: SELECT NOME FROM LISTA_DE_HOSPEDES WHERE NOME LIKE _AR_E%;
Pgina 12
NOME MARCELO FREITAS O ltimo operador a ser discutido neste tpico o IN, que nos permite selecionar dados que se encaixem em um conjunto ou uma lista de valores. Os valores podem ser indicados explicitamente em uma declarao, como nos exemplos a seguir. A query abaixo seleciona o nome, o tcnico e o quarto de cada hspede cujo o tcnico esteja presente na lista BRUNA, JULIO: SELECT NOME, TECNICO, QUARTO FROM LISTA_DE_HOSPEDES WHERE TECNICO IN (BRUNA, JULIO); NOME JANE FYUNDAI MARCELO FREITAS JOS AUGUSTO BIANCA OLIVEIRA ALEXANDRE GOMES TCNICO JLIO BRUNA JLIO BRUNA BRUNA QUARTO 3 2 4 6 9
Todos os operadores relacionais tambm podem ser utilizados com o NOT. Na query abaixo, selecionamos o nome, o tcnico e o quarto dos hspedes cujo o tcnico no esteja includo na lista: SELECT NOME, TECNICO, QUARTO FROM LISTA_DE_HOSPEDES WHERE TECNICO NOT IN (BRUNA, JULIO); NOME ALEXANDRE GOMES MAURCIO DE SOUZA JANE FYUNDAI STELLA SHIELDS QUARTO 1 5 7 8 TCNICO RICARDO RICARDO SERENA SERENA
Pgina 13
Podemos acrescentar inmeras condies clusula WHERE usando os operadores AND e OR. A prxima query acrescenta vrios componentes: SELECT NOME, QUARTO, TECNICO, CHEGADA, SAIDA FROM LISTA_DE_HOSPEDES WHERE SAIDA IS NULL AND TECNICO = ROBERTO AND QUARTO > 16 AND CHEGADA < 20-08-97;
4.1.
Operadores Aritmticos
So quatro os operadores aritmticos que podem formar expresses: + * / adio subtrao multiplicao diviso
A query abaixo, usamos o operador de soma para adicionar 0.05 (uma constante) ao valor corrente de DESCONTO na linha de Marcelo Freitas. A clusula SELECT contm duas expresses: NOME e a expresso formada pelo operador aritmtico, DESCONTO + 0.05. A tabela resultado dever conter duas colunas, uma para cada expresso: SELECT NOME, DESCONTO + 0.05 FROM LISTA_DE_HOSPEDES WHERE NOME = MARCELO FREITAS NOME MARCELO FREITAS DESCTO 0.15
Embora as regras variem de implementao para implementao, algumas permitem ainda o uso de operadores aritmticos com dados do tipo data e hora. Em SQL Base, por exemplo, a query abaixo pode ser usada para determinar por quantos dias ficaram no Spa os hspedes que j foram embora. Este nmero obtido subtraindo-se a data de chegada de sada. Outras implementaes permitem queries semelhantes, mas no idnticas. SELECT NOME, SAIDA - CHEGADA FROM LISTA_DE_HOSPEDES WHERE NOME = MARCELO FREITAS
Pgina 14
4.2.
Funes
As funes constituem mais uma forma de usar queries para manipular os dados das tabelas. Uma funo retorna o valor resultante de uma determinada operao realizada sobre o seu argumento (ou argumentos). Uma funo, como o seu argumento, representa um valor e portanto uma expresso.
As funes agregadas normalmente usam como argumento um nome de coluna ou uma expresso que tenha um nome de coluna como componente, mas podemos us-las com qualquer expresso numrica ou de datas. A query a seguir l todos os valores da coluna DESCONTO e fornece os percentuais mdio, mximo e mnimo de desconto oferecidos aos hspedes do Visual Spa. Como as funo AVG, MX, MIN e SUM ignoram valores nulos, o valor AVG (mdia) realmente o desconto mdio apenas daqueles hspedes que obtiveram algum desconto: SELECT AVG(DESCONTO), MAX(DESCONTO), MIN(DESCONTO) FROM LISTA_DE_HOSPEDES; AVG(DESCONTO) 0.115635 MAX(DESCONTO) 0.20 MIN(DESCONTO) 0.05
Outros exemplos: SELECT MIN(DESCONTO) * AVG(SAIDA-CHEGADA) FROM LISTA_DE_HOSPEDES WHERE TECNICO = SENERA;
Pgina 15
SELECT NOME, @PROPER(@LENGTH(NOME,5)) FROM LISTA_DE_HOSPEDES; NOME JANE FYUNDAI MARCELO FREITAS JOS AUGUSTO BIANCA OLIVEIRA ALEXANDRE GOMES @PROPER(@LENGTH (NOME,5)) jane marce jos bianc alexan
Queries semelhantes podem ser criadas com as funes @MONTH, @YEAR, @HOUR, @MINUTE e @SECOND.
Pgina 16
5.Organizando o Resultado
5.1. Clusula GROUP BY
A clusula GROUP BY rene diferentes linhas do resultado de uma query em conjuntos de acordo com as colunas nela mencionadas, chamadas colunas formadoras de grupos. As linhas so agrupadas de duas formas, ou em dois aspectos. A query abaixo exemplifica a primeira forma, na qual todas as linhas que contm o mesmo valor na primeira coluna especificada so exibidas em grupos no resultado. Neste caso, a primeira coluna formadora de grupo TECNICO. Todas as linhas que tenham o mesmo valor na coluna TECNICO aparecero juntas no resultado: SELECT TECNICO, NOME FROM LISTA_DE_HOSPEDES GROUP BY TECNICO, NOME; TCNICO BRUNA BRUNA BRUNA JLIO JLIO RICARDO RICARDO SERENA SERENA NOME MARCELO FREITAS BIANCA OLIVEIRA ALEXANDRE GOMES JANE FYUNDAI JOS AUGUSTO ALEXANDRE GOMES MAURCIO DE SOUZA JANE FYUNDAI STELLA SHIELDS
Se houvesse linhas em que a coluna TECNICO estivesse em branco, ou seja, com um valor nulo para TECNICO, tambm seriam agrupadas. E as linhas so agrupadas da mesma maneira para cada coluna formadora de grupos subseqente, embora isto no esteja aparente no exemplo dados pois s contm duas colunas. Obs.: As funes agregadas AVG, SUM, MAX, MIN e COUNT no podem ser usadas em clusulas GROUP BY pois geram um nico valor e por isso no podem agrupar linhas. A clusula GROUP BY tambm pode ser usada em queries contendo uma clusula WHERE. Neste caso, a GROUP BY codificada depois da clusula WHERE. Por exemplo, a query abaixo exibe os nomes dos hspedes que chegaram depois do dia 15 de agosto por tcnico: SELECT TECNICO, NOME FROM LISTA_DE_HOSPEDES WHERE CHEGADA > 15-08-97 GROUP BY TECNICO, NOME;
5.2.
Clusula HAVING
A clusula HAVING nos permite estreitar a rea de atuao da clusula GROUP BY da mesma forma que a clusula WHERE estreita a rea de atuao da clusula SELECT, ou seja, atravs de uma condio de pesquisa. Ao contrrio da clusula WHERE, no entanto, a clusula HAVING pode conter funes agregadas.
Pgina 17
Uma nova tabela, HOSPEDES_PS, ser usada nos exemplos deste tpico. Criamos uma tabela com a declarao CREATE TABLE abaixo. Esta tabela se destina a registrar as pesagens peridicas dos hspedes do Visual Spa. CREATE TABLE HOSPEDE_PS (HOSPEDE VARCHAR(25) NOT FULL, PESO DECIMAL(4,1), QUANDO DATE); Chamamos a coluna DATE de QUANDO porque DATE uma palavra reservada. As palavras reservadas no podem ser usadas como nomes de colunas ou outros identificadores, a no ser que entre aspas. Aps a incluso dos dados, a tabela HOSPEDE_PS tem a seguinte aparncia: SELECT * FROM HOSPEDE_PS NOME JANE FYUNDAI MARCELO FREITAS ALEXANDRE GOMES JOS AUGUSTO MAURCIO DE SOUZA JANE FYUNDAI MARCELO FREITAS ALEXANDRE GOMES JOS AUGUSTO MAURCIO DE SOUZA PESO 68 59 86 87 68.5 67.5 55 84 84 67 QUANDO 14-08-97 14-08-97 15-08-97 15-08-97 15-08-97 16-08-97 16-08-97 17-08-97 17-08-97 17-08-97
A tabela contm dois registros de peso para cada estada: um na data de entrada e outro na data de sada. A query a seguir indica os hspedes que tiveram uma diferena acima de um entre seu peso mnimo e seu peso mximo. Observe a presena de funes agregadas na clusula HAVING. SELECT HOSPEDE, MIN(PESO), MAX(PESO) MIN(PESO) FROM HOSPEDE_PS GROUP BY HOSPEDE HAVING MAX(PESO) MIN(PESO) > 1; NOME MARCELO FREITAS ALEXANDRE GOMES JOS AUGUSTO MAURCIO DE SOUZA MIN(PESO) 55 84 84 67 MAX(PESO MAX(PESO)-MIN(PESO) ) 59 4 86 2 87 3 68.5 1.5
Passemos para um outro exemplo. Esta query solicita o nmero de hspedes orientados por cada tcnico que trabalhou com mais de dois hspedes: SELECT HOSPEDE, COUNT(NOME) FROM HOSPEDE_PS GROUP BY HOSPEDE HAVING CONT(NOME) > 2;
5.3.
Clusula ORDER BY
A clusula ORDER BY nos permite classificar as linhas do resultado alfabtica e numericamente, em ordem crescente ou decrescente. O default a ordem crescente. A clusula ORDER BY sempre a ltima clusula da query. No exemplo a seguir, obtemos os nomes dos hspedes classificados em ordem decrescente colocando a palavra DESC na clusula ORDER BY depois do nome da coluna a ser ordenada. Usamos a palavra-chave DISTINCT para suprimir as linhas duplicadas:
Pgina 18
SELECT DISTINCT NOME FROM LISTA_DE_HOSPEDES ORDER BY NOME DESC; NOME STELLA SHIELDS MAURCIO DE SOUZA MARCELO FREITAS JOS AUGUSTO JANE FYUNDAI JANE FYUNDAI BIANCA OLIVEIRA ALEXANDRE GOMES ALEXANDRE GOMES As classificaes so, por default, efetuadas em ordem crescente, a no ser que seja indicada a palavrachave DESC aps o nome da coluna. Porm, podemos tambm explicitar a ordem crescente para uma determinada coluna, usando-se a palavra-chave ASC aps o nome da coluna na clusula ORDER BY.
A query a seguir obtm a altura de Rogrio Nunes : SELECT NOME, ALTURA FROM HOSPEDES WHERE NOME = BIANCA OLIVEIRA; NOME BIANCA OLIVEIRA ALTURA 1,65
A prxima query obtm seu tcnico da tabela LISTA_DE_HOSPEDES: SELECT NOME, TECNICO FROM LISTA_DE_HOSPEDES WHERE NOME = BIANCA OLIVEIRA; NOME BIANCA OLIVEIRA TECNICO BRUNA
Podemos, no entanto, obter as mesmas informaes de uma s vez atravs de uma query chamada juno. Uma juno uma query que obtm dados de mais de uma tabela ao mesmo tempo, baseando-se na condio de juno indicada na clusula WHERE. Temos abaixo uma juno que fornece a altura e o tcnico de todos os hspedes: SELECT HOSPEDES.NOME, ALTURA, TECNICO
Pgina 19
FROM HOSPEDES, LISTA_DE_HOSPEDES WHERE HOSPEDES.NOME = LISTA_DE_HOSPEDES.NOME; NOME JANE FYUNDAI JOS AUGUSTO MAURCIO DE SOUZA BIANCA OLIVEIRA STELLA SHIELDS TCNICO ALTURA JLIO 1,80 JLIO 1,67 RICARDO 1,72 BRUNA 1,65 SERENA 1,65
Podemos traduzir a query da seguinte maneira: Para todas as linhas de HOSPEDES e LISTA_DE_HOSPEDES cujo o valor de HOSPEDES.NOME seja igual ao de LISTA_DE_HOSPEDES.NOME, obtenha os respectivos NOME e ALTURA de HOSPEDES e o TECNICO de LISTA_DE_HOSPEDES.
6.1.
Equijunes
A ltima query que analisamos um exemplo de equijuno uma juno baseada em uma condio de igualdade. Outros tipos de predicados relacionais podem constituir outros tipos de condio de juno, dos quais veremos alguns exemplos. Porm de antemo sabemos que o tipo mais comum o de igualdade a equijuno. Para que possamos dar um exemplo um pouco diferente, criaremos uma nova tabela, QUARTOS, que ir conter detalhes das acomodaes do Visual Spa. A declarao utilizada para cri-la a seguinte: CREATE TABLE QUARTOS (QUARTO VARCHAR(3), NOME VARCHAR(15), TAXA FLOAT, DESCRICAO LONG VARCHAR); A tabela em questo preenchida com dados, excetuando-se a coluna de tipo LONG, tem a seguinte aparncia: SELECT QUARTO, NOME, TAXA FROM QUARTOS; QUARTO 1 2 3 4 5 NOME ANA PAULA CARMEM SOUZA CRISTIANO BEZERRA MARCONE ALMEIDA MARIA FERREIRA TAXA 300 300 250 325 250
Pgina 20
Segue-se ento o exemplo de equijuno. Para efeito de demonstrao, a equijuno encontra-se em uma clusula AND. Observe, tambm, que nenhuma das duas colunas unidas, QUARTO da tabela QUARTOS e da LISTA_DE_HOSPEDES, aparece na lista do SELECT. SELECT LISTA_DE_HOSPEDES.NOME, QUARTOS.NOME, QUARTOS.TAXA, LISTA_DE_HOSPEDES.DESCONTO FROM QUARTOS, LISTA_DE_HOSPEDES WHERE LISTA_DE_HOSPEDES.NOME = JANE FYUNDAI AND QUARTOS.QUARTO = LISTA_DE_HOSPEDES.QUARTO; LISTA_DE_HOSPEDES. QUARTOS.NOME NOME JANE FYUNDAI MARCONE ALMEIDA QUARTOS.TAXA 325 LISTA_DE_HOSPEDES. DESCTO 0.20
6.2.
Junes Externas
Suponhamos que quisssemos saber o nome, o sexo, o biotipo, a altura e o tcnico de cada um dos hspedes do Visual Spa. Os tcnicos so indicados na tabela LISTA_DE_HOSPEDES, a qual contm informaes sobre hspedes atuais; as outras informaes esto contidas na tabela HOSPEDES, que contm os registros de todos os hspedes, atuais e passados. Podemos, para isso, usar esta query, uma simples equijuno: SELECT HOSPEDES.NOME, SEXO, BIOTIPO, ALTURA, TECNICO FROM HOSPEDES, LISTA_DE_HOSPEDES WHERE HOSPEDES.NOME = LISTA_DE_HOSPEDES.NOME; NOME JOS AUGUSTO MAURCIO DE SOUZA BIANCA OLIVEIRA JANE FYUNDAI STELLA SHIELDS ROGRIO NUNES CLINT WESTWOOD SEXO M M F F F M M BIOTIPO M M G G M M M ALTURA 1,67 1,72 1,65 1,80 1,65 1,78 1,85 TECNICO JULIO RICARDO BRUNA JULIO SERENA SERENA RICARDO
Uma juno externa nos permite unir tabelas atravs de colunas com nmeros diferentes de linhas, sem que as linhas comuns s duas sejam excludas da tabela resultado. Ao contrrio, as linhas exclusivas de apenas uma das tabelas so includas no resultado, com valores nulos em quaisquer colunas da outra tabela, onde aquelas linhas no existem. O recurso de junes externas s existe em poucas implementaes da linguagem SQL. Entretanto, por consider-lo importante e como possivelmente ser implementado em maior escala no futuro, vamos analisar como efetuado este tipo de juno no SQL Base. A sintaxe SQL Base para converter o exemplo anterior em uma juno externa a fim de incluir as demais linhas da tabela no contidas no resultado simples: basta acrescentar um sinal de adio (+) ao lado do nome da coluna que no possui as linhas externas, ou seja, aquela na qual incluiremos valores nulos no resultado, na condio de juno. Ex.: SELECT HOSPEDES.NOME, SEXO, BIOTIPO, ALTURA, TECNICO FROM HOSPEDES, LISTA_DE_HOSPEDES WHERE HOSPEDES.NOME = LISTA_DE_HOSPEDES.NOME(+);
6.3.
Auto-Junes
Por muitas vezes, precisamos fazer uma juno de uma tabela com ela mesma. Esta uma forma de tratarmos uma nica tabela como se fosse na verdade duas tabelas, a fim de possibilitar certos tipos de queries.
Pgina 21
Suponhamos que quisssemos selecionar todos os hspedes que tenham obtido o mesmo percentual de desconto que Maurcio de Souza. Todas as informaes que desejamos esto na tabela LISTA_DE_HOSPEDES, que tem a seguinte aparncia: SELECT * FROM LISTA_DE_HOSPEDES; NOME JANE FYUNDAI MARCELO FREITAS JANE FYUNDAI ALEXANDRE GOMES JOS AUGUSTO MAURCIO DE SOUZA BIANCA OLIVEIRA STELLA SHIELDS ALEXANDRE GOMES QUARTO 3 2 4 1 7 5 6 8 9 TCNICO JLIO BRUNA SERENA RICARDO JLIO RICARDO BRUNA SERENA BRUNA CHEGADA 15-08-1997 26-08-1997 24-08-1997 14-08-1997 15-08-1997 25-08-1997 15-08-1997 25-08-1997 17-08-1997 SADA 17-08-1997 16-08-1997 19-08-1997 20-08-1997 23-08-1997 0.15 0.05 0.15 0.20 DESCTO 0.20 0.10
Poderamos, evidentemente, usar uma query para selecionar DESCONTO onde NOME fosse igual a MAURICIO DE SOUZA e, em seguida, uma outra que selecionasse NOME e DESCONTO onde DESCONTO fosse igual ao resultado da primeira query. Mais digamos que quisssemos optar por uma forma mais elegante e menos trabalhosa usar uma nica query. Esta tarefa parece bastante simples. Poderamos comear a construir a query assim: SELECT NOME, DESCONTO FROM LISTA_DE_HOSPEDES WHERE DESCONTO = ...? Entretanto, neste ponto chegamos a um impasse. Queremos dizer WHERE DESCONTO = (o desconto de Maurcio de Souza), mas no vemos como. Observe como seria fcil resolver este problema se, ao invs de lida com apenas uma tabela, estivssemos lidando com duas, a fim de obter o desconto de Maurcio de Souza de uma e as informaes sobre os outros hspedes da outra. Ento, usando as letras A e B para distinguir duas tabelas na realidade idnticas, teramos a seguinte query: SELECT A.NOME, A.DESCONTO FROM LISTA_DE_HOSPEDES A, LISTA_DE_HOSPEDES_B WHERE A.DESCONTO = B.DESCONTO AND B.NOME = MAURICIO DE SOUZA; NOME MAURCIO DE SOUZA STELLA SHIELDS DESCTO 0.15 0.15
Como voc pode comprovar atravs do resultado, esta a forma que temos para resolver este tipo de query chamada auto-juno. Os nomes de tabelas temporrios, denominados nomes correlatos ou ttulos (labels), so os elementoschaves que permitem que a juno ocorra a partir de uma nica tabela. Os nomes correlatos so definidos na lista do FROM, na qual estabelecemos que a tabela em questo passa a ser conhecida por estes nomes. A partir da, todos os nomes de colunas que quisermos usar tero como prefixo estes nomes correlatos.
Pgina 22
6.4.
7.2.
Pgina 23
Suponhamos que quisssemos criar uma tabela HOSPEDES_HOMENS, idntica HOSPEDES, exceo de que, ao invs de listar o sexo, o biotipo e a altura de todos os hspedes, antigos e atuais, HOSPEDES_HOMENS contm apenas os dados dos hspedes do sexo masculino (e, portanto, no listar o sexo). A tabela criada pela declarao abaixo: CREATE TABLE HOSPEDES_HOMENS (NOME VARCHAR(25), BIOTIPO VARCHAR(1), ALTURA INTEGER); Agora temos que incluir dados. Os dados que desejamos j esto cadastrados na tabela HOSPEDES e podem ser extrados e includos atravs de uma declarao INSERT contendo uma query. INSERT INTO HOSPEDES_HOMENS SELECT NOME, BIOTIPO, ALTURA FROM HOSPEDES WHERE SEXO = M; As nicas restries existentes neste caso so as seguintes: O nmero de colunas do SELECT tem que ser o mesmo que o da declarao INSERT ou, como nosso exemplo, o mesmo nmero de colunas contidas na tabela, se as colunas no forem mencionadas. O tipo e o tamanho dos dados selecionados tm que ser compatveis com as especificaes das colunas na tabela de destino. Por exemplo, nmeros podem ser includos em uma coluna de tipo caractere, mas o contrrio no aceito.
8.1.
Alterando os Dados
Uma declarao de manipulao de dados que j vimos o INSERT, cuja funo incluir novas linhas. Alm do INSERT, h mais duas outras declaraes de manipulao de dados: UPDATE e DELETE. Como o INSERT as duas declaraes nos permitem alterar o contedo do banco de dados. UPDATE altera linhas existentes e DELETE as exclui do banco de dados.
Pgina 24
Podemos usar a declarao UPDATE para realizar as duas alteraes de uma s vez. A segunda condio de pesquisa, especificando a data de chegada, necessria pois existem dois quartos ocupados pelo Andr em LISTA_DE_HOSPEDES, e s queremos alterar um deles. UPDATE LISTA_DE_HOSPEDES SET QUARTO = 7, DESCONTO = DESCONTO + 0.02 WHERE NOME = ALEXANDRE AND CHEGADA = 17-08-97; Como podemos observar no exemplo, possvel alterar mais de uma coluna ao mesmo tempo e usar expresses aritmticas para indicar o valor novo.
8.2.
Pgina 25
Em SQL Base, temos cinco opes de clusulas ou continuaes para complementar a declarao, dependendo da operao desejada: ADD (incluir) MODIFY (modificar) DROP (eliminar) RENAME (trocar o nome de) RENAME TABLE (trocar nome tabela) uma nova coluna o tamanho de uma coluna ou se a coluna dever aceitar valores nulos. uma coluna existente uma coluna existente
Pgina 26
Pgina 27
9.1.
Utilizando um ndice
A query abaixo pesquisa duas tabelas para obter o nome, o tcnico e a altura de todos os hspedes. SELECT A.NOME, TECNICO, ALTURA FROM LISTA_DE_HOSPEDES A, HOSPEDES B WHERE A.NOME = B.NOME; Usaremos a declarao CREATE INDEX para criar um ndice, especificando primeiro o nome da tabela, LISTA_DE_HOSPEDES, e, em seguida, entre parnteses, a coluna ou as colunas a serem indexadas. Podemos incluir tambm a palavra-chave ASC ou DESC ao lado do nome da coluna para identificar a indexao em ordem crescente ou decrescente. O default a ordem crescente. CREATE INDEX NOME_ID ON LISTA_DE_HOSPEDES (NOME); O ndice acelera a execuo da query anterior em 13% em um PC/AT.
9.2.
Pgina 28
A declarao abaixo cria um ndice nico na coluna NOME da tabela HOSPEDES: CREATE UNIQUE INDEX NOME1_IND ON HOSPEDES (NOME); Chamamos este ndice de NOME1_IND porque j temos o NOME_IND, e os ndices tm que ter nomes diferentes, mesmo que sejam criados em colunas de tabelas diferentes. Devido a presena de um ndice nico, qualquer valor duplicado no ser aceito. Agora com os dois ndices que criamos, a query do incio deste tpico tem a sua execuo acelerada em 20% em um PC/AT.
9.3.
Sempre que quisermos consultar a faixa aceitvel de peso de uma pessoa na tabela QUADRO_DE_PESOS, teremos que fornecer ao sistema os valores das trs colunas ALTURA, SEXO e BIOTIPO. A query a seguir executa esta consulta. Seleciona o nome, o tcnico e a faixa aceitvel de peso de todos os hspedes. NOME e TECNICO vm da LISTA_DE_HOSPEDES; a altura, o sexo e o biotipo so obtidos da tabela HOSPEDES e so usados para localizar a respectiva faixa no QUADRO_DE_PESOS: SELECT A.NOME, TECNICO, PS_MIN, PS_MAX FROM LISTA_DE_HOSPEDES A, HOSPEDES B, QUADRO_DE_PESOS C WHERE A.NOME = B.NOME AND B.SEXO = C.SEXO AND B.ALTURA = C.ALTURA AND B.BIOTIPO = C.BIOTIPO; Podemos reduzir significamente o tempo de execuo da query criando um ndice concatenado abrangendo as colunas ALTURA, SEXO e BIOTIPO: CREATE INDEX PESO_IND ON QUADRO_DE_PESOS (ALTURA, SEXO, BIOTIPO); O ndice concatenado reduz o tempo de execuo da query em 38% em um PC/AT.
9.4.
Apagando um ndice
Qualquer ndice de uma tabela eliminado automaticamente quando a tabela excluda. Para eliminar um ndice manualmente, usamos a declarao DROP INDEX, que a mesma declarao usada para apagar tabelas. S agora concluiremos a explicao desta declarao. A declarao abaixo apaga o ndice PESO_IND que criamos na tabela QUADRO_DE_PESOS: DROP INDEX PESO_IND; A tabela onde foi criado o ndice no afetada pela sua eliminao.
Pgina 29
10.Programando em SQL
No incio desta apostila, vimos como usar a linguagem SQL de modo interativo, ou seja, como executar as declaraes SQL diretamente do teclado. Agora, focalizaremos o tpico programao em SQL declaraes SQL embutidas em programas escritos em outra linguagem, como por exemplo, C ou COBOL.
Pgina 30
Clique na opo "Abrir banco de dados existentes", selecione o arquivo Northwind e clique em "OK". Caso o arquivo no esteja na relacionado na lista de arquivos, selecione a opo "Mais arquivos..." e em seguida o boto OK. O arquivo encontra-se na seguinte pasta "C:\Arquivos de Programas\Microsoft Office\Exemplos". Aps o arquivo aberto aparecer a seguinte tela:
Esta janela possui toda estrutura do arquivo Nortwind, esta estrutura dividida pelas seguintes guias: Tabela / Consulta / Formulrio / Relatrios / Macros / Mdulos, a guia tabela possui todas as tabelas do Northwind, que utilizaremos nos nossos exerccios. Clique na guia Consulta, exclua todas as consultas existentes nesta caixa ( Shift+Delete). A caixa dever ficar com a seguinte aparncia:
Pgina 31
Selecione a opo Modo estrutura e clique no boto OK. Em seguida clique no boto Cancelar na prxima Caixa de Dilogo. Pronto! Voc dever esta com a janela de consulta aberta. (observe a figura abaixo)
Antes de iniciarmos os nossos exerccios, precisaremos alterar para a janela MODO SQL. Siga as seguintes instrues: Clique no Menu Exibir, opo Modo SQL.
Esta janela ser utilizada para criarmos nossas consultas atravs da SQL. Para executar cada consulta clique no boto "Executar" na barra de ferramentas. Obs1.: Para cada consulta criada utilizaremos um arquivo, ou seja, gravaremos a consulta atual e abriremos uma nova. Obs2.: Caso necessrio consulte os anexos de tabelas para resoluo dos exerccios.
Pgina 32