Curso SQL
Curso SQL
htttp://www.josecintra.com/blog
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
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
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
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.
20
Tipos de Dados Texto
CHAR → Texto de comprimento fixo
VARCHAR → Texto de comprimento variável
TEXT/BLOB → Textos Grandes/Binários
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.
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:
29
Comando ALTER TABLE - Exemplos
Adicionar um novo campo à tabela funcionario:
ALTER TABLE funcionario
ADD func_comissao DECIMAL(8,4) NOT NULL;
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:
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
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:
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 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%.
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:
43
DELETE - Exemplos
→DELETE FROM projetos
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
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]
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
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):
52
SELECT – Cláusula ORDER BY
select * from funcionario order by depto_id ASC,
func_salario DESC
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)
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
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
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
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
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
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
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