0% acharam este documento útil (0 voto)
24 visualizações94 páginas

Curso SQL

Enviado por

degocagil1993
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
24 visualizações94 páginas

Curso SQL

Enviado por

degocagil1993
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 94

Curso de SQL

Uma abordagem com MySQL

Prof. José Augusto Cintra

htttp://www.josecintra.com/blog

Revisão 2 - Julho/2020 – Quarto mês da quarentena


Apresentação
O objetivo deste curso é fornecer conceitos
básicos sobre a SQL, linguagem amplamente
utilizada para manipulação de Bancos de
Dados Relacionais.
Os exemplos aqui apresentados foram testados
no SGBD MySQL, mas são compatíveis com a
maioria dos bancos de dados.
Para melhor entendimento do conteúdo,
subentende-se que o leitor possua
conhecimentos prévios sobre Modelagem de
Bancos de Dados e Teoria Relacional. Caso
contrário, sugiro a leitura deste material.
2
Introdução

Vamos iniciar com uma breve introdução sobre o histórico e


características da linguagem. Apresentaremos também o modelo
de banco de dados a ser utilizado durante todo o curso.
Histórico
SQL (Structured Query Language) ou Linguagem
de Consulta Estruturada é uma linguagem para
definição, acesso, manipulação e controle de Bases
de Dados Relacionais.

Baseada na Álgebra Relacional, foi desenvolvida originalmente


no início dos anos 70 nos laboratórios da IBM, dentro do projeto
System R, que tinha por objetivo demonstrar a viabilidade da
implementação do modelo relacional proposto por E. F. Codd.
A linguagem se tornou um grande padrão de banco de dados,
devido a sua eficácia, simplicidade e facilidade de uso.

4
Características da SQL
 Estilo declarativo;
 Sintaxe simples e bem definida;
 Pode ser utilizada interativamente ou embutida em linguagens de
programação;
 Não é uma linguagem completa como C, Java ou Delphi;
 Portável;
 Presente nos mais importantes SGBDs Relacionais. Diferentes
fornecedores apresentam versões com algumas particularidades;
 Apresenta várias padrões evolutivos: SQL86, SQL89(SQL1), SQL92
(SQL2), SQL99(SQL3). A última versão definida pela ANSI/ISO traz
características como: Stored Procedures, Triggers, Suporte à
Programação OO, XML, entre outras.
5
Divisões da SQL
A SQL é dividida em grupos de comandos, de acordo com a sua natureza:
 DDL → Data Definition Language (Linguagem de Definição de Dados)
Reúne os comandos de criação dos objetos de Bancos;
 DML → Data Manipulation Language (Linguagem de manipulação de
dados) Comandos utilizados para realizar inclusões, alterações e
exclusões dos dados;
 DQL → Data Query Language (Linguagem de Consulta de Dados)
Agrupa os comandos que permitem ao usuário especificar uma consulta
 DCL → Data Control Language (Linguagem de Controle de Dados).
Comandos de controle de acesso que atribuem permissões aos usuários.
 DTL → Data Transaction Language (Linguagem de Transação de
Dados). Controla uma sequência de comandos e a integridade dos dados
resultantes.
6
Divisões da SQL

Fonte: javatpoint.com

Obs: Esta divisão é apenas uma convenção. Alguns autores descartam a


DQL e colocam o comando SELECT como pertencendo à DML.
Em caso de concursos ou provas, verifique na bibliografia da banca, qual
a convenção utilizada. 7
Modelo de Dados: Cadastro de Funcionários
Esse é o diagrama do banco de dados que
vamos criar e que usaremos em todos os
exemplos do curso.
Detalhamento nas próximas páginas...

8
Modelo de Dados: Cadastro de Funcionários
O diagrama de dados apresentado na página anterior tem finalidade
puramente didática. Não nos preocupamos com a eficiência ou correção
do modelo e sim com as possibilidades de aprendizado da SQL. Representa
uma parte do cadastro de funcionários de uma empresa fictícia:
 Um funcionário pode trabalhar em um único departamento. Mas não é
obrigatório, pode ficar temporariamente sem departamento.
 Um departamento pode ter vários funcionários, mas podem haver
departamentos sem funcionários.
 Um funcionário pode ser alocado em vários projetos e um projeto pode
conter vários funcionários. No entanto, podem existir projetos sem
funcionários alocados e também funcionários sem projetos.

9
Modelo de Dados: Cadastro de Funcionários
 A tabela ‘departamento’ armazena os nomes dos departamentos da
empresa que são identificados por uma chave numérica sequencial.
 A tabela ‘projeto’ armazena os nomes dos projetos da empresa que são
identificados por uma sigla alfabética de três letras. O campo ‘interno’ é
uma flag booleana que indica se o projeto é interno ou não.
 A tabela ‘funcionario’ armazena os dados dos funcionários que são
identificados por uma chave numérica sequencial. Possui um única
chave estrangeira ‘depto_id’ que aponta para a tabela de departamentos,
indicando qual departamento o funcionário trabalha.
 A tabela ‘alocacao’ faz a associação (alocação) entre projetos e
funcionários. Dessa forma possui duas chaves estrangeiras que apontam
para as tabelas de funcionários e projetos. Armazena também as datas em
que o funcionário iniciou e saiu do projeto. Cada alocação é identificada
por uma chave numérica sequencial. 10
DDL

A DDL reúne os comandos de definição do banco de dados e de


seus objetos, tais como criação de tabelas, índices, triggers, etc.
Neste curso cuidaremos da criação de tabelas. A criação dos
outros tipos de objetos, veremos nos outros cursos.
Criação do Banco de Dados
O primeiro passo para podermos testar os comandos SQL é a criação do
Banco de Dados. Fazemos isso através do comando CREATE.

Sintaxe:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS]
nome_banco [opções]
Exemplo:
CREATE DATABASE cadastro_funcionarios

Obs:
1. DATABASE e SCHEMA são sinônimos
2. Como opção, podem ser selecionados o CHARSET e COLLATION.
Mais detalhes na outra apostila aqui.
3. IF NOT EXISTS só criará o banco se ele não existir 12
Constraints

Na criação das tabelas, precisaremos definir os tipos de dados e


restrições (CONSTRAINTS) para os campos e tabelas.
As constraints são regras, validações impostas aos elementos
para promover a integridade dos dados. Essas restrições podem
ser definidas a nível de campo ou de tabela. Qualquer tentativa
de violação dessas regras resultará em erro e a operação não será
concretizada. 13
Constraints
 PRIMARY KEY (PK ou Chave Primária) → Especifica qual coluna
ou conjunto de colunas será a chave primária da tabela (Campo que
identifica de forma única um registro na tabela).
 FOREIGN KEY (FK ou Chave Estrangeira) → Determina que uma
coluna ou conjunto de colunas é uma chave estrangeira e que, portanto,
se relaciona a uma PK de outra tabela.
 UNIQUE → Determina que o valor de um campo não poderá se repetir
dentro da tabela. Será criado um índice para esse campo. Veja mais sobre
índices na outra apostila aqui.
 CHECK → Especifica uma condição que a coluna precisa atender para
poder salvar o registro (a partir da versão 8 do MySQL);
 NOT NULL → Determina que a coluna tem preenchimento obrigatório;
 DEFAULT → Especifica um valor padrão para gravar no campo, caso
