Você está na página 1de 23

Guia rápido para consultas SQL

Publicado em: 19/01/2010

COMANDO SELECT

A linguagem SQL foi criada com o objetivo de padronizar os comandos de


manipulação de dados em SGBD’s. Hoje em dia, apesar da linguagem possuir uma
quantidade considerável de extensões e implementações proprietárias, pode se
afirmar que a meta foi alcançada. Conhecendo bem a linguagem é possível acessar os
recursos básicos de qualquer banco relacional, como Oracle, SQL Server ou MySQL,
sem praticamente nenhuma mudança.
Veremos nesse artigo um pequeno guia de consultas para o comando SELECT,
um dos mais importantes da linguagem SQL.

SELECT simples

O comando SELECT permite recuperar os dados de um objeto do banco de


dados, como uma tabela, view e, em alguns casos, uma stored procedure (alguns
bancos de dados permitem a criação de procedimentos que retornam valor). A sintaxe
mais básica do comando é:

SELECT <LISTA_DE_CAMPOS>
FROM <NOME_DA_TABELA>

Exemplo:

SELECT CODIGO, NOME FROM CLIENTES


SELECT * FROM CLIENTES

O caractere * representa todos os campos. Apesar de prática, este caractere


não é muito utilizado, pois, para o SGBD, é mais rápido receber o comando com todos
os campos explicitados. O uso do * obriga o servidor a consultar quais são os campos
antes de efetuar a busca dos dados, criando mais um passo no processo.

COMANDO WHERE

A cláusula Where permite ao comando SQL passar condições de filtragem.


Veja o exemplo:

SELECT CODIGO, NOME FROM CLIENTES


WHERE CODIGO = 10

SELECT CODIGO, NOME FROM CLIENTES


WHERE UF = ‘RJ’

SELECT CODIGO, NOME FROM CLIENTES


WHERE CODIGO >= 100 AND CODIGO <= 500

SELECT CODIGO, NOME FROM CLIENTES


WHERE UF = ‘MG’ OR UF = ‘SP’

Os parênteses corretamente utilizados dão mais poder as consultas:

SELECT CODIGO, NOME FROM CLIENTES


WHERE UF = ‘RJ’ OR (UF = ‘SP’ AND ATIVO = ‘N’)
Neste comando, todos os clientes do Rio de Janeiro e apenas os clientes
inativos de São Paulo seriam capturados.

SELECT CODIGO, NOME FROM CLIENTES


WHERE (ENDERECO IS NULL) OR (CIDADE IS NULL)

Aqui todos os clientes que não possuem endereço ou cidade cadastrada serão
selecionados.

FILTRO DE TEXTO

SELECT CODIGO, NOME FROM FUNCIONARIOS


WHERE DEPARTAMENTO = ‘VENDAS’

Para busca parcial de string, o SELECT fornece o operador LIKE

SELECT CODIGO, NOME FROM CLIENTES


WHERE NOME LIKE ‘MARIA%’

Neste comando, todos os clientes cujos nomes iniciam com Maria serão
retornados. Se quisermos retornar os nomes que contenham ‘MARIA’ também no
meio, podemos alterar para:

SELECT CODIGO, NOME FROM CLIENTES


WHERE NOME LIKE ‘%MARIA%’

O uso de máscara no inicio e no fim da string fornece maior poder de busca,


mas causa considerável perda de performance. Este recurso deve ser utilizado com
critério.

OBS: Em alguns bancos de dados a máscara de filtro não é representada por %.


Consulte a referência do banco para verificar o caractere correto.
Por padrão a SQL diferencia caixa baixa de caixa alta. Para eliminar essa
diferença, utiliza a função UPPER

SELECT CODIGO, NOME FROM CLIENTES


WHERE UPPER(NOME) LIKE ‘MARIA %SILVA%’

ORDENAÇÃO

A ordenação pode ser definida com o comando ORDER BY. Assim como no
comando WHERE, o campo de ordenação não precisa estar listado como campo de
visualização:

SELECT CODIGO, NOME FROM CLIENTES


ORDER BY NOME

SELECT CODIGO, NOME FROM CLIENTES


ORDER BY UF, NOME

A utilização da palavra DESC garante a ordenação invertida

SELECT CODIGO, NOME FROM CLIENTES


ORDER BY NOME DESC
SELECT CODIGO, NOME FROM CLIENTES
ORDER BY UF DESC

JUNÇÃO DE TABELAS

O SELECT permite juntar duas ou mais tabelas no mesmo resultado. Isso


pode ser feito de várias formas:

SELECT CLIENTES.CODIGO, CLIENTES.NOME, PEDIDOS.DATA


FROM CLIENTES, PEDIDOS
WHERE CLIENTES.CODIGO = PEDIDOS.CODCLIENTE

Nesta linha as tabelas relacionadas CLIENTES e PEDIDOS são unificadas


através do campo chave, em uma operação de igualdade. Repare que os nomes dos
campos passam a ser prefixados pelo nome das tabelas, resolvendo duplicidades. Uma
versão resumida desse comando pode ser:

SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR


FROM CLIENTES A, PEDIDOS B
WHERE A.CODIGO = B.CODCLIENTE

O uso de aliases no código SQL torna a manutenção mais simples.


No comando abaixo temos várias tabelas unificadas em uma mesma cláusula:

SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR, C.QTD, D.DESCRIC


FROM CLIENTES A, PEDIDOS B, ITENS C, PRODUTOS D
WHERE A.CODIGO = B.CODCLIENTE
AND B.CODIGO = C.CODPEDIDO
AND C.CODPRODUTO = D.CODIGO

Neste comando unificamos as tabelas relacionadas CLIENTES, PEDIDOS,


ITENS e PRODUTOS. Veja mais alguns exemplos:

SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR


FROM CLIENTES A, PEDIDOS B
WHERE A.CODIGO = B.CODCLIENTE
AND A.UF = ‘RJ’

Observe que a junção através da igualdade de campos traz como resultado


somente os registros que possuem referências nas duas tabelas. Observe o comando
abaixo:

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO


FROM PROUTOS A, COMPONENTES B
WHERE A.CODIGO = B.CODPRODUTO

Os produtos que não possuem componentes não são selecionados. Caso seja
necessário criar uma listagem incluindo também os registros que não possuem
correspondência, deve se utilizar o comando JOIN.

COMANDO JOIN

A junção de tabelas no comando SELECT também pode ser feita com o


comando JOIN. Este comando deve ser utilizado com a palavra reservada INNER ou
com a palavra OUTER:

INNER: Semelhante ao uso do operador “=” na junção de tabelas. Aqui os registros


sem correspondências não são incluídos. Esta cláusula é opcional e pode ser omitida
no comando JOIN.

OUTER: Os registros que não se relacionam também são exibidos. Neste caso, é
possível definir qual tabela será incluída na seleção, mesmo não tendo
correspondência.
Para exemplificar, temos as tabelas abaixo:

Observe os exemplos e o resultado produzido:

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO, B.QTD


FROM PRODUTOS A
INNER JOIN COMPONENTES B
ON (A.CODIGO = B.CODPRODUTO)

Este comando pode ser escrito na versão resumida abaixo:

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO


FROM PRODUTOS A
JOIN COMPONENTES B
ON (A.CODIGO = B.CODPRODUTO)

Como mostrado no resultado, os produtos que não possuem componentes não


são incluídos na seleção.

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO, B.QTDE


FROM PRODUTOS A
LEFT OUTER JOIN COMPONENTES B
ON (A.CODIGO = B.CODPRODUTO)

Neste comando todos os produtos serão incluídos na seleção, independente de


possuírem um componente. Observe que a palavra LEFT se refere à primeira tabela do
relacionamento. O mesmo comando poderia ser descrito da forma:

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO


FROM COMPONENTES A
RIGHT OUTER JOIN PRODUTOS B
ON (A.CODIGO = B.CODPRODUTO)

A ordem das tabelas foi invertida mas o resultado é o mesmo. Observe mais
alguns exemplos:

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO, B.QTDE


FROM PRODUTOS A
JOIN COMPONENTES B
ON (A.CODIGO = B.CODPRODUTO)
WHERE A.CATEGORIA = 1

SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO


FROM PRODUTOS A JOIN COMPONENTES B
ON (A.CODIGO = B.CODPRODUTO)
WHERE A.CATEGORIA = 1 OR A.CATEGORIA = 2
ORDER BY A.CATEGORIA, A.DESCRICAO
FULL OUTER JOIN

Podemos ainda combinar o uso de INNER e OUTER através do comando FULL


OUTER JOIN. Neste caso, todos os registros das duas tabelas envolvidas serão
exibidas, tendo ou não relacionamento. Observe:

UNION

Existe ainda uma segunda forma de juntar tabelas com o comando SELECT.
Através do parâmetro UNION, é possível colar o conteúdo de duas tabelas. Veja o
exemplo:

SELECT CODIGO, NOME FROM CLIENTES


UNION
SELECT CODIGO. NOME FROM FUNCIONARIOS

O resultado deste comando é a listagem de todos os clientes e a listagem de


todos os funcionários, dentro do mesmo result set. Repare que no comando JOIN á
união é horizontal e no UNION a união é vertical.
Por default, os registros duplicados são eliminados na cláusula UNION. No
exemplo anterior, se tivéssemos um cliente com o mesmo nome e código de um
funcionário, apenas o registro da primeira tabela seria exibido. Para incluir todos os
registros, independente de duplicidade, utilize a palavra ALL:

SELECT CODIGO, NOME FROM CLIENTES


UNION ALL
SELECT CODIGO, NOME FROM FUNCIONARIOS

FUNÇÕES DE AGRUPAMENTO

São cinco as funções básicas de agrupamento:


AVG: Retorna a média do campo especificado

SELECT AVG(VALOR) FROM PEDIDOS

MIN/MAX/SUM: Respectivamente retorna o menor valor, o maior e o somatório de um


grupo de registros:

SELECT MIN(VALOR) FROM PEDIDOS


SELECT MAX(VALOR) FROM PEDIDOS
SELECT AVG(VALOR) FROM PEDIDOS

COUNT: Retorna a quantidade de itens da seleção:

SELECT COUNT(CODIGO) FROM CLIENTES

AGRUPAMENTO

Um poderoso recurso do comando SELECT é o parâmetro GROUPY BY. Através


dele podemos retornar informações agrupadas de um conjunto de registros,
estabelecendo uma condição de agrupamento. É um recurso muito utilizado na
confecção de relatórios. Para exemplificar, temos as tabelas CLIENTES E PEDIDOS

SELECT CODCLIENTE, MAX(VALOR)


FROM PEDIDOS
GROUP BY CODCLIENTE

O comando acima retorna o maior valor de pedido de cada cliente. Observe o


resultado:
SELECT CODCLIENTE, COUNT(*)
FROM PEDIDOS
GROUPY BY CODCLIENTE

Aqui vemos quantos pedidos foram feitos por cada cliente.

HAVING

Através do comando HAVING podemos filtrar a cláusula GROUP BY.


Observe o comando abaixo:

SELECT CODCLIENTE, COUNT(*)


FROM PEDIDOS
GROUPY BY CODCLIENTE
HAVING COUNT(*) >= 2

Somente os clientes com 2 ou mais pedidos serão selecionados. Repare que o


HAVING é utilizado, geralmente com alguma função de agrupamento. Para filtros
normais, pode se utilizar o comando WHERE. Observe o exemplo abaixo:

SELECT CODCLIENTE, COUNT(*)


FROM PEDIDOS
WHERE DATA > ‘06/10/2002’
GROUPY BY CODCLIENTE
HAVING COUNT(*) >= 2
Repare que o cliente número 3 apresentou apenas dois pedidos, visto
que o primeiro não possui data maior que 06/10.
SQL Dicas & Truques (versão 0.1)
Publicado em: 04/02/2004

Introdução

Todo programador sempre é obrigado a trabalhar com mais de uma linguagem, precisa
entender pelo menos HTML, JavaScript e sua linguagem escolhida, além da sintaxe SQL
para acesso à banco de dados.

Nos meus primeiros anos de programação SQL, sempre gastava horas pesquisando
sintaxe pelas páginas de resultado do Google e alguns comandos exóticos nunca ficavam
fixados em mente, visto que eram utilizados com freqüência muito baixa. Pensando nisso,
certo dia criei um arquivo vazio e comecei a anotar as queries menos comuns e não
menos úteis e hoje resolvi compartilhar este pedaço do meu diário de programador aqui
no Viva o Linux.com.br.

Criação de usuários

GRANT ALL PRIVILEGES ON meuBD.* TO joao@localhost


IDENTIFIED BY 'ola' WITH GRANT OPTION;
FLUSH PRIVILEGES;
Descrição: atribui todos os privilégios à todas as tabelas do banco de dadosmeuBD ao
usuário joao, a partir da máquina localhost, cuja senha é ola. O comando FLUSH
PRIVILEGES atualiza as novas alterações no daemon do MySQL. Caso o usuário joao
não existe, um novo usuário será criado.

Funções de data e hora

SELECT * FROM table WHERE MONTH(data)='05';


Descrição: seleciona todos os registros da tabela table onde o campo data possui a data
no mês de Maio.

SELECT DISTINCT DAYOFMONTH(data),MONTH(data),YEAR(data);


Descrição: seleciona o dia do mês, mês e ano sem repetir da tabela table.

SELECT DATE_FORMAT(campoData,'%d-%m-%Y') FROM table;


Descrição: formata o campoData no seguinte formato: dd/mm/yyyy. Maiores detalhes
sobre a funções DATE_FORMAT podem ser encontradas através da URL:
http://www.mysql.com/doc/en/Date_and_time_functions.html.

Importando e exportando arquivos

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name


FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Descrição: carrega os registros em formato txt do arquivo data.txt para a tabela tbl_name,
onde os campos estão separados por ',' (vírgula), delimitados por '"' (aspas) e as linhas
delimitadas por '\n' (quebra de linha).

SELECT * INTO OUTFILE 'saida.txt' FROM table;


Descrição: seleciona todos os registros da tabela table e os grava no arquivo saida.txt.

Transferindo registros de uma tabela para outra

INSERT INTO table1 (nome) SELECT nome FROM table2;


Descrição: insere todos os nomes da tabela table2 na tabela table1.

Continue acompanhando este artigo, aos poucos vou adicionando mais dicas e truques
SQL.

Atenciosamente,
Fábio Berbert de Paula
fabio@vivaolinux.com.br

Programação de Banco de Dados - parte 3


Publicado em: 30/07/2004

Este é o terceiro artigo relacionado com programação de Banco de Dados, sairemos um


pouco de teoria e vamos abordar mais a prática explicando a linguagem SQL. No segundo
artigo o enfoque foi explicar a arquitetura cliente servidor com os modelos de 2 e 3
camadas.

SQL (Structured Query Language)

Quando os Bancos de Dados Relacionais estavam sendo desenvolvidos, foram criadas


linguagens destinadas à sua manipulação. O departamento de Pesquisa da IBM
desenvolveu a SQL como forma de interface para o sistema de BD relacional denominado
SYSREM R, início dos anos 70. Em 1986 o American National Standard Institute
( ANSI) , publicou um padrão SQL.A SQL estabeleceu-se como linguagem padrão de
Banco de Dados Relacional.

SQL apresenta uma série de comandos que permitem a definição dos dados, chamada de
DDL ( Data Definition Language) , composta entre outros pelos comandos Create, que é
destinado a criação do Banco de Dados, das tabelas que o compõe, além das relações
existentes entre as tabelas. Como exemplo de comandos da classe DDL temos os
comandos Create, Alter e Drop.

Os comandos da série DML ( Data Manipulation Language), destinados a consultas,


inserções, exclusões e alterações em um ou mais registros de uma ou mais tabelas de
maneira simultânea. Com exemplo de comandos da classe DML temos os comandos
Select, Insert, Update e Delete.

Um subclasse de comandos DML, a DCL ( Data Control Language), dispõe de comandos


de controle como Grant e Revoke.

A linguagem SQL tem como grandes virtudes sua capacidade de gerenciar índices, sem
necessidade de controle individualizado de índice corrente, algo muito comum nas
linguagens de manipulação de dados do tipo registro a registro.Outra característica muito
importante disponível em SQL é sua capacidade de construção de visões, que são formas
de visualizarmos os dados na forma de listagens independente das tabelas e organização
lógica dos dados.

Outra característica interessante da linguagem SQL é a sua capacidade que dispomos de


cancelar uma série de atualizações ou de as gravarmos, depois de iniciarmos uma
seqüência de atualizações. Os comandos Commit e Rollback são responsáveis por estas
facilidades.

Devemos notar que a linguagem SQL consegue implementar estas soluções, somente pelo
fato de estar baseada em Banco de Dados, que garante por si mesmo a integridade das
relações existentes entre as tabelas e seus índices.

» COMANDOS SQL

Comando Descrição
SELECT Recupera dados do Banco de Dados
INSERT Insere novas linhas, altera linhas existentes e remove linhas de tabelas do
UPDATE banco de dados, respectivamente. Estes comandos são conhecidos como
DELETE comandos DML (Data Manipulation Language).
CREATE Cria, altera e remove objetos do banco de dados. São conhecidos como
ALTER comandos DDL (Data Definition Language).
DROP
RENAME
TRUNCATE
COMMIT Gerenciam as modificações realizadas pelos comandos DML. As
ROLLBACK modificações efetuadas pelos comandos DML podem ser agrupadas em
SAVEPOINT transações lógicas.
GRANT Atribuem e removem direitos de acesso ao banco de dados e aos objetos a
REVOKE ele pertencentes. São conhecidos como comandos DCL (Data Control
Language).

» DML ( Data Manipulation Languagem)

Veremos agora os comandos SQL DML destinados a manipulação dos dados.Comandos:


COMANDO SELECT

Sintaxe: Select <campos da tabela> From <nome da tabela> Where <condição>

Exemplo 1: Selecionar linhas de uma tabela

SELECT NUMERO, NOME FROM EMPREGADOS;

Exemplo 2: Utilizando a cláusula DISTINCT para suprimir linhas duplicatas.

SELECT DISTINCT CARGO FROM EMPREGADOS;

Exemplo 3: Utilizando a cláusula DISTINCT com várias colunas.

SELECT DISTINCT CARGO, NUMERO_DEPT FROM EMPREGADOS;

Exemplo 4: Utilizando a cláusula * para listar todas as colunas da tabela.

SELECT * FROM EMPREGADOS

Exemplo 5: Utilizando operadores aritméticos (+, -,*, / ) na cláusula Select.

SELECT NOME, SALARIO * 12, DT_ADMISSAO FROM EMPREGADOS;

Exemplo 6: Utilizando Alias.

SELECT NOME, SALARIO * 12 AS SAL_ANUAL,DT_ADMISSAO FROM


EMPREGADOS;
OU
SELECT NOME, SALARIO * 12 "SAL ANUAL", DT_ADMISSAO FROM
EMPREGADOS;

Exemplo 7: Utilizando operador de concatenação.

SELECT NOME||' '||SOBRENOME FROM EMPREGADOS;

Como Ordenar e Limitar as Linhas Selecionadas

Exemplo 1: Ordenando as linhas selecionadas com a cláusula ORDER BY

SELECT NOME, SALARIO FROM EMPREGADOS ORDER BY SALARIO;


OU
SELECT NOME, SALARIO FROM EMPREGADOS ORDER BY SALARIO DESC;

Obs: Na ordenação ascendente, valores NULOS aparecem no final.

Exemplo 2: Ordenando pela posição da coluna selecionada

SELECT NOME, SALARIO * 12


FROM EMPREGADOS ORDER BY SALARIO * 12;
OU
SELECT NOME, SALARIO * 12 FROM EMPREGADOS ORDER BY 2;

Exemplo 3: Selecionando apenas os empregados lotados no departamento 20.

SELECT NOME, NUMERO_DEPT, SALARIO FROM EMPREGADOS


WHERE NUMERO_DEPT = 20 ORDER BY SALARIO;

Exemplo 4: Selecionando apenas o empregado denominado SMITH.

SELECT NOME, NUMERO_DEPT, SALARIO FROM EMPREGADOS WHERE


NOME = 'CELIO';

Exemplo 5: Selecionando com operadores lógicos.

SELECT NOME, NUMERO_DEPT, SALARIO FROM EMPREGADOS


WHERE SALARIO > 1000;

Observações:

1. Operadores para comparações lógicas: = > >= <= <> 2. Outros comparadores:

o
BETWEEN ... AND ... NOT BETWEEN
u
o
IN (Lista) NOT IN
u
o
LIKE NOT LIKE
u
o
IS NULL IS NOT NULL
u

3. Operadores lógicos: AND


OR
NOT

Exemplo 6: Selecionando linhas com BETWEEN ... AND ...

SELECT NOME, DT_ADMISSAO FROM EMPREGADOS


WHERE DT_ADMISSAO BETWEEN '28-SEP-90' AND '30-JAN-91';

Exemplo 7: Selecionando linhas com a cláusula IN.

SELECT NOME, NUMERO_DEPT, SALARIO FROM EMPREGADOS


WHERE NUMERO_DEPT IN (10, 20) ORDER BY NUMERO_DEPT, SALARIO;

Exemplo 8: Selecionando linhas com a cláusula LIKE.


SELECT NOME, SALARIO FROM EMPREGADOS WHERE NOME LIKE 'S%'
ORDER BY NOME;
OU
SELECT NOME, SALARIO FROM EMPREGADOS
WHERE NOME NOT LIKE '%I%'
ORDER BY NOME;
OU
SELECT NOME, SALARIO FROM EMPREGADOS
WHERE NOME LIKE '_A%';

Observações:

- "%" representa nenhum ou muitos caracteres.


- "_" representa um único caracter.

Exemplo 9: Selecionando linhas com a cláusula IS NULL.

A coluna Num_supervisor contém o número do empregado que supervisiona o empregado


corrente.

SELECT NUMERO, NOME, CARGO, NUM_SUPERVISOR


FROM EMPREGADOS;

Com esta Query recuperamos o único empregado da empresa que não é gerenciado por
ninguém, isto é, o Presidente da empresa.

SELECT NOME, CARGO, NUM_SUPERVISOR FROM EMPREGADOS


WHERE NUM_SUPERVISOR IS NULL;

Observação: O resultado da cláusula Where abaixo é sempre falso pois um valor nulo não
pode ser igual ou diferente de outro valor, mesmo que este outro valor seja nulo. Se valores
nulos forem comparados por operadores que não o "IS NULL" o resultado será sempre
falso.

SELECT NOME, CARGO, NUM_SUPERVISOR FROM EMPREGADOS


WHERE NUM_SUPERVISOR = NULL;

Exemplo 10: Selecionando linhas com operadores lógicos.

SELECT NOME, SALARIO, NUMERO_DEPT FROM EMPREGADOS


WHERE SALARIO >= 3000 AND (NUMERO_DEPT = 10
OR NUMERO_DEPT = 30);

Funções Aplicadas a Linhas

Há dois tipos de funções:

- Funções de linhas
- Funções de grupos
Um função de linha retorna um resultado por linha da tabela acessada. Já uma função de
grupo retorna um resultado por grupo de registros.

Exemplos de Funções de Linha:

- LOWER ('UFF') » uff


- UPPER ('uff') » UFF
- INITCAP ('UNIVERSIDADE FEDERAL') » Universidade Federal
- CONCAT ('String1', 'String2') » String1String2
- SUBSTR ('String', 1, 3) » Str
- LENGTH ('UFF') » 3
- NVL (SAL, 0) » Se SAL for NULO seu valor será convertido para zero.
- ROUND (78.731, 2) » 78.73 (Até 4 p/ baixo, Acima de 4 p/ cima)
- ROUND (78.731, 0) » 79
- TRUNC (78.731, 2) » 78.73
- TRUNC (78.731) » 78
- MOD (100, 30) » 10

Exemplo 1: Utilização da função UPPER em uma sentença SQL.

SELECT NOME, SALARIO, NUMERO_DEPT FROM EMPREGADOS


WHERE UPPER (NOME) = 'CELIO';

Exemplo 2: Utilização das funções SUBSTR e LENGTH em uma sentença SQL.

SELECT NOME, LENGTH (NOME) FROM EMPREGADOS


WHERE SUBSTR (NOME, 1, 3) = 'CEL';

Como selecionar dados de mais de uma tabela

Para se exibir dados de mais de uma tabela, através de um comando SQL, é preciso definir
condições de junção. (Joins)

Os joins geralmente ocorrem entre valores de chave primária e de chave estrangeira. Tipos
de Joins:

• Equijoin
• Non-equijoin
• Outer join
• Self Join
• Set operators

Um produto cartesiano geralmente ocorre quando a condição de junção é omitida ou


inválida. Para evitar produtos cartesianos é preciso incluir, na cláusula Where, condições
de junção válidas.

Exemplo 1:Uma junção simples entre a Tabela de Empregados (Emp) e a tabela de


Departamentos (Dept).

SELECT EMPREGADOS.NOME, NUMERO_DEPT, DEPARTAMENTOS.NOME


FROM EMPREGADOS, DEPARTAMENTOS
WHERE EMPREGADOS.NUMERO_DEPT = DEPARTAMENTOS.NUMERO;

Obs: Haverá um ganho de desempenho e de clareza se você sempre qualificar as colunas


com o nome das tabelas às quais elas pertencem.

Exemplo 2: Uma junção simples entre a Tabela de Empregados e a tabela de


Departamentos considerando apenas aqueles empregados que ganham mais de 2500,00.

SELECT EMPREGADOS.NOME, EMPREGADOS.NUMERO_DEPT,


DEPARTAMENTOS.NOME
FROM EMPREGADOS, DEPARTAMENTOS
WHERE EMPREGADOS.NUMERO_DEPT = DEPARTAMENTOS.NUMERO
AND EMPREGADOS.SALARIO > 2500;
OU
SELECT E.NOME, E.NUMERO_DEPT, D.NOME
FROM EMPREGADOS E, DEPARTAMENTOS D
WHERE E.NUMERO_DEPT = D.NUMERO
AND E.SALARIO > 2500;

Exemplo 3: Uma junção entre a tabela de Empregados, a tabela de Departamentos e a


tabela de Dependentes.

SELECT E.NOME, E.NUMERO_DEPT, DPT.NOME, DEP.NOME


FROM EMPREGADOS E, DEPARTAMENTOS DPT, DEPENDENTES DEP
WHERE E.NUMERO_DEPT = DPT.NUMERO AND E.NUMERO =
DEP.NUMERO_EMP;

Funções de Grupo

Funções de grupo operam com um conjunto de linhas para dar um resultado por grupo de
linhas. Um conjunto de linhas pode ser uma tabela inteira ou linhas desta tabela divididas
em grupos.

Funções de grupo podem aparecer tanto na cláusula Select quanto na cláusula Having.
A cláusula Group By divide as linhas de uma ou mais tabelas em grupos de linhas.
A cláusula Having seleciona os grupos que serão aceitos.

Funções de Grupo Existentes:

• AVG
• COUNT
• MAX
• MIN
• STDDEV
• SUM
• VARIANCE

Observações:

A cláusula Distinct pode ser utilizada para que sejam considerados apenas valores não
duplicatas. Todas as funções de grupo ignoram valores nulos. Para substituir um valor nulo
por outro valor utilize a função NVL.

Exemplo 1: Utilização de funções de grupo, considerando todas as linhas de uma tabela um


único grupo.

SELECT AVG(SALARIO), MAX(SALARIO), MIN(SALARIO), SUM(SALARIO)


FROM EMPREGADOS;
OU
SELECT MIN(NOME), MAX(NOME)
FROM EMPREGADOS;

Exemplo 2: Um único grupo definido através da cláusula Where.

SELECT AVG(SALARIO), MAX(SALARIO), MIN(SALARIO), SUM(SALARIO)


FROM EMPREGADOS WHERE CARGO LIKE 'VEND%';

Exemplo 3: Utilização da função COUNT para contar o número de empregados lotados no


departamento número 10.

SELECT COUNT(*) FROM EMPREGADOS WHERE NUMERO_DEPT = 10;

Exemplo 4: Utilização da função COUNT para contar o número de empregados que


possuem percentual de comissão diferente de nulo.

SELECT COUNT(PERC_COMISSAO) FROM EMPREGADOS;

Exemplo 5: Utilização da função COUNT para contar o número de empregados na tabela.

SELECT COUNT(NVL(PERC_COMISSAO, 0)) FROM EMPREGADOS;

Observações:

COUNT(*) conta o número de linhas na tabela.


COUNT(PERC_COMISSAO) conta o número de linhas com percentual de comissão
diferente de nulo.
COUNT(NUMERO) conta o número de linhas na tabela uma vez que a coluna NUMERO
é a chave primária da tabela e toda chave primária não pode conter valores nulos.

A cláusula Group By

Exemplo 6: Utilização da cláusula GROUP BY e da função COUNT para se contar


quantos empregados estão lotados em cada departamento.

SELECT NUMERO_DEPT, COUNT(*) FROM EMPREGADOS


GROUP BY NUMERO_DEPT;

Observações:

Qualquer coluna incluída na cláusula SELECT, se não estiver em uma função de grupo,
deverá constar da cláusula GROUP BY.

Com a cláusula WHERE é possível excluir determinadas linhas dos grupos.

Por default as linhas são ordenadas ascendentemente conforme a lista de colunas


especificada na cláusula GROUP BY. Para modificar este comportamento é preciso utilizar
a cláusula ORDER BY.

Exemplo 7: Utilização da cláusula Group By, da função COUNT e de um JOIN para se


contar quantos empregados estão lotados em cada departamento.

SELECT D.NOME "DEPARTAMENTO", COUNT(*) "QTD"


FROM EMPREGADOS E, DEPARTAMENTOS D
WHERE E.NUMERO_DEPT = D.NUMERO
GROUP BY D.NOME;

Exemplo 8: A query abaixo está correta? A intenção é listar o número dos departamentos
seguido da média salarial. No entanto, deseja-se listar apenas aqueles departamentos cuja
média salarial é superior a 2000.

SELECT NUMERO_DEPT, AVG(SALARIO) FROM EMPREGADOS


WHERE AVG(SALARIO) > 2000 GROUP BY NUMERO_DEPT;

A cláusula Having

Para se restringir a inclusão de grupos não se pode utilizar a cláusula WHERE.

A cláusula WHERE deve ser utilizada para se restringir a inclusão de linhas em um grupo.
Para se omitir a inclusão de grupos inteiros do resultado de uma query deve-se utilizar a
cláusula HAVING.

Exemplo 9: A utilização da cláusula HAVING para listar o número dos departamentos


seguido da média salarial de seus empregados. No entanto, deseja-se listar apenas aqueles
departamentos cuja média salarial é superior a 2000.

SELECT NUMERO_DEPT, AVG(SALARIO) FROM EMPREGADOS


GROUP BY NUMERO_DEPT
HAVING AVG(SALARIO) > 2000;

Exemplo 10: A utilização da cláusula GROUP BY para listar a quantidade de empregados


por departamento/cargo. Isto é, grupos dentro de grupos. Não deve ser exibido Número de
Departamento NULO.

SELECT NUMERO_DEPT, CARGO, COUNT(*) FROM EMPREGADOS


GROUP BY NUMERO_DEPT, CARGO HAVING NUMERO_DEPT IS NOT NULL;

As cláusulas do comando Select são avaliadas na seguinte ordem:

Se o comando SQL contem a cláusula WHERE, o SGBD seleciona as linhas candidatas.


O SGBD identifica os grupos especificados pela cláusula GROUP BY.
A cláusula HAVING restringe os grupos resultantes que não estão de acordo com os
critérios especificados nesta cláusula.

A recuperação de dados com subconsultas (Subqueries)

Uma subconsulta é um comando SELECT embutido em uma cláusula de outro comando


SQL.

Quando e como utilizar:

Escreva subconsultas para recuperar dados baseados em critérios desconhecidos.


Pode ser muito útil quando se necessita selecionar linhas de uma tabela com uma condição
que depende dos dados que estão na própria ou em outra tabela.
Subconsultas não podem conter a cláusula ORDER BY.
Duas classes de operadores de comparações são utilizadas em subconsultas:
Operadores de uma única linha: >, =, >=, <, <=, <>
Operadores de multiplas linhas: IN e NOT IN.
Como uma subconsulta é processada?
Primeiramente é executado o comando SELECT aninhado.
Em seguida o resultado é utilizado em uma condição da consulta principal.

Exemplo 1: A utilização de uma subconsulta aninhada para recuperar o nome e salário de


todos os empregados que trabalham no mesmo departamento que o JOSE trabalha.

SELECT NOME, SALARIO FROM EMPREGADOS


WHERE NUMERO_DEPT = (SELECT NUMERO_DEPT
FROM EMPREGADOS
WHERE NOME = 'JOSE');

Exemplo 2: A utilização de uma subconsulta aninhada para recuperar o nome e salário de


todos os empregados que ganham mais do que a média salarial da empresa.

SELECT NOME, SALARIO FROM EMPREGADOS


WHERE SALARIO > (SELECT AVG(SALARIO)
FROM EMPREGADOS);

Exemplo 3: A utilização de uma subconsulta aninhada para recuperar o nome, número do


departamento e salário de todos os empregados que trabalham no departamento situado no
RIO ou no departamento denominado VENDAS.

SELECT NOME, NUMERO_DEPT, SALARIO


FROM EMPREGADOS
WHERE NUMERO_DEPT = (SELECT NUMERO
FROM DEPARTAMENTOS
WHERE LOCAL = 'RIO' OR
NOME = 'VENDAS');

Exemplo 4: A utilização de uma subconsulta aninhada para recuperar o nome, número do


departamento e salário de todos os empregados que trabalham no departamento situado no
RIO ou no departamento denominado VENDAS.

Correção da query anterior com a utilização da cláusula IN uma vez que esta subconsulta
retorna mais de uma linha.

SELECT NOME, NUMERO_DEPT, SALARIO FROM EMPREGADOS


WHERE NUMERO_DEPT IN (SELECT NUMERO
FROM DEPARTAMENTOS
WHERE LOCAL = 'RIO' OR
NOME = 'VENDAS');

Exemplo 5: A utilização de uma subconsulta aninhada para recuperar o número do


departamento e sua média salarial. Devem ser recuperados apenas os departamentos cuja
média salarial é maior do que a média salarial do departamento número 30.

SELECT NUMERO_DEPT, AVG(SALARIO) FROM EMPREGADOS


GROUP BY NUMERO_DEPT
HAVING AVG(SALARIO) >= (SELECT AVG(SALARIO)
FROM EMPREGADOS
WHERE NUMERO_DEPT = 30);

A recuperação de dados com subconsultas correlacionadas

No exemplo abaixo a subconsulta é executada uma vez para cada linha da tabela de
empregados na consulta mais externa.

Exemplo 1: A utilização de uma subconsulta correlacionada para recuperar o nome dos


empregados que trabalham no projeto numero 2.

SELECT NOME FROM EMPREGADOS


WHERE 2 IN ( SELECT NUMERO_PROJ
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO);

Exemplo 2: A mesma query acima sem a utilização de subconsulta correlacionada.

SELECT NOME FROM EMPREGADOS E, TRABALHAM T


WHERE E.NUMERO = T.NUMERO_EMP
AND T.NUMERO_PROJ = 2;

Quantificador Existencial

Exists representa o quantificador existencial, uma noção emprestada da lógica formal. Em


SQL, um predicado existencialmente quantificado é representado pela expressão da forma
EXISTS (SELECT * FROM ... ).

Essa expressão será verdadeira se o resultado do cálculo da subconsulta representado por


"SELECT * FROM ..." não estiver vazio, isto é, se existir pelo menos um registro na tabela
FROM da subconsulta que satisfaz a condição WHERE dessa mesma subconsulta.

Qualquer consulta que utilize IN pode alternativamente ser formulada com EXISTS, porém
o inverso não é verdadeiro.

Exemplo 1: Obter o nome dos empregados que trabalham no projeto nº 2.

SELECT NOME FROM EMPREGADOS E


WHERE EXISTS (SELECT *
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO
AND NUMERO_PROJ = 2);

OU

SELECT NOME
FROM EMPREGADOS E, TRABALHAM T
WHERE E.NUMERO = T.NUMERO_EMP
AND T.NUMERO_PROJ = 2;

Exemplo 2: Obter o nome dos empregados que não trabalham no projeto nº 2.

SELECT NOME FROM EMPREGADOS E


WHERE NOT EXISTS
(SELECT *
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO
AND NUMERO_PROJ = 2);

OU

SELECT NOME FROM EMPREGADOS MINUS SELECT NOME


FROM EMPREGADOS E, TRABALHAM T
WHERE T.NUMERO_EMP = E.NUMERO AND T.NUMERO_PROJ = 2;

União (Union e Union All)

Linhas duplicatas são eliminadas do resultado de uma união a não ser que o operador
UNION inclua explicitamente o quantificador ALL. Assim, no exemplo nº 1, o projeto nº 3
é selecionado em ambos os SELECTS, mas só aparece uma vez no resultado final.

Já o exemplo nº 2 retornará os números de projeto 2, 3 e 3.


Qualquer número de SELECTS pode ser unido pelo UNION.

Quando sabemos que não haverá elementos duplicados no resultado é conveniente


utilizarmos UNION ALL para que o sistema não seja forçado a eliminar duplicidades,
desnecessariamente.

Exemplo 1: Obter o número dos projetos que, ou se iniciaram após 31-JUL-97, ou possuem
o empregado 7566 nele trabalhando. União sem repetição.

SELECT NUMERO FROM PROJETOS WHERE DT_INICIO > '31-JUL-97'


UNION
SELECT NUMERO_PROJ FROM TRABALHAM
WHERE NUMERO_EMP = 7566;

Exemplo 2: Obter o número dos projetos que, ou se iniciaram após 31-JUL-97, ou possuem
o empregado 7566 nele trabalhando. União com repetição.

SELECT NUMERO FROM PROJETOS WHERE DT_INICIO > '31-JUL-97'


UNION ALL
SELECT NUMERO_PROJ FROM TRABALHAM WHERE NUMERO_EMP = 7566;

Exemplo 3: A possibilidade de incluirmos constantes numa cláusula SELECT é


frequentemente útil quando a cláusula UNION é utilizada. Por exemplo, para indicar qual
das duas condições WHERE foi atendida para a inclusão do elemento no resultado final.

SELECT NUMERO, 'DT_INICIO > 07-JAN-90' CONDIÇÃO


FROM PROJETOS
WHERE DT_INICIO > '07-JAN-90'
UNION ALL
SELECT NUMERO_PROJ, 'NUMERO_EMP = 7566'
FROM TRABALHAM
WHERE NUMERO_EMP = 7566;

Resultado:

NUMERO CONDIÇÃO
------------ ---------------------
2 DT_INICIO > 07-JAN-90
3 DT_INICIO > 07-JAN-90
4 DT_INICIO > 07-JAN-90
3 NUMERO_EMP = 7566

No próximo artigo vamos continuar a falar sobre os comandos SQL DML (Insert, Delete e
Update).