Consultas e Comandos em SQL
Consultas e Comandos em SQL
Consultas e Comandos em SQL
1. Introdução
do banco (criando tabelas e visões, por exemplo) e manipular os dados (inserindo, removendo, atualizando e consultando).
Quando escrevemos uma consulta em SQL, especificamos qual o resultado deve ser retornado, e não como chegar nele. Isso
possibilita que o SGBD tenha liberdade para realizar otimizações com propósito de melhorar o desempenho das consultas.
SQL é a linguagem de consulta padrão dos SGBDs relacionais. Isso significa que os SGBDs disponíveis no mercado
implementam e disponibilizam a linguagem SQL para que os usuários utilizem. Os SGBDs acabam não seguindo à risca o
padrão SQL, mas as diferenças de sintaxe são pequenas e sutis. O "grosso" da linguagem é igual.
Qual a vantagem disso? É que, caso o usuário esteja insatisfeito com o SGBD que usa, ele consegue facilmente migrar para
Veremos neste capítulo os pontos mais importantes da linguagem SQL e que são mais cobrados nas provas de concurso.
2. Criando tabelas
Como vimos, a estrutura básica do modelo relacional formal são as relações, que trataremos aqui, informalmente, como tabelas. É
CREATE TABLE nome_tabela (
nome_atributo1 tipo1 restrição1 restrição2 ...,
(...)
)
Onde tipo é o domínio, indicando qual tipo de dados o atributo armazena (um número? uma data?), e restrição é alguma restrição
Não se preocupe porque veremos mais detalhadamente os tipos de dados e as restrições que podem ser especificadas nos próximos
tópicos.
2.1 Tipos de dados
Os tipos de dados especificam o domínio do atributo, ou seja, o conjunto de valores válidos para o campo. Os tipos básicos que
existem na linguagem SQL são: numérico, cadeia de caracteres, booleano e data/hora. Vamos ver cada um deles:
2.1.1 Numérico
Os valores inteiros são representados por INTEGER ou INT. Eles também podem ter tamanhos variados (BIGINT, SMALLINT). A
As cadeias de tamanho fixo são representadas por CHAR(n) ou CHARACTER(n), onde n é o número de caracteres. Se for inserida
uma cadeia de comprimento menor que n, ela é automaticamente preenchida com caracteres em branco. Para fins de comparação,
As cadeias de tamanho variável, por sua vez, são especificadas por VARCHAR(n) ou CHARACTER VARYING(n), onde n é o número
máximo de caracteres.
As cadeias de caracteres são representadas por aspas simples e diferenciam letras maiúsculas de minúsculas. É possível
comparar duas cadeias de caracteres através dos operadores >, >=, <, <= (maior que, maior ou igual, menor que, menor ou igual).
Uma cadeia será menor que a outra se ela vier antes na ordem alfabética. Exemplo: 'Casa' é menor que 'Piscina'.
Uma operação bastante utilizada nas cadeias de caracteres é a concatenação, representada pelo operador || (duas barras
verticais). Essa operação combina duas cadeias de caracteres, unindo em uma só. Por exemplo 'abc' || '999' vai resultar em 'abc999'.
2.1.3 Booleano
O tipo booleano é representado por BOOLEAN. Ele armazena TRUE ou FALSE e é indicado para atributos que são do tipo "sim" ou
"não". Por exemplo: o atributo casado pode ser modelado como do tipo booleano, contendo TRUE se a pessoa for casada e FALSE se
2.1.4 Data e tempo
O tipo data é representado por DATE. Ele armazena as datas no formato DD-MM-YYYY e só aceita datas válidas. Por exemplo: o
componente mês não pode receber um valor maior que 12 (afinal, só temos 12 meses no ano).
O tipo tempo é representado por TIME e armazena o horário no formato HH:MM:SS. É possível ainda definir precisão em segundos
Vamos ver um exemplo: imagine que em um banco de dados seja armazenado com frequência a placa dos carros, ou seja, várias
tabelas armazenam um atributo que representa a placa. Supondo que as placas são formadas por uma cadeias de caracteres de
2.2 Restrições
As restrições são mecanismos que garantem a integridade e consistência dos dados do banco.
Se um determinado atributo não puder receber o valor nulo, devemos especificar a restrição NOT NULL. Caso não especifiquemos,
Por exemplo:
Definimos os atributos Nome e Data_Nascimento com a restrição NOT NULL porque todo aluno precisa, obrigatoriamente, ter um
nome e uma data de nascimento. Por outro lado, não é obrigatório que um aluno tenha um endereço de e-mail.
Através da cláusula DEFAULT, é possível especificar um valor padrão para um determinado atributo. Se um valor não for
especificado para esse atributo quando uma nova linha for inserida na tabela, automaticamente será colocado o valor padrão.
Como a maioria dos alunos de uma faculdade ainda não estão casados, podemos definir o atributo Casado como falso por padrão.
Por exemplo: imagine que um banco de dados de uma empresa armazena informações dos seus funcionários e o salário nunca pode
ser menor que o salário mínimo (atualmente de R$ 1045,00 reais). Ficaria assim:
Assim, sempre que tentarmos inserir um funcionário com salário menor que 1045.00, um erro será exibido e a inserção falhará.
Se um atributo não aceitar valores repetidos na tabela, deve-se especificar a restrição UNIQUE. Vamos ver um exemplo:
CREATE TABLE DISCIPLINA (
Código INT PRIMARY KEY,
Nome VARCHAR(50) NOT NULL UNIQUE
);
No caso de duas disciplinas não poderem ter o mesmo nome, definimos o atributo Nome como UNIQUE.
Para definir a chave primária de uma tabela, especificamos a restrição PRIMARY KEY. Por debaixo dos panos, é como se
ela incluísse as restrições UNIQUE e NOT NULL ao mesmo tempo. Isso porque uma chave primária não pode se repetir nem receber o
valor nulo.
Por outro lado, se a chave for composta, obrigatoriamente temos que fazer assim:
CREATE TABLE LIVRO (
CPF_AUTOR CHAR(11) NOT NULL,
TITULO VARCHAR(100) NOT NULL,
PRIMARY KEY (CPF_AUTOR, TITULO)
);
Para definir uma chave estrangeira de uma tabela, especificamos a restrição FOREIGN KEY. Ela irá indicar qual atributo e qual
Em ambos os casos, estamos dizendo que o CPF_DONO é uma chave estrangeira que aponta para o atributo CPF da tabela
PESSOA. Lembrando que uma tabela pode ter uma quantidade qualquer de chaves estrangeiras.
Por outro lado, se uma chave estrangeira for composta, então obrigatoriamente precisamos fazer da seguinte forma:
A chave primária da tabela LIVRO é composta pelo par (CPF_AUTOR, TITULO). Assim, a chave estrangeira da tabela VENDA_LIVRO será
Dentro do contexto da chave estrangeira, temos que ter alguns cuidados para garantir a integridade referencial. Imagine as
seguintes tabelas:
PESSOA
CPF Nome
09809485910 Joaquim Silva Campos
19490984911 Amanda Alves
CACHORRO
ID Nome CPF_DONO
1 Belinha 09809485910
O que acontecerá se excluirmos a PESSOA de CPF '09809485910'? Ou se atualizarmos o CPF dela para outro valor? Ela está sendo
referenciada pela tabela CACHORRO. Temos quatro opções de ações para nos protegermos nessa situação:
RESTRICT: rejeita a exclusão/atualização e é a opção padrão do banco de dados se outra não for especificada;
SET DEFAULT: permite a exclusão/atualização e coloca um valor definido previamente como padrão na chave estrangeira;
exclusão/atualização é propagada.
Essas ações são especificadas em conjunto com as cláusulas ON DELETE e ON UPDATE. A sintaxe é assim:
Se excluirmos uma pessoa que está sendo referenciada pela tabela CACHORRO, a linha da tabela cachorro que a referencia também
será excluída. Se atualizarmos a chave primária dessa linha referenciada, a chave estrangeira da tabela CACHORRO também é
atualizada.
O comando DROP TABLE é utilizado para remover completamente uma tabela do banco de dados. A sintaxe é:
O comando TRUNCATE elimina todas as linhas de uma tabela, mas não a exclui do banco. Tem uma performance melhor que o
comando DELETE (que veremos daqui a pouco). Internamente é como se executasse um DROP e, em seguida, recriasse a tabela. A
sintaxe é:
O comando INSERT é utilizado para inserir novas linhas em uma tabela. Devemos passar os campos na ordem em que estão na
Se quisermos inserir os atributos em uma ordem diferente de como eles aparecem na tabela, temos que especificar o nome dos
INSERT INTO ALUNO (CASADO, EMAIL, NOME, CPF)
VALUES (TRUE, joaquim@dominio.com', 'Joaquim', '12345678912');
Em ambas as opções, podemos omitir os atributos que podem receber nulo, ou seja, que não possuem a restrição NOT NULL.
Também é possível omitir atributos que foram especificados com a cláusula DEFAULT, pois o valor padrão será automaticamente
atribuído.
Sempre que realizamos uma operação de inserção, todas as restrições especificadas devem ser respeitadas. Vamos ver alguns
exemplos:
Se um atributo é chave primária, ele não pode receber nulo nem receber um valor que já existe na tabela;
Se um atributo é chave estrangeira, ele tem que referenciar um valor que de fato exista na tabela referenciada;
Se um atributo for definido como NOT NULL, ele não pode receber o valor nulo;
Se um atributo for definido como UNIQUE, ele não pode receber um valor que já exista na tabela.
O comando DELETE é utilizado para remover todas as linhas de uma tabela ou apenas linhas que satisfazem uma condição. No
entanto, a tabela continua no banco, mesmo que vazia (caso sejam excluídas todas as linhas).
DELETE FROM nome_tabela WHERE condição;
Onde condição é uma expressão que resulta em verdadeiro ou falso. Apenas as linhas em que essa expressão for verdadeira serão
excluídas.
Perceba que pode ser que o comando não exclua nenhuma linha, caso nenhuma linha satisfaça a condição; pode excluir só uma
linha, caso só uma linha satisfaça a condição; ou ainda podem ser excluídas múltiplas linhas, caso elas satisfaçam a condição.
UPDATE nome_tabela
SET atributo = novo_valor
WHERE condição;
A cláusula WHERE é opcional. Se não for especificada, será atualizado o valor do atributo para todas as linhas da tabela. Se for
especificada, só irá atualiza as colunas das linhas que satisfaçam a condição. Observe um exemplo:
UPDATE ALUNO
SET Nome = 'Joaquim Silva'
WHERE CPF = '09409894910';
Na cláusula SET, é possível definir mais de um atributo para ser atualizado ao mesmo tempo. Também é possível realizar operações
UPDATE produto
SET estoque = estoque - 20, valor = valor *1,2
WHERE codigo = 17;
O comando acima está subtraindo 20 da quantidade do estoque e reajustando o valor em 20% do produto de código 17.
4.4 Consultando os dados
SELECT atributos
FROM tabelas
WHERE condição;
A cláusula WHERE é opcional. A condição é uma expressão que utiliza os atributos da tabela para verificar se satisfaz algum
requisito. As operações com valores incluem = (igual), > (maior que) , >= (maior ou igual), < (menor que), <= (menor ou igual) e < >
(diferente de).
FUNCIONARIO
ID NOME SALARIO Data_Nascimento
1 José Ricardo 3000.00 22/10/1958
2 Maria Cecília 6000.00 02/04/1975
3 Antônio Costa 4000.00 15/10/1994
4 Paulo Ortka 3500.00 07/07/1977
5 Magali Machado 5000.00 17/09/1981
Imagine que queremos retornar os nomes apenas dos funcionários que ganham mais de 5000.00. Para isso, fazemos a seguinte
consulta:
SELECT NOME
FROM FUNCIONARIO
WHERE SALARIO > 5000.00;
NOME
Maria Cecília
Também é possível utilizar os operadores lógicos AND, OR e NOT dentro da condição especificada na cláusula WHERE. Observe:
SELECT *
FROM FUNCIONARIO
WHERE SALARIO > 4000.00
AND DATA_NASCIMENTO > 01/01/1980;
O comando acima irá retornar todos os atributos da tabela funcionário, apenas dos funcionários que o ganham mais que R$ 4000.00
NOME
Magali Machado
Já vimos que as chaves estrangeiras são a forma de representar os relacionamentos entre tabelas no modelo relacional. Quando
temos duas ou mais tabelas que se relacionam e quisermos obter informações do relacionamento, devemos fazer uma junção
Autor
CPF Nome
98498401911 Antônio Mesquita
75893810334 Ricardo Jacobs
Livro
Título CPF_Autor Valor
Devaneios de um artista 98498401911 110.00
Amor é a cura 98498401911 70.00
Solidão infeliz 98498401911 50.00
Investimentos em renda fixa 75893810334 120.00
Bolsa de valores 75893810334 15.00
Se quisermos listar o nome do autor e seu respectivo livro, apenas dos livros que custam menos que 100 reais, podemos executar a
seguinte consulta:
Nome Título
Antônio Mesquita Amor é a cura
Antônio Mesquita Solidão infeliz
Ricardo Jacobs Bolsa de valores
É possível que dois atributos tenham o mesmo nome, contanto que estejam em relação diferentes. Nesse caso, podemos diferenciá-
Imagine que temos as seguintes tabelas:
Onde DEPTO é chave estrangeira que aponta para o atributo código da tabela DEPARTAMENTO.
Se quisermos retornar o nome dos funcionários e o nome do departamento onde trabalha, fazemos assim:
Aniversariante
Paulo Ortka
4.4.3 Operadores
4.4.3.1 DISTINCT
O operador DISTINCT é utilizado logo após a cláusula SELECT e serve para retornar apenas os valores distintos, ou seja, sem
repetições.
Exemplo: imagine que temos uma tabela chamada CACHORRO que armazena o nome de vários cães. Não existe a restrição UNIQUE
para esse atributo, de forma que dois cães podem ter o mesmo nome. Se quisermos retornar apenas os nomes distintos, fazemos:
4.4.3.2 BETWEEN
SELECT NOME
FROM PESSOA
WHERE IDADE BETWEEN 20 AND 60;
O operador BETWEEN inclui os extremos. Ou seja, os nomes das pessoas com idade entre 20 (inclusive) e 60 (inclusive) serão
retornados.
4.4.3.3 LIKE
O operador LIKE realiza casamento de padrão em uma cadeia de caracteres, ou seja, verifica se ela segue um determinado
Porcentagem (%): representa qualquer cadeia de caracteres, incluindo a cadeia vazia. Ou seja, pode existir zero, um ou vários
Vamos ver um exemplo: se quisermos retornar o nome de todas as pessoas que começam com a letra A, podemos fazer:
SELECT NOME
FROM PESSOA
WHERE NOME LIKE 'A%';
Se quisermos retornar o nome de todas as pessoas que possuem a letra B no segundo caractere do nome, fazemos:
SELECT NOME
FROM PESSOA
WHERE NOME LIKE '_b%';
4.4.3.4 IS NULL
SELECT NOME
FROM FUNCIONARIO
WHERE EMAIL IS NULL;
A consulta irá retornar o nome de todos os funcionários que não possuem e-mail cadastrado.
Se quisermos retornar os que não são NULL, utilizamos o operador IS NOT NULL.
4.4.3.5 IN
SELECT CODIGO
FROM PRODUTO
WHERE CATEGORIA IN ('Higiene', 'Comida');
A consulta irá retornar o código de todos os produtos que pertencem à categoria de higiene ou comida. Seria a mesma coisa que
fazer:
SELECT CODIGO
FROM PRODUTO
WHERE CATEGORIA = 'Higiene'
OR CATEGORIA = 'Comida';
4.4.3.6 Funções de agregação
As funções de agregação são funções que recebem várias linhas e retornam um único valor. São elas:
Vamos ver um exemplo. Se quisermos retornar a quantidade de pessoas que recebem um salário maior que 5.000,00, fazemos:
SELECT COUNT(nome)
FROM FUNCIONARIOS
WHERE SALARIO > 5000.00;
Para ordenar os resultados de uma consulta, utilizamos o comando ORDER BY. Ele é colocado após a cláusula WHERE. A sintaxe é:
SELECT lista_atributos
FROM tabela
WHERE condição
ORDER BY atributo;
A palavra chave ASC é opcional. Se colocarmos ela ou apenas fizermos "(...) ORDER BY atributo", os resultados serão ordenados em
ordem alfabética crescente.
Por outro lado, se quisermos retornar os resultados em ordem alfabética decrescente, temos obrigatoriamente que colocar DESC.
O ORDER BY também funciona com atributos numéricos e datas. Funciona com todos os tipos que puderem ser comparados.
Resumo do capítulo
1. Introdução
especificamos qual o resultado deve ser retornado, e não como chegar nele. É a linguagem de consulta padrão nos SGBDs
relacionais.
2. CREATE TABLE
Para criar uma tabela, utilizamos o comando CREATE TABLE. A sintaxe é:
2.1 Restrições
NOT NULL
Especifica que um atributo não pode receber nulo e deve obrigatoriamente ser informado.
DEFAULT
Especifica um valor padrão para o atributo caso ele não seja informado na hora da inserção.
UNIQUE
PRIMARY KEY
Especifica que um atributo é chave primária. Um atributo com essa restrição não pode ter valores repetidos nem receber o valor nulo.
FOREIGN KEY
Especifica que um atributo é chave estrangeira, indicando o atributo e a tabela que referencia.
O comando DROP TABLE é utilizado para remover completamente uma tabela do banco. A sintaxe é:
O comando TRUNCATE TABLE elimina todas as linhas, mas a mantém a tabela no banco de dados. É como se executasse um DROP
4. INSERT
No caso acima, a lista de atributos tem que estar na mesma ordem especificada na tabela. Se quisermos passar os atributos fora de
5. DELETE
O comando DELETE é utilizado para remover linhas de uma tabela. A sintaxe para remover todas as linhas é:
6. UPDATE
UPDATE nome_tabela
SET atributo = novo_valor
WHERE condição;
7. Consultas básicas
SELECT atributos
FROM tabelas
WHERE condição;
Se colocarmos um * logo após o SELECT, todos os atributos da tabela serão retornados. A cláusula WHERE é opcional.
7.1 Operadores
7.1.1 DISTINCT
É utilizado logo após a cláusula SELECT e serve para retornar apenas os valores distintos, ou seja, sem repetições.
7.1.2 BETWEEN
SELECT atributos
FROM tabela
WHERE atributo_numerico BETWEEN 20 AND 60;
O operador BETWEEN inclui os extremos. Também pode ser utilizado em datas.
7.1.3 LIKE
O operador LIKE realiza casamento de padrão em uma cadeia de caracteres. Dois caracteres curingas auxiliam o uso do LIKE:
Porcentagem (%): representa qualquer cadeia de caracteres, incluindo a cadeia vazia. Ou seja, pode existir zero, um ou vários
Exemplo de sintaxe:
SELECT NOME
FROM PESSOA
WHERE NOME LIKE 'A%';
7.1.4 IS NULL
SELECT atributos
FROM tabela
WHERE atributo IS NULL;
7.1.5 IN
SELECT atributos
FROM tabela
WHERE atributo IN (valor1,, valor2, valor3, ...);
São funções que recebem várias linhas e retornam um único valor. São elas:
7.2 ORDER BY
É colocada após a cláusula WHERE e serve para ordenar os resultados de uma consulta. Observe a sintaxe:
SELECT lista_atributos
FROM tabela
WHERE condição
ORDER BY atributo;
Para retornar em ordem alfabética crescente, basta colocar ASC ou omiti-lo (como no exemplo acima).