este não seja informado no comando de inserção. 14
Considerações sobre NULL e DEFAULT
O valor NULL (nulo) é especial em banco de dados e, muitas vezes difícil
de ser tratado. Ele será gravado em um campo, quando não for informado
nenhum valor para o mesmo durante a inserção (Comando INSERT).
Já, a restrição DEFAULT permite que seja definido um valor padrão para o
campo que será usado para evitar a gravação do NULL.

Dessa forma, quando não informamos um valor para o campo, na inserção,


o Banco de Dados, verificará o seguinte:
1. Caso exista um valor DEFAULT, este será gravado no campo;
2. Caso não exista o DEFAULT e o campo for NOT NULL, ocorrerá um
erro. Caso contrário será gravado o valor NULL no campo.

15
A chave primária (Primary Key)
Quando definimos uma chave primária, as seguintes restrições serão
impostas:
1. A tabela só pode possuir uma chave primária;
2. O campos da chave não podem conter NULL, ou seja, são obrigatórios;
3. O valor da chave será único em toda tabela, ou seja, não pode se
repetir;
4. Será criado, por padrão, um índice PRIMARY. Veja mais sobre índices
na outra apostila aqui.
5. Uma chave primária pode ser composta, ou seja, formada por mais de
um campo. Dessa forma, as regras acima valem para a combinação dos
dois campos.

Na prática, a restrição PRIMARY KEY é uma combinação de NOT


NULL e UNIQUE. 16
Chave estrangeira e Integridade Referencial
Em um banco de dados relacional, quando um registro de uma tabela
aponta para outro em outra tabela, é necessário estabelecer regras para que
o registro "pai" não possa ser alterado ou excluído se ele tiver "filhos".
Exemplo: Na tabela departamento, não podemos excluir um
departamento se algum funcionário estiver cadastrado (trabalhando) nele.

Os tipos mais comuns de restrições de integridade são:


CASCADE → Ao se remover um registro da tabela referenciada pela
chave estrangeira, os registros relacionados àquele removido serão
eliminados em todas as tabelas relacionadas.
RESTRICT → Não permite a remoção de registros que possuam
relacionamentos em outras tabelas. (Comportamento padrão)
DEFAULT → Atribuem esses valores para as chaves estrangeiras cujos
registros relacionados foram excluídos. 17
Tipos de Dados
O tipo de dado de uma coluna define uma faixa de valores válidos
(domínio) que podem ser armazenados nessa coluna. Define também as
operações passíveis de serem realizadas com esses valores.
O tipo de dados não é considerado uma constraint, mas possui a mesma
função, pois estabelecemos uma restrição aos valores que serão aceitos e,
caso essa regra seja violada, será emitida uma mensagem de erro.
Com certeza é mais uma forma de buscarmos garantir a integridade dos
dados.

Podemos dividir os tipos de dados do MySQL em 3 categorias:


 String (Texto) → Conjunto de valores alfanuméricos (Letras, números e
caracteres especiais)
 Numérico → Números inteiros e decimais de diversas precisões
 Data → Data e Horários que podem ser manipulados em vários formatos18
Tipos de Dados Numéricos
 INT, INTEGER → Inteiros regulares
 BIGINT, SMALLINT e TINYINT → Inteiros grandes, pequenos e
muito pequenos
 FLOAT/DOUBLE → Números de ponto flutuante de precisão simples
ou dupla
 DECIMAL/NUMERIC → Números de ponto fixo que possuem melhor
precisão. Podem ser usados para valores monetários, por exemplo.

Podemos definir um tamanho para cada campo. Caso não o façamos, o


sistema assumirá o tamanho padrão.
Exemplos:
INT(5) → Define um campo inteiro com 5 dígitos
DECIMAL(8,2) → Define um número com 6 dígitos inteiros e 2 decimais
19
Variações dos Tipos Numéricos
Para os campos numéricos, podemos ainda definir as seguintes
propriedades:

UNSIGNED → Determina que o campo não vai aceitar valores negativos.


Útil para aumentar a faixa de valores válidos de números positivos.
AUTO_INCREMENT → O valor do campo será gerado automaticamente
de forma sequencial (1,2,3,...). Ou seja, na inclusão, o valor desse campo
não precisa ser informado, pois será atribuído o próximo da sequência.
Caso seja informado, a sequência continuará a partir desse número.
ZERO_FILL → Campos numéricos serão preenchidos com zeros à
esquerda

20
Tipos de Dados Texto
CHAR → Texto de comprimento fixo
VARCHAR → Texto de comprimento variável
TEXT/BLOB → Textos Grandes/Binários

VARCHAR é preferível em relação ao CHAR, pois ocupa menos espaço.


Exemplo: Seja um campo NOME definido como VARCHAR(100). Ao
armazenar o valor ‘Zé’ nesse campo, ele vai ocupar por volta de 2 bytes.
Caso o tipo do campo fosse CHAR, ocuparia por volta de 100 bytes.
No entanto, o tipo CHAR é mais rápido nas consultas.

Existem ainda os tipos NCHAR e NVARCHAR que são semelhantes, mas


aceitam valores UNICODE.
21
Tipos de Dados para Datas
DATE → Datas no padrão YYYY-MM-DD
DATETIME → Data e horário no padrão YYYY-MM-DD HH:MM:SS
TIME → Horário no padrão HH:MM:SS
YEAR → Um ano de 4 dígitos na faixa de 1901 até 2155.
TIMESTAMP → Padrão UTC. Armazena os segundos desde '1970-01-01
00:00:00' UTC

Os campos DATE e DATETIME podem armazenar datas com valores entre


01/Jan/1000 até 31/Dez/9999. Já, o TIMESTAMP até ‘2038-01-09
03:14:07’.
No MySQL estão disponíveis várias funções para manipulação e
formatação de datas que veremos no desenrolar do curso

22
Variações
GENERATED → São campos calculados a partir de outros valores e,
portanto, seus valores são gerados automaticamente no momento da
inserção/atualização do registro.
ENUM → Tipo de dados TEXTO que permite definir um conjunto de
dados discretos como domínio do campo.

Exemplo:
Podemos definir o campo SEXO como ENUM(’F’,‘M’)
O Banco de dados vai armazenar o valor 1 para masculino e 2 para
Feminino. Economiza espaço em disco, mas cuidado, pois o banco
ordena esses campos pelo seu índice.
23
Comando CREATE TABLE
Vejamos agora a sintaxe do comando CREATE TABLE usado para criar
uma nova tabela em um banco de dados:
CREATE TABLE [IF NOT EXISTS] nome_tabela
[( [nome_coluna tipo_dados [restrição_coluna]] |
[restrição_tabela],...)]
Onde: restrição_coluna e restrição_tabela são as restrições que
estudamos anteriormente.

A seguir vamos usar o comando CREATE para criar as tabelas do nosso


modelo de cadastro de funcionários e ver exemplos de cada um desses
conceitos. Antes de criarmos as tabelas, é necessário selecionar o banco de
dados com o comando USE:
USE cadastro_funcionarios
24
Criação da Tabela de Departamentos
CREATE TABLE departamento (
depto_id int unsigned NOT NULL AUTO_INCREMENT,
depto_nome varchar(45) NOT NULL,
PRIMARY KEY (depto_id)
)

Comentários:
 O campo depto_id (Inteiro positivo) foi definido como chave primária
e o seu valor será incrementado automaticamente a cada inclusão (auto
incremento). Será criado um índice PRIMARY para esse campo.
 O campo depto_nome não aceitará valores nulos e suportará até 45
caracteres de tamanho, mas o gerenciador armazenará somente o
tamanho ocupado.
25
Criação da Tabela de Projetos
CREATE TABLE projeto (
proj_sigla char(3) NOT NULL,
proj_nome varchar(45) NOT NULL,
proj_interno tinyint DEFAULT '0',
PRIMARY KEY (proj_sigla)
)
Comentários:
 O campo chave da tabela será um CHAR de 3 caracteres.
 O campo proj_interno possui um valor default de ‘0’, ou seja, caso não
for informado nenhum valor na inserção, será gravado o valor ‘0’ e não
NULL.

26
Criação da Tabela de Funcionários
CREATE TABLE funcionario (
func_id int unsigned NOT NULL AUTO_INCREMENT,
func_nome varchar(100) NOT NULL,
func_nasc date NOT NULL,
func_sexo enum('F','M'),
func_salario decimal(12,2) unsigned,
depto_id int unsigned,
PRIMARY KEY (func_id),
KEY func_depto_idx (depto_id),
CONSTRAINT func_depto_fk FOREIGN KEY (depto_id)
REFERENCES departamento (`depto_id`)
)
Comentários:
 O campo depto_id é uma chave estrangeira que referencia o campo depto_id da
tabela departamento e, por isso, foi criado um índice para esse campo (KEY) 27
Criação da Tabela de Alocações
CREATE TABLE alocacao (
aloca_id int unsigned NOT NULL AUTO_INCREMENT,
func_id int unsigned NOT NULL,
proj_sigla char(3) NOT NULL,
aloca_inicio datetime DEFAULT CURRENT_TIMESTAMP,
aloca_fim datetime,
PRIMARY KEY (aloca_id),
KEY aloca_proj_idx (proj_sigla),
KEY aloca_func_idx (func_id),
CONSTRAINT aloca_func_fk FOREIGN KEY (func_id)
REFERENCES funcionario (func_id),
CONSTRAINT aloca_proj_fk FOREIGN KEY (proj_sigla)
REFERENCES projeto (proj_sigla)
)
28
Comando ALTER TABLE
Usamos o comando ALTER TABLE para alterar a estrutura de uma tabela
existente. Podemos adicionar, alterar e excluir campos e restrições.

Sintaxe:

→ ALTER TABLE nome_tabela


ADD novas colunas | novas restrições
→ ALTER TABLE nome_tabela
CHANGE definição das colunas
→ ALTER TABLE nome_tabela
DROP coluna | restrição_coluna

29
Comando ALTER TABLE - Exemplos
 Adicionar um novo campo à tabela funcionario:
ALTER TABLE funcionario
ADD func_comissao DECIMAL(8,4) NOT NULL;

 Alterar o tamanho do campo descr_nome da tabela departamento:


ALTER TABLE departamento
CHANGE depto_nome VARCHAR(100);

 Excluir da tabela funcionario o campo de comissão recém criado:


ALTER TABLE funcionario
DROP func_comissao;

30
Constraint CHECK
Vamos agora adicionar uma restrição CHECK para os campos de datas da
tabela de alocações. A data de início no projeto não pode ser maior que a
data da saída do projeto:

ALTER TABLE alocacao ADD CONSTRAINT data_ck


CHECK (aloca_inicio < aloca_fim)

A constraint CHECK só está disponível na versão 8.0.16 do MySQL.

31
Comando DROP TABLE
O comando DROP é usado para excluir um objeto do banco de dados

Sintaxe:
DROP TABLE nome_tabela

Exemplo:
DROP TABLE departamento

Obs: Este comando, assim como os demais comandos DDL, possui regras
rígidas de segurança e integridade de dados. Assim só podem ser
executados em alguns casos. Não é possível, por exemplo excluir uma
tabela que possua relacionamentos.
32
DML

Como vimos, a DML engloba os comandos que permitem a manutenção


das informações armazenadas nas tabelas do banco de dados, ou seja,
permite realizar a inserção, alteração e exclusão de dados.
Para testar os comandos, vamos popular as tabelas criadas nos capítulos
anteriores e depois alterar e excluir alguns registros.
Comando INSERT
O comando INSERT insere registros nas tabelas, atribuindo conteúdo em
seus campos de acordo com o tipo e tamanho dos dados. Dessa forma, é
necessário conhecer a estrutura da tabela que se deseja manipular.
Nome da tabela que vai Nomes dos campos que
Sintaxe: receber o novo registro receberão os valores

INSERT INTO <tabela> [( <atributo>, ... )] VALUES


( expressão, ... );

Valores que serão inseridos. A expressão deve ser


compatível com o campo respectivo

34
INSERT - Exemplos
INSERT INTO departamento
(depto_id, depto_nome)
VALUES
(1, ‘COMPRAS’)
Observações:
 Neste exemplo, será inserido um novo registro na tabela departamento,
sendo que o campo depto_id receberá o valor 1 e o campo depto_nome,
o valor ‘COMPRAS’ respectivamente.
 O campo depto_nome é do tipo TEXTO. Por isso, o valor inserido
deve possuir o delimitador ASPAS SIMPLES. Isso não ocorre para o
campo depto_ID, que é numérico.
 Os campos e valores envolvidos devem ser compatíveis quanto ao tipo e
tamanho dos dados. Caso contrário, ocorrerá um erro.
35
INSERT - Exemplos
INSERT INTO departamento
(depto_nome, depto_id)
VALUES
(‘COMPRAS’, 1)

Observações:

 Este exemplo é idêntico ao anterior. A ordem dos campos foi alterada,


mas a correspondência continua a mesma.

36
INSERT - Exemplos
INSERT INTO departamento
VALUES
(1,‘COMPRAS’)

Observações:
Este exemplo é idêntico ao anterior. Os nomes dos campos foram omitidos,
então é preciso certificar-se do seguinte:
 O Sistema fará a correspondência automática entre os valores e os
campos na ordem física. Dessa forma, os valores precisam ser
compatíveis.
 Todos os campos devem ser informados, exceto os não obrigatórios.
Nesse caso, utilize vírgulas adicionais

37
INSERT com AUTO INCREMENT
INSERT INTO departamento
(depto_nome)
VALUES
(‘COMPRAS’)
Observações:
 Este exemplo é idêntico ao anterior. Só que agora usamos o recurso do
AUTO_INCREMENT.
 O valor do campo depto_id (chave primária) não foi informado. Isso
causaria um erro por ser NOT NULL. No entanto, como esse campo foi
definido como “auto incrementável”, então será gravado o próximo valor
da sequência. Por exemplo, se o último valor do campo era 1, então será
gravado o valor 2 nesse campo.

38
INSERT - Exemplos
INSERT INTO funcionario
(func_id,func_nome,func_nasc,func_sexo,depto_id)
VALUES
(1,‘JOSÉ DA SILVA’,’2000-01-01’ ’M’,,1)
Observações:
 Foi utilizado o delimitador de aspas simples para inserir a data de
nascimento. Para campos do tipo DATE, cuidado com o formato
utilizado pelo BD.
 O valor do campo func_salario não foi informado. Nesse caso, será
gravado o valor NULL.
 Para o campo depto_id foi informado o valor 1 que corresponde ao
departamento ‘COMPRAS’ na tabela departamento . O sistema sempre
fará a checagem da tabela relacionada, resultando em erro, caso o valor
informado não exista. 39
Comando UPDATE
O comando UPDATE altera os dados dos registros nas tabelas, atribuindo
o novo conteúdo em seus campos de acordo com o tipo e tamanho dos
dados. Dessa forma, é necessário conhecer a estrutura da tabela que se
deseja manipular.
Sintaxe: Nome da tabela cujos Nomes dos campos que vão
registros vão ser ser alterados
alterados

UPDATE <tabela> SET <Atributo> = <expressão>, ...


[ WHERE <Condição> ]
Determina quais registros
receberão as alterações, de Novos valores dos campos
acordo com a condição lógica
(filtro) 40
UPDATE - Exemplos
UPDATE funcionário
SET func_salario = 5000.50
Este comando irá atualizar o salário de TODOS os funcionários para R$
5000,50

UPDATE funcionário
SET func_salario = func_salario * 1.10
Este comando irá atualizar o salário de TODOS os funcionários
reajustando-os em 10%.

Obs: Como não existe um filtro (WHERE) especificado a atualização será


feita em todos os registros sem distinção.

41
UPDATE - Exemplos
UPDATE funcionario
SET func_salario = func_salario * 1.10
WHERE depto_id = 1
Este comando irá atualizar o salário de todos os funcionários do
departamento cujo código é igual a 1, reajustando-os em 10%.

UPDATE funcionario
SET func_salario = 5000.50, depto_id = ‘M’
WHERE func_id = 1
Este comando vai atualizar o salário e o departamento ao mesmo tempo.
Vai fazer isso somente para um funcionário, pois func_id é chave primária.

42
Comando DELETE
O comando DELETE é simples e direto. Sua função é excluir registros da
tabela de acordo com uma condição especificada.

Sintaxe:

DELETE FROM <tabela> [WHERE <Condição>]

Tabela da qual Filtro (condição)


queremos excluir especificando quais registros
os registros vão ser excluídos

43
DELETE - Exemplos
→DELETE FROM projetos

→DELETE FROM projetos where proj_sigla = ‘XYZ’

Observações:
 O primeiro exemplo exclui incondicionalmente todos os registros da
tabela de projetos.
 O segundo exemplo excluir apenas o projeto de sigla = 1 (primary
key).
 O sistema irá verificar se existe algum funcionário relacionado ao projeto
na tabela alocacao, caso exista, ocorrerá um erro, a menos que o
relacionamento tenha sido feito com a opção CASCADE. Isso vale
também para o comando UPDATE.
44
DQL

A DQL engloba os comandos que permitem a realização de consultas à


base de Dados. Ou seja, o SELECT!
Com o comando SELECT é possível pesquisar dados em uma ou mais
tabelas de acordo com o critério de filtro definido. É o astro da SQL e o
mais complexo comando da linguagem, como veremos a seguir...
SELECT – Dados de Trabalho
Tabela funcionario Tabela departamento
func_id func_nome func_nasc func_sexo func_salario depto_id depto_id depto_nome
1 JOSÉ DA SILVA 2000-01-01 M 5000 1 1 COMPRAS
2 MARIA DA SILVA 1987-02-01 F 8000,5 1 2 VENDAS
3 JOÃO DA SILVA 1970-01-01 M 5500,5 2 3 CONTABILIDADE
4 ANTONIO ALCÂNTARA 2000-03-01 M 6500 2 4 INFORMÁTICA
5 MARIA DE SOUZA 1990-05-01 F 6500 NULL
6 LUIZ MOURA 1960-05-01 M 7500 4
7 JOANA OLIVEIRA 1975-02-01 F 9000,7 1

Tabela projeto Tabela alocação


proj_sigla proj_nome proj_interno aloca_id func_id proj_sigla aloca_inicio aloca_fim
123 Projeto 123 0 1 1 XYZ 2019-01-01 00:00:00
ABC Projeto ABC 0 2 1 123 2020-01-01 00:00:00
PQR Projeto PQR 1 3 2 XYZ 2019-01-01 00:00:00 2020-01-01 00:00:00
XYZ Projeto XYZ 0 4 3 PQR 2018-01-01 00:00:00
5 4 123 2019-01-01 00:00:00

Essas são as tabelas já preenchidas com os dados que vamos utilizar nos
exemplos com SELECT. Todos os nomes e valores são fictícios. Veja que a
funcionária “Maria de Souza” ainda não tem um departamento e o
departamento de “contabilidade” está sem funcionários. 46
Comando SELECT
Sintaxe:
SELECT [ ALL | DISTINCT ] <lista de campos>
FROM <lista de tabelas>
[ WHERE <condição> ]
[ GROUP BY <atributo>, ...
[ HAVING <condição> ] ]
ORDER BY <lista de atributos> [ ASC | DESC ], ...]
 A cláusula FROM indica em qual tabela, view ou query vai ser realizada
a consulta.
 A lista de atributos contém a relação de campos que vão ser
requisitados na consulta.
 A cláusula WHERE determina o filtro da pesquisa com os parâmetros e
critérios de busca.
Detalharemos essas e as demais opções a seguir...
47
SELECT – Lista de Campos
A lista de campos do comando SELECT indica quais colunas ou
expressões vão ser mostrados no resultado da consulta. Para exibir todos as
colunas, use o caractere *.
É possível mudar os nomes dos campos para exibição, atribuindo-lhes um
apelido (alias). Da mesma forma, podemos colocar um prefixo para o
campo, indicando sua tabela de origem:
[nome_da_tabela].nome_do_campo | expressão [AS]
[apelido_do_campo]

Como exemplo, o campo nome_func da tabela funcionario pode ser


indicado por uma das quatro formas, entre outras:
func_nome ♦ funcionario.func_nome
func_nome AS nome ♦ funcionario.func_nome AS nome
48
SELEC T – Lista de Campos
Os seguintes comandos são equivalentes e listam todos os campos da tabela
funcionario:
 SELECT
func_id,func_nome,func_nasc,func_sexo,func_salario,depto_id
FROM funcionário
 SELECT * FROM funcionario

Obs: Como não foi usada a cláusula WHERE, serão exibidos todos os
registros também:
func_id func_nome func_nasc func_sexo func_salario depto_id
1 JOSÉ DA SILVA 2000-01-01 M 5000.00 1
2 MARIA DA SILVA 1987-02-01 F 8000.50 1
3 JOÃO DA SILVA 1970-01-01 M 5500.50 2
4 ANTONIO ALCÂNTARA 2000-03-01 M 6500.00 2
5 MARIA DE SOUZA 1990-05-01 F 6500.00 NULL
6 LUIZ MOURA 1960-05-01 M 7500.00 4
7 JOANA OLIVEIRA 1975-02-01 F 9000.70 1
49
SELECT – Lista de Campos
Neste exemplo selecionamos 3 campos e um campo calculado da tabela
funcionario, usando aliases:
Apelidos
Prefixo (opcional nesse caso)
SELECT
funcionario.func_id AS Código,
func_nome Nome,
func_salario Salário,
(func_salario*1.10) AS ’Salário Reajustado’ FROM funcionario

Código Nome Salário Salário Reajustado


1 JOSE DA SILVA 5000.00 5500.00

2 MARIA DA SILVA 8000.50 8800.55

3 JOÃO DA SILVA 5500.50 6050.55


Campo 4 ANTONIO ALCÂNTARA 6500.00 7150.00
Calculado 5 MARIA DE SOUZA 6500.00 7150.00

6 LUIZ MOURA 7500.00 8250.00

7 JOANA OLIVEIRA 9000.70 9900.77


50
SELECT – Cláusula ORDER BY
Podemos ordenar os resultados de uma consulta através da cláusula
ORDER BY.
Sintaxe:
ORDER BY {<atributo>|expressão [ ASC | DESC]}

Observações
 atributo: Campo ou expressão que vai ser utilizado como critério para a
ordenação. Podemos usar mais de um campo.
 ASC: Ordenação ascendente (crescente)
 DESC: Ordenação descendente (decrescente)
 Caso o sentido da ordenação não seja informado, o padrão será ASC;
 A cláusula ORDER BY deve vir depois da cláusula WHERE, caso esta
exista.
51
SELECT – Cláusula ORDER BY
SELECT * FROM funcionario ORDER BY func_nome
Este exemplo irá listar os funcionários em ordem crescente de nome
(campo func_nome):

func_id func_nome func_nasc func_sexo func_salario depto_id


4 ANTONIO ALCÂNTARA 2000-03-01 M 6500.00 2
7 JOANA OLIVEIRA 1975-02-01 F 9000.70 1
3 JOÃO DA SILVA 1970-01-01 M 5500.50 2
1 JOSÉ DA SILVA 2000-01-01 M 5000.00 1
5 MARIA DE SOUZA 1990-05-01 F 6500.00 NULL
6 LUIZ MOURA 1960-05-01 M 7500.00 4
2 MARIA DA SILVA 1987-02-01 F 8000.50 1

52
SELECT – Cláusula ORDER BY
select * from funcionario order by depto_id ASC,
func_salario DESC

Este exemplo irá listar os funcionários em ordem crescente de


departamento (campo depto_id) e, dentro de departamento, em ordem
decrescente de salário (campo func_salario):

func_id func_nome func_nasc func_sexo func_salario depto_id


5 MARIA DE SOUZA 1990-05-01 F 6500.00 NULL
7 JOANA OLIVEIRA 1975-02-01 F 9000.70 1
2 MARIA DA SILVA 1987-02-01 F 8000.50 1
1 JOSÉ DA SILVA 2000-01-01 M 5000.00 1
3 JOÃO DA SILVA 1970-01-01 M 6500.00 2
4 ANTONIO ALCÂNTARA 2000-03-01 M 5500.50 2
6 LUIZ MOURA 1960-05-01 M 7500.00 4
53
SELECT – Cláusula WHERE
A cláusula WHERE permite filtar os registros a serem exibidos de acordo
com uma condição do pesquisa que é basicamente uma coleção de
predicados que podem ser combinados através dos operadores booleanos
AND, OR, NOT.
Um predicado pode ser:

• Uma comparação com os operadores condicionais (=,<,>,<=,>=,<>)


• Um predicado de BETWEEN para pesquisa em faixas de valores
• Um predicado IN para buscar um valor em um conjunto
• Um predicado de LIKE para busca de trechos em campos texto
• Um teste de valor nulo

Vejamos cada um deles… 54


SELECT – Comparações
Fumncionários que trabalham no departamento de número 2:
SELECT * FROM funcionario WHERE depto_id = 2

func_id func_nome func_nasc func_sexo func_salario depto_id


3 JOÃO DA SILVA 1970-01-01 M 5500.50 2
4 ANTONIO ALCÂNTARA 2000-03-01 M 6500.00 2

Funcionários que NÃO trabalham no departamento de número 2:


SELECT * FROM funcionario WHERE depto_id <> 2

func_id func_nome func_nasc func_sexo func_salario depto_id


1 JOSÉ DA SILVA 2000-01-01 M 5000.00 1
2 MARIA DA SILVA 1987-02-01 F 8000.50 1
7 JOANA OLIVEIRA 1975-02-01 F 9000.70 1
6 LUIZ MOURA 1960-05-01 M 7500.00 4

Veja que a consulta não trouxe códigos de departamentos nulos. Veremos


55
mais à frente como tratar campos nulos.
SELECT – Comparações
Funcionários que recebem salário maior que R$ 7.000,00:
SELECT * FROM funcionario WHERE func_salario > 7000

func_id func_nome func_nasc func_sexo func_salario depto_id


2 MARIA DA SILVA 1987-02-01 F 8000,5 1
6 LUIZ MOURA 1960-05-01 M 7500 4
7 JOANA OLIVEIRA 1975-02-01 F 9000,7 1

Funcionários que trabalham no departamento de número 1 e recebem


salário maior que R$ 7.000,00:
SELECT * FROM funcionario WHERE depto_id = 1 AND
func_salario > 7000
func_id func_nome func_nasc func_sexo func_salario depto_id
2 MARIA DA SILVA 1987-02-01 F 8000,5 1
7 JOANA OLIVEIRA 1975-02-01 F 9000,7 1
56
SELECT – Comparações
Funcionários Homens que recebem salários maiores que R$ 6.000,00 e
Mulheres que ganham salários menores que R$ 7.000,00 :
SELECT * FROM funcionario WHERE
(func_sexo = ‘M’ AND func_salario > 6000) OR
(func_sexo = ‘F’ AND func_salario < 7000)

func_id func_nome func_nasc func_sexo func_salario depto_id

4ANTONIO ALCÂNTARA 2000-03-01 M 6500 2

5MARIA DE SOUZA 1990-05-01 F 6500 NULL

6LUIZ MOURA 1960-05-01 M 7500 4

57
SELECT – Cláusula BETWEEN
A cláusula BETWEEN é usada para facilitar a filtragem de faixas de
valores.
Exemplo: Listar os funcionários que recebem salários entre R$ 6.000,00 e
R$ 8.000,00 (inclusive)

Uma solução usando operadores condicionais poderia ser:


SELECT * FROM funcionario
WHERE func_salario >= 6000 AND
func_salario <= 8000

Usando a cláusula BETWEEN fica:


SELECT * FROM funcionario
WHERE func_salario BETWEEN 6000 AND 8000
58
SELECT – Cláusula IN
A cláusula IN é usada para facilitar a realização de comparações múltiplas

Exemplo: Listar os funcionários que trabalham nos departamentos 1, 3 e 5


Uma solução usando operadores condicionais poderia ser:
SELECT * FROM funcionario WHERE
depto_id = 1 OR depto_id = 3 OR depto_id = 5
Usando a cláusula IN fica:
SELECT * FROM funcionario
WHERE depto_id IN (1,3,5)

Obs: Caso os valores sejam do tipo texto, colocá-los entre aspas simples.
Mais para frente, falaremos sobre IN em subconsultas.
59
SELECT – LIKE
O operador LIKE é usada para localizar trechos de textos em campos
alfanuméricos de acordo com padrões. Para isso são usados os caracteres
coringa (wildcards) que são os seguintes:
WildCard Função
% Qualquer quantidade de caracteres
_ Exatamente um caractere

Qualquer nome que termine em ‘SILVA’:


SELECT * FROM funcionario WHERE func_nome LIKE ‘%SILVA’
Qualquer nome que comece com ‘MARIA’:
SELECT * FROM funcionario WHERE func_nome LIKE ‘MARIA%’
Qualquer nome que termine em ‘S’ seguido de 3 letras e depois a letra ‘A’:
SELECT * FROM funcionario WHERE func_nome LIKE '%S___A’
Nesse último exemplo vai trazer os sobrenomes SILVA e SOUZA. 60
SELECT – Valores nulos (NULL)
Os valores nulos são um caso à parte e são muito difíceis de serem
trabalhados pelos seguintes motivos:
• Um valor nulo nunca é igual à outro;
• Operações com nulos sempre retornam nulos, sejam eles numéricos ou
não.
Desta forma, por exemplo:
10 * NULL = NULL;
10 + NULL = NULL;
Para trabalhar com valores nulos temos, entre outros, os seguintes
operadores e funções:
IS NULL / IS NOT NULL → Comparam valores com NULL
COALESCE() → Função que substitui um valor nulo por outro não nulo.
Existe também a função IFNULL que produz o mesmo resultado. 61
SELECT – Tratando Valores Nulos
Exemplo 1: Pesquisar os funcionários que não estão cadastrados em
nenhum departamento (cod_depto é nulo):
SELECT * FROM funcionario WHERE depto_id IS NULL

Exemplo 2: Pesquisar os funcionários que estão alocados em algum


departamento:
SELECT * FROM funcionario WHERE depto_id IS NOT NULL

Exemplo 3: Mostrar os salários acrescidos de 1000, mesmo para salários


nulos:
SELECT COALESCE(func_salario,0) + 1000 FROM funcionario
Obs: Neste ultimo caso, os salários nulos serão convertidos para 0
(ZERO) antes de serem somados. Caso contrário, o resultado da soma seria
NULL.
62
SELECT – Maiúsculas e Minúsculas
SQL não é sensível ao caso, portanto escrever SELECT ou select ou
SeLeCt é a mesma coisa. No entanto, o mesmo não vale para o conteúdo
dos campos que nem sempre é sensível ao caso. Isso depende do
CHARSET e COLLATION usados. Dessa forma, ‘ANTONIO’ pode ser
diferente de ‘antonio’.

Para fazer pesquisas não sensíveis ao caso, usamos as seguintes funções:


UPPER() → Converte as letras para maiúscula
LOWER() → Converte as letras para minúsculas
Exemplos: Os seguintes comando produzem o mesmo resultado:
• SELECT * FROM funcionario WHERE
UPPER(func_nome) = ‘JOSE DA SILVA’
• SELECT * FROM funcionario WHERE
LOWER(func_nome) = ‘jose da silva’
63
SELECT – Cláusula DISTINCT
A cláusula DISTINCT é usada para eliminar do resultado da consulta todas
as linhas duplicadas.
Exemplo: Como listar todos os números de departamentos que
possuem funcionários alocados?
Precisamos fazer um SELECT na tabela funcionario trazendo os
departamentos, pois assim garantimos que um funcionário está alocado no
departamento. Uma solução poderia ser o seguinte comando:
SELECT depto_id FROM funcionario
No entanto, esse comando trará vários departamentos repetidos. Para
resolver, usamos a cláusula DISTINCT da seguinte forma:
SELECT DISTINCT depto_id FROM funcionario
Obs: A cláusula DISTINCT deve vir logo após o comando SELECT e se
aplica a todas as colunas selecionadas.
64
SELECT – Cláusula LIMIT
A cláusula LIMIT é usada para limitar o número de registros retornados. É
útil para fazer relatórios paginados ou para testes em tabelas grandes, além
de outras finalidades.

Exemplo1: Busca os três primeiros funcionários:


select * from funcionario limit 3

Exemplo2: Busca os três primeiros funcionários a partir do segundo


registro:
select * from funcionario limit 2,3

65
SELECT – CASE
A expressão CASE é uma estrutura de controle que permite adicionar lógica
if-else a uma consulta SELECT. Ela permite escolher um valor entre um
conjunto de valores.
CASE value
WHEN value1 THEN result1
WHEN value2 THEN result2

[ELSE else_result]
END
Exemplo: Exibindo o sexo por extenso.
SELECT func_nome,
CASE func_sexo Obs:
WHEN 'F' THEN 'feminino’ É possível também usar expressões
ELSE 'Masculino’ lógicas para os valores
END AS Sexo
66
FROM funcionario
SELECT – Funções de Agregação
As funções de agregação permitem a execução de operações matemáticas e
estatísticas sobre um conjunto de dados, retornando um único valor
totalizador.
As principais funções de agregação em MySQL são:
MIN → Valor Mínimo
MAX → Valor Máximo
AVG → Média Aritmética
SUM → Soma
COUNT → Contagem

As funções de agregação recebem como parâmetro o nome do campo que


vai ser totalizado e, com algumas exceções, desconsideram na totalização os
valores NULL.
67
SELECT – Funções de Agregação – Exemplos
Contar o número total de registros da tabela de departamentos:
select count(depto_id) from departamento
Calcular a média de salários dos funcionários:
select avg(func_salario) from funcionário
Calcular a média de salários dos funcionários do departamento 1:
select avg(func_salario) from funcionario
where depto_id = 1
Calcular a soma de salários e o menor salário do departamento 1
select sum(func_salario), min(func_salario)
from funcionario where depto_id = 1
Use DISTINCT para ignorar valores duplicados na agregação:
select avg(DISTINCT func_salario) from funcionário
68
SELECT – Cláusula GROUP BY
Usamos a cláusula GROUP BY para agrupar registros em subgrupos
baseados em valores retornados por um campo ou expressão. É usado
frequentemente em conjunto com funções de agregação para produzir
subtotais.
Exemplo: Obter a média dos salários para cada departamento:
SELECT depto_id, AVG(func_salario) AS 'Média’
FROM funcionario GROUP BY depto_id

depto_id Média
NULL 6500
1 7333,733333
2 6000,25
4 7500

69
SELECT – Cláusula GROUP BY - Exemplos
Exemplo 1: Obter a média dos salários para cada departamento:
SELECT depto_id, AVG(func_salario) AS 'Média’
FROM funcionario GROUP BY depto_id
depto_id Média
NULL 6500
1 7333,733333
2 6000,25
4 7500
Exemplo 1: Obter a média dos salários por sexo e departamento:
SELECT depto_id, func_sexo, AVG(func_salario) AS 'Média’
FROM funcionario GROUP BY depto_id,func_sexo

depto_id func_sexo Média


1M 5000
1F 8500,6
2M 6000,25
NULLF 6500
4M 7500
70
SELECT – Cláusula GROUP BY & HAVING
Muitas vezes é necessário filtrar os dados dos agrupamentos retornados pelo
GROUP BY. Para isso, empregamos a cláusula HAVING que permite
especificar condições para inclusão dos grupos nas agregações. É
semelhante à cláusula WHERE, mas não se aplica aos registros e sim aos
agrupamentos do GROUP BY,
Exemplo: Somar os salários agrupados por departamento e sexo, mas
excluir as somas menores ou iguais a 5000,00:
SELECT depto_id, func_sexo, SUM(func_salario) AS 'Soma’
FROM funcionario GROUP BY depto_id,func_sexo
HAVING SUM(func_salario) > 5000
depto_id func_sexo Soma
1F 17001,2
2M 12000,5
NULLF 6500
4M 7500
71
SELECT – Subconsultas
Uma subconsulta, na prática, é uma instrução SELECT dentro de outra
instrução SQL.
Podemos embutir uma instrução SELECT em vários pontos de outra
instrução SELECT:
• Como uma nova coluna da consulta. O campo é um SELECT.
• Como filtro de uma consulta (cláusula WHERE).
• Como fonte de dados de outra consulta (cláusula FROM).

A seguir, vamos fazer alguns exemplos para demonstrar esse recurso.

72
SELECT – Subconsulta Como Campo
Exemplo: Trazer a quantidade de funcionários que trabalham em cada
departamento:
Essa subconsulta destacada em verde é um campo da consulta
SELECT principal e recebe um nome (alias) de ‘Qtde’.
Em sua cláusula WHERE, ela faz referência a um campo
d.depto_id, da consulta principal. Veja que os parênteses são importantes
d.depto_nome,
(SELECT COUNT(*) FROM funcionario AS f
WHERE f.depto_id = d.depto_id) AS ‘Qtde’
FROM
departamento AS d

depto_id depto_nome Qtde


1COMPRAS 3
2VENDAS 2
3CONTABILIDADE 0
4INFORMÁTICA 1
73
SELECT – Subconsulta Como Fonte de Dados
Exemplo: Usar a consulta do exemplo 1 (página anterior) para trazer os
departamentos que não possuem funcionários:

SELECT * FROM ( Essa subconsulta destacada em verde é agora usada na


SELECT cláusula FROM como se fosse uma tabela ou view.
d.depto_id, Seus campos podem ser referenciados normalmente na
consulta principal através do seu alias (tabela)
d.depto_nome,
(SELECT COUNT(*) FROM funcionario AS f
WHERE f.depto_id = d.depto_id) AS ‘Qtde’
FROM
departamento AS d
) AS tabela WHERE t.qtde = 0
depto_id depto_nome Qtde
3CONTABILIDADE 0
74
SELECT – Subconsulta Como Filtro
Exemplo: Trazer os códigos e nomes dos funcionários que já trabalharam
em pelo menos um projeto:

SELECT
Essa subconsulta destacada em verde é agora usada
f.func_id,f.func_nome na cláusula WHERE através do operador IN
FROM
funcionario f
WHERE
f.func_id IN (SELECT DISTINCT a.func_id FROM alocacao a)

func_id func_nome
1 JOSÉ DA SILVA
2 MARIA DA SILVA
3 JOÃO DA SILVA
4 ANTONIO ALCÂNTARA
75
SELECT – Junções de Tabelas

Os bancos de dados relacionais como o MySQL armazenam as informações


em tabelas separadas mas relacionadas entre si através de campos comuns.
Esses campos comuns são as chaves primárias e estrangeiras que permitem
juntar as informações para produzir um resultado só. O comando SELECT
disponibiliza algumas cláusulas que permitem efetuar junções entre tabelas,
mesmo sem haver campos comuns.
Você vai ver nos exemplos que, quando trabalhamos com junções de
tabelas, é muito comum atribuirmos apelidos para as tabelas para evitar
conflitos entre nomes de campos iguais e também para simplificar a escrita
76
SELECT – Junções de Tabelas
 CROSS JOIN → Retorna a combinação de todos os registros das duas
tabelas sem nenhum critério. Na verdade, é um PRODUTO
CARTESIANO e não será abordado nesse curso.
 INNER JOIN → Retorna somente registros que possuem valores
correspondentes nas duas tabelas de acordo com o critério de junção.
 OUTER JOIN → Retorna registros das duas tabelas de acordo com o
seguinte:
 LEFT JOIN → Todos os Registros da tabela à esquerda e os registros
correspondentes da tabela direita
 RIGHT JOIN → Todos os Registros da tabela à direita e os registros
correspondentes da tabela esquerda
 FULL JOIN → Todos os registros, quando houver uma
correspondência, e os não correspondentes das tabelas esquerda e
direita. Obs: O MySQL não suporta FULL JOINS.
77
SELECT – Junções de Tabelas

Fonte: terminalroot.com.br 78
SELECT – Junções de Tabelas - Exemplos
Para exemplificar melhor essas formas de junção, veremos um estudo de
caso.

Vamos supor que o seu chefe imediato te pediu um relatório simples com
todos os códigos e nomes dos funcionários e os nomes de seus
respectivos departamentos.
Como o nome e o código do funcionários estão na tabela funcionario, mas
o nome do departamento está na tabela departamento, a primeira ideia que
você teve foi juntar as duas tabelas usando o campo comum depto_id,
através de um INNER JOIN.


79
SELECT – Junções de Tabelas – INNER JOIN
SELECT
f.func_id,f.func_nome,d.depto_nome
FROM
Destacado em verde, vemos a junção por
funcionario f igualdade do campo ‘depto_id’ presente
INNER JOIN nas duas tabelas.
Veja que o registro 5 não apareceu, pois
departamento d está com NULL nesse campo
ON
f.depto_id = d.depto_id
func_id func_nome depto_nome
1 JOSÉ DA SILVA COMPRAS
O seu chefe não gostou desse relatório!
2 MARIA DA SILVA COMPRAS Não apareceu a MARIA DE SOUZA.
7 JOANA OLIVEIRA COMPRAS A solução é refazer usando LEFT
3 JOÃO DA SILVA VENDAS
JOIN, que veremos a seguir →
4 ANTONIO ALCÂNTARA VENDAS
6 LUIZ MOURA INFORMÁTICA
80
SELECT – Junções de Tabelas – LEFT JOIN
SELECT
f.func_id,f.func_nome,d.depto_nome
FROM
Destacado em verde, vemos a junção por
funcionario f igualdade com LEFT JOIN.
LEFT JOIN Agora apareceu o registro cinco

departamento d
ON
f.depto_id = d.depto_id
func_id func_nome depto_nome O seu chefe AINDA não gostou desse
1 JOSÉ DA SILVA COMPRAS
2 MARIA DA SILVA COMPRAS
relatório:
3 JOÃO DA SILVA VENDAS Cadê o departamento de
4 ANTONIO ALCÂNTARA VENDAS contabilidade?
5 MARIA DE SOUZA NULL A solução é refazer usando RIGHT
6 LUIZ MOURA INFORMÁTICA
JOIN, que veremos a seguir → 81
7 JOANA OLIVEIRA COMPRAS
SELECT – Junções de Tabelas – RIGHT JOIN
SELECT
f.func_id,f.func_nome,d.depto_nome
FROM
Destacado em verde, vemos a junção por
funcionario f igualdade com RIGHT JOIN.
RIGHT JOIN Agora apareceu o departamento de
CONTABILIDADE, mas o registro 5
departamento d Desapareceu de novo
ON
f.depto_id = d.depto_id
func_id func_nome depto_nome É melhor nem levar esse relatório para
1 JOSÉ DA SILVA COMPRAS
2 MARIA DA SILVA COMPRAS
o seu chefe:
3 JOÃO DA SILVA VENDAS A contabilidade está ok, mas a MARIA
4 ANTONIO ALCÂNTARA VENDAS DE SOUZA desapareceu!
5 MARIA DE SOUZA NULL A solução é refazer usando UNION,
6 LUIZ MOURA INFORMÁTICA
que veremos a seguir → 82
7 JOANA OLIVEIRA COMPRAS
SELECT – Junções de Tabelas – FULL JOIN
Pois é, você ia finalizar o relatório usando FULL OUTER JOIN para
resolver o problema, mas eis que você descobre que o MYSQL não o
suporta.
A solução é fazer uma gambi com UNION.
A cláusula UNION combina duas ou mais declarações SELECT. O
resultado de cada SELECT deve possuir o mesmo número de colunas, e o
tipo de dado de cada coluna correspondente deve ser compatível. O nome
das colunas não precisam ser iguais.
Dessa forma, podemos combinar duas consultas, uma com LEFT JOIN e
outra com RIGHT JOIN para produzir o mesmo resultado de uma consulta
com FULL OUTER JOIN.
Obs: Por padrão, o operador UNION elimina resultados duplicados. Para
incluí-los, acrescente a palavra ALL.

→ 83
SELECT – Junções de Tabelas – UNION
SELECT func_id func_nome depto_nome
f.func_id,f.func_nome,d.depto_nome 1 JOSÉ DA SILVA COMPRAS
2 MARIA DA SILVA COMPRAS
FROM
3 JOÃO DA SILVA VENDAS
funcionario f
4 ANTONIO ALCÂNTARA VENDAS
LEFT JOIN 5 MARIA DE SOUZA NULL
departamento d 6 LUIZ MOURA INFORMÁTICA
ON 7 JOANA OLIVEIRA COMPRAS
f.depto_id = d.depto_id NULL NULL CONTABILIDADE

UNION
SELECT Pronto. Com o uso de UNION
f.func_id,f.func_nome,d.depto_nome Conseguimos o resultado
FROM esperado. O seu chefe te elogiou,
funcionario f mas pediu uma última alteração:
RIGHT JOIN Mudar o valor NULL para uma
departamento d coisa mais bonitinha
ON Ainda bem que aprendemos a
f.depto_id = d.depto_id função COALESCE. Vejamos a
versão final do relatório → 84
TIMESTAMPDIFF(DAY,'2022-02-01','2022-02-21')

SELECT – Funções com Datas


TIMESTAMPDIFF(DAY,'2022-02-01','2022-02-21')

Algumas funções do MYSQL que podemos usar para facilitar as consultas:

• CURDATE → Retorna da data corrente


• YEAR(), MONTH() e DAY() → Extraem o ano, o mês e o dia de uma data passada
como parâmetro
Ex: MONTH(‘2019-01-01’) # Retorna: 1

• DATEDIFF() → Retorna o número de dias entre duas datas


Ex: DATEDIFF(‘2020-06-25’, ‘2020-06-15’) # Retorna: 10

• TIMESTAMPDIFF() → Retorna a diferença entre duas datas em uma unidade


específica (anos, meses, segundos, etc.)
Ex: TIMESTAMPDIFF(DAY,'2022-02-01','2022-02-21’) # Retorna: 10

• DATE_FORMAT() → Formata uma data de acordo com os parâmetros


Ex: DATE_FORMAT("2020-06-15", "%d/%m/%Y") # Retorna:15/06/2020
85
Exercícios

A seguir alguns exercícios resolvidos com o comando SELECT ...


Exercícios Resolvidos
1) Listar o menor e o maior salário agrupados por departamento

SELECT
d.depto_nome AS Departamento,
MIN(f.func_salario) AS 'Menor Salário',
MAX(f.func_salario) AS 'Maior Salário'
FROM
funcionario f
INNER JOIN
departamento d ON f.depto_id = d.depto_id
GROUP BY
d.depto_nome
87
Exercícios Resolvidos
2) Listar Código, nome do funcionário, seu departamento e em quantos
projetos ele trabalhou

SELECT
f.func_id AS Código,
f.func_nome AS Nome,
IFNULL(d.depto_nome,'N/C') AS Departamento,
(SELECT count(a.aloca_id) from alocacao a where a.func_id = f.func_id)
AS Projetos
FROM
funcionario f
LEFT JOIN
departamento d ON f.depto_id = d.depto_id

88
Exercícios Resolvidos
3) Listar Código e nome dos funcionários que recebem salário maior do que
a média de salários da empresa:
SELECT
f.func_id AS Código,
f.func_nome AS Nome,
f.func_salario As Salário
FROM
funcionario f
WHERE
f.func_salario >=
(SELECT AVG(func_salario) FROM funcionario)

Veja que essa consulta não é muito “performática” se não existirem índices
para o campo de salário. O plano de execução do MySQL é inteligente, mas
o ideal, nesse caso, é criar um script onde a média dos salários é calculada
para uma variável e depois comparar os salários com essa variável.
Veremos sobre criação de scripts SQL em outro curso. 89
Exercícios Resolvidos
4) Listar nome, data de Nascimento e a idade dos funcionários que fazem
aniversário neste mês (mês atual)

SELECT
f.func_nome as Nome,
f.func_nasc AS Nascimento,
TIMESTAMPDIFF(YEAR,f.func_nasc,CURDATE()) AS Idade
FROM
funcionario f
WHERE
MONTH(curdate()) = (MONTH(f.func_nasc))

90
Exercícios Resolvidos
5) Listar a quantidades de projetos NÃO internos iniciados em cada ano

SELECT
YEAR(a.aloca_inicio) AS Ano,
count(p.proj_sigla) As 'Qtde.Projetos'
FROM
projeto p
INNER JOIN
alocacao a
ON
p.proj_sigla = a.proj_sigla
WHERE
NOT p.proj_interno
GROUP BY
YEAR(a.aloca_inicio)
91
Exercícios Resolvidos
6) Emitir uma listagem geral dos funcionários, seus departamentos e
projetos, incluindo os que não trabalharam em projetos e não estão em
nenhum departamento.
SELECT
f.func_id,
f.func_nome,
IFNULL(d.depto_nome,'N/C’),
IFNULL(p.proj_nome,'N/C')
FROM
funcionario f
LEFT JOIN
departamento d ON f.depto_id = d.depto_id
LEFT JOIN
alocacao a ON a.func_id = f.func_id
LEFT JOIN
projeto p ON p.proj_sigla = a.proj_sigla 92
FIM
Obrigado!

93
Referências
Links
 https://dev.mysql.com/doc/
 https://www.tutorialspoint.com/sql/index.htm
 https://www.w3schools.com/sql/
 http://www.bosontreinamentos.com.br/curso-completo-de-mysql/
 http://www.josecintra.com/blog

Livros
 Lynn Beighley - Use a Cabeça SQL – Alta Books
 C.J.Date - SQL e Teoria Relacional - Editora Novatec

94

Você também pode gostar