Curso de SQL Uma abordagem com MySQL · Apresentação O objetivo deste curso é fornecer conceitos...

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

Transcript of Curso de SQL Uma abordagem com MySQL · Apresentação O objetivo deste curso é fornecer conceitos...

  • 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

    htttp://www.josecintra.com/ead

  • 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 testadosno SGBD MySQL, mas são compatíveis com amaioria dos bancos de dados.

    Para melhor entendimento do conteúdo,subentende-se que o leitor possuaconhecimentos prévios sobre Modelagem deBancos de Dados e Teoria Relacional. Casocontrário, sugiro a leitura deste material.

    2

    https://www.mysql.com/http://docente.ifrn.edu.br/abrahaolopes/semestre-2013.1/3.2411.1v-prog-bd/conceitos-bd/viewhttps://www.mysql.com/

  • 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.

    Introdução

  • 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

    http://pt.wikipedia.org/wiki/%C3%81lgebra_relacionalhttp://pt.wikipedia.org/wiki/Edgar_Frank_Codd

  • 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

    http://pt.wikipedia.org/wiki/Stored_procedurehttp://pt.wikipedia.org/wiki/Trigger

  • 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

  • 7

    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.

    https://www.javatpoint.com/dbms-sql-command

  • Modelo de Dados: Cadastro de Funcionários

    8

    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...

  • 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

  • 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.

    DDL

  • 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

    http://josecintra.com/blog/otimizacao-desempenho-bancos-dados-mysql/

  • 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

    http://josecintra.com/blog/otimizacao-desempenho-bancos-dados-mysql/

  • 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

    http://josecintra.com/blog/otimizacao-desempenho-bancos-dados-mysql/

  • 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 eformataçã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

  • 24

    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

  • 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

  • 26

    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.

  • 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

  • 28

    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)

    )

  • 29

    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

  • 30

    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;

  • 31

    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.

  • 32

    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.

  • 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.

    DML

  • 34

    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.

    Sintaxe:

    INSERT INTO [( , ... )] VALUES

    ( expressão, ... );

    Nome da tabela que vai receber o novo registro

    Nomes dos campos que receberão os valores

    Valores que serão inseridos. A expressão deve ser compatível com o campo respectivo

  • 35

    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.

  • 36

    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.

  • 37

    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

  • 38

    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.

  • 39

    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.

  • 40

    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:

    UPDATE SET = , ...

    [ WHERE ]

    Nome da tabela cujos registros vão ser alterados

    Nomes dos campos que vão ser alterados

    Novos valores dos camposDetermina quais registros receberão as alterações, de acordo com a condição lógica (filtro)

  • 41

    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.

  • 42

    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.

  • 43

    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 [WHERE ]

    Tabela da qual queremos excluir os registros

    Filtro (condição) especificando quais registros vão ser excluídos

  • 44

    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.

  • 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...

    DQL

  • 46

    SELECT – Dados de Trabalho

    Tabela funcionario Tabela departamento

    Tabela projeto Tabela alocação

    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.

    func_id func_nome func_nasc func_sexo func_salario depto_id

    1 JOSÉ DA SILVA 2000-01-01 M 5000 1

    2 MARIA DA SILVA 1987-02-01 F 8000,5 1

    3 JOÃO DA SILVA 1970-01-01 M 5500,5 2

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

    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

    depto_id depto_nome

    1 COMPRAS

    2 VENDAS

    3 CONTABILIDADE

    4 INFORMÁTICA

    proj_sigla proj_nome proj_interno

    123 Projeto 123 0

    ABC Projeto ABC 0

    PQR Projeto PQR 1

    XYZ Projeto XYZ 0

    aloca_id func_id proj_sigla aloca_inicio aloca_fim

    1 1 XYZ 2019-01-01 00:00:00

    2 1 123 2020-01-01 00:00:00

    3 2 XYZ 2019-01-01 00:00:00 2020-01-01 00:00:00

    4 3 PQR 2018-01-01 00:00:00

    5 4 123 2019-01-01 00:00:00

  • 47

    Comando SELECT

    Sintaxe:

    SELECT [ ALL | DISTINCT ]

    FROM

    [ WHERE ]

    [ GROUP BY , ...

    [ HAVING ] ]

    ORDER BY [ 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...

  • 48

    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

  • 49

    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

  • 50

    SELECT – Lista de Campos

    Neste exemplo selecionamos 3 campos e um campo calculado da tabela

    funcionario, usando aliases:

    SELECT

    funcionario.func_id AS Código,

    func_nome Nome,

    func_salario Salário,

    (func_salario*1.10) AS ’Salário Reajustado’ FROM funcionario

    Apelidos

    Campo Calculado

    Prefixo (opcional nesse caso)

    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

    4 ANTONIO ALCÂNTARA 6500.00 7150.00

    5 MARIA DE SOUZA 6500.00 7150.00

    6 LUIZ MOURA 7500.00 8250.00

    7 JOANA OLIVEIRA 9000.70 9900.77

  • 51

    SELECT – Cláusula ORDER BY

    Podemos ordenar os resultados de uma consulta através da cláusula

    ORDER BY.

    Sintaxe:

    ORDER BY {|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.

  • 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

    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

  • 53

    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 ordemdecrescente 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

  • A cláusula WHERE permite filtar os registros a serem exibidos de acordocom uma condição do pesquisa que é basicamente uma coleção depredicados que podem ser combinados através dos operadores booleanosAND, 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…

    SELECT – Cláusula WHERE

    54

  • Fumncionários que trabalham no departamento de número 2:

    SELECT * FROM funcionario WHERE depto_id = 2

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

    SELECT * FROM funcionario WHERE depto_id 2

    Veja que a consulta não trouxe códigos de departamentos nulos. Veremosmais à frente como tratar campos nulos.

    SELECT – Comparações

    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

    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

    55

  • Funcionários que recebem salário maior que R$ 7.000,00:

    SELECT * FROM funcionario WHERE func_salario > 7000

    Funcionários que trabalham no departamento de número 1 e recebemsalário maior que R$ 7.000,00:

    SELECT * FROM funcionario WHERE depto_id = 1 AND

    func_salario > 7000

    SELECT – Comparações

    func_id func_nome func_nasc func_sexo func_salario depto_id

    2MARIA DA SILVA 1987-02-01 F 8000,5 1

    6LUIZ MOURA 1960-05-01 M 7500 4

    7JOANA OLIVEIRA 1975-02-01 F 9000,7 1

    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 156

  • Funcionários Homens que recebem salários maiores que R$ 6.000,00 eMulheres 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)

    SELECT – Comparações

    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

  • A cláusula BETWEEN é usada para facilitar a filtragem de faixas devalores.

    Exemplo: Listar os funcionários que recebem salários entre R$ 6.000,00 eR$ 8.000,00 (inclusive)

    Uma solução usando operadores condicionais poderia ser:

    SELECT * FROM funcionario

    WHERE func_salario >= 6000 AND

    func_salario

  • 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.

    SELECT – Cláusula IN

    59

  • O operador LIKE é usada para localizar trechos de textos em camposalfanuméricos de acordo com padrões. Para isso são usados os caracterescoringa (wildcards) que são os seguintes:

    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.

    SELECT – LIKE

    WildCard Função

    % Qualquer quantidade de caracteres

    _ Exatamente um caractere

    60

  • Os valores nulos são um caso à parte e são muito difíceis de seremtrabalhados pelos seguintes motivos:

    • Um valor nulo nunca é igual à outro;

    • Operações com nulos sempre retornam nulos, sejam eles numéricos ounão.

    Desta forma, por exemplo:

    10 * NULL = NULL;

    10 + NULL = NULL;

    Para trabalhar com valores nulos temos, entre outros, os seguintesoperadores 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.

    SELECT –Valores nulos (NULL)

    61

  • Exemplo 1: Pesquisar os funcionários que não estão cadastrados emnenhum departamento (cod_depto é nulo):

    SELECT * FROM funcionario WHERE depto_id IS NULL

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

    SELECT * FROM funcionario WHERE depto_id IS NOT NULL

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

    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 seriaNULL.

    SELECT –Tratando Valores Nulos

    62

  • SQL não é sensível ao caso, portanto escrever SELECT ou select ouSeLeCt é a mesma coisa. No entanto, o mesmo não vale para o conteúdodos campos que nem sempre é sensível ao caso. Isso depende doCHARSET e COLLATION usados. Dessa forma, ‘ANTONIO’ pode serdiferente 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’

    SELECT – Maiúsculas e Minúsculas

    63

  • 64

    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.

  • 65

    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

  • 66

    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

    WHEN 'F' THEN 'feminino’

    ELSE 'Masculino’

    END AS Sexo

    FROM funcionario

    Obs:

    É possível também usar expressões

    lógicas para os valores

  • 67

    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.

  • 68

    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

  • 69

    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édiaNULL 6500

    1 7333,7333332 6000,254 7500

  • 70

    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

    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 MédiaNULL 6500

    1 7333,733333

    2 6000,254 7500

    depto_id func_sexo Média

    1M 50001F 8500,62M 6000,25

    NULLF 6500

    4M 7500

  • 71

    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,22M 12000,5

    NULLF 65004M 7500

  • 72

    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.

  • Exemplo: Trazer a quantidade de funcionários que trabalham em cada

    departamento:

    SELECT

    d.depto_id,

    d.depto_nome,

    (SELECT COUNT(*) FROM funcionario AS f

    WHERE f.depto_id = d.depto_id) AS ‘Qtde’

    FROM

    departamento AS d

    73

    SELECT – Subconsulta Como Campo

    Essa subconsulta destacada em verde é um campo da consulta

    principal e recebe um nome (alias) de ‘Qtde’.

    Em sua cláusula WHERE, ela faz referência a um campo

    da consulta principal. Veja que os parênteses são importantes

    depto_id depto_nome Qtde

    1COMPRAS 3

    2VENDAS 2

    3CONTABILIDADE 0

    4INFORMÁTICA 1

  • Exemplo: Usar a consulta do exemplo 1 (página anterior) para trazer os

    departamentos que não possuem funcionários:

    SELECT * FROM (

    SELECT

    d.depto_id,

    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

    74

    SELECT – Subconsulta Como Fonte de Dados

    Essa subconsulta destacada em verde é agora usada na

    cláusula FROM como se fosse uma tabela ou view.

    Seus campos podem ser referenciados normalmente na

    consulta principal através do seu alias (tabela)

    depto_id depto_nome Qtde

    3CONTABILIDADE 0

  • Exemplo: Trazer os códigos e nomes dos funcionários que já trabalharam

    em pelo menos um projeto:

    SELECT

    f.func_id,f.func_nome

    FROM

    funcionario f

    WHERE

    f.func_id IN (SELECT DISTINCT a.func_id FROM alocacao a)

    75

    SELECT – Subconsulta Como Filtro

    Essa subconsulta destacada em verde é agora usada

    na cláusula WHERE através do operador IN

    func_id func_nome

    1JOSÉ DA SILVA

    2MARIA DA SILVA

    3JOÃO DA SILVA

    4ANTONIO ALCÂNTARA

  • 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

  • 78

    SELECT – Junções de Tabelas

    Fonte: terminalroot.com.br

    https://terminalroot.com.br/2019/10/inner-join-left-join-right-join-mysql.html

  • 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 - Exemplos

  • SELECT

    f.func_id,f.func_nome,d.depto_nome

    FROM

    funcionario f

    INNER JOIN

    departamento d

    ON

    f.depto_id = d.depto_id

    80

    SELECT – Junções de Tabelas – INNER JOIN

    func_id func_nome depto_nome

    1JOSÉ DA SILVA COMPRAS

    2MARIA DA SILVA COMPRAS

    7JOANA OLIVEIRA COMPRAS

    3JOÃO DA SILVA VENDAS

    4ANTONIO ALCÂNTARA VENDAS

    6LUIZ MOURA INFORMÁTICA

    Destacado em verde, vemos a junção por

    igualdade do campo ‘depto_id’ presente

    nas duas tabelas.

    Veja que o registro 5 não apareceu, pois

    está com NULL nesse campo

    O seu chefe não gostou desse relatório!

    Não apareceu a MARIA DE SOUZA.

    A solução é refazer usando LEFT

    JOIN, que veremos a seguir →

  • SELECT

    f.func_id,f.func_nome,d.depto_nome

    FROM

    funcionario f

    LEFT JOIN

    departamento d

    ON

    f.depto_id = d.depto_id

    81

    SELECT – Junções de Tabelas – LEFT JOIN

    Destacado em verde, vemos a junção por

    igualdade com LEFT JOIN.

    Agora apareceu o registro cinco

    O seu chefe AINDA não gostou desse

    relatório:

    Cadê o departamento de

    contabilidade?

    A solução é refazer usando RIGHT

    JOIN, que veremos a seguir →

    func_id func_nome depto_nome

    1JOSÉ DA SILVA COMPRAS

    2MARIA DA SILVA COMPRAS

    3JOÃO DA SILVA VENDAS

    4ANTONIO ALCÂNTARA VENDAS

    5MARIA DE SOUZA NULL

    6LUIZ MOURA INFORMÁTICA

    7JOANA OLIVEIRA COMPRAS

  • SELECT

    f.func_id,f.func_nome,d.depto_nome

    FROM

    funcionario f

    RIGHT JOIN

    departamento d

    ON

    f.depto_id = d.depto_id

    82

    SELECT – Junções de Tabelas – RIGHT JOIN

    Destacado em verde, vemos a junção por

    igualdade com RIGHT JOIN.

    Agora apareceu o departamento de

    CONTABILIDADE, mas o registro 5

    Desapareceu de novo

    É melhor nem levar esse relatório para

    o seu chefe:

    A contabilidade está ok, mas a MARIA

    DE SOUZA desapareceu!

    A solução é refazer usando UNION,

    que veremos a seguir →

    func_id func_nome depto_nome

    1JOSÉ DA SILVA COMPRAS

    2MARIA DA SILVA COMPRAS

    3JOÃO DA SILVA VENDAS

    4ANTONIO ALCÂNTARA VENDAS

    5MARIA DE SOUZA NULL

    6LUIZ MOURA INFORMÁTICA

    7JOANA OLIVEIRA COMPRAS

  • 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 – FULL JOIN

  • SELECT

    f.func_id,f.func_nome,d.depto_nome

    FROM

    funcionario f

    LEFT JOIN

    departamento d

    ON

    f.depto_id = d.depto_id

    UNION

    SELECT

    f.func_id,f.func_nome,d.depto_nome

    FROM

    funcionario f

    RIGHT JOIN

    departamento d

    ON

    f.depto_id = d.depto_id

    84

    SELECT – Junções de Tabelas – UNION

    Pronto. Com o uso de UNION

    Conseguimos o resultado

    esperado. O seu chefe te elogiou,

    mas pediu uma última alteração:

    Mudar o valor NULL para uma

    coisa mais bonitinha

    Ainda bem que aprendemos a

    função COALESCE. Vejamos a

    versão final do relatório →

    func_id func_nome depto_nome

    1 JOSÉ DA SILVA COMPRAS

    2 MARIA DA SILVA COMPRAS

    3 JOÃO DA SILVA VENDAS

    4 ANTONIO ALCÂNTARA VENDAS

    5 MARIA DE SOUZA NULL

    6 LUIZ MOURA INFORMÁTICA

    7 JOANA OLIVEIRA COMPRAS

    NULL NULL CONTABILIDADE

  • 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 passadacomo parâmetro

    Ex: MONTH(‘2019-01-01’) # Retorna: 1

    • DATEDIFF()→ Retorna o número de dias entre duas datasEx: DATEDIFF(‘2020-06-25’, ‘2020-06-15’) # Retorna: 10

    • TIMESTAMPDIFF() → Retorna a diferença entre duas datas em uma unidadeespecí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âmetrosEx: DATE_FORMAT("2020-06-15", "%d/%m/%Y") # Retorna:15/06/2020

    85

    SELECT – Funções com DatasTIMESTAMPDIFF(DAY,'2022-02-01','2022-02-21')

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

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

    Exercícios

  • 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

    Exercícios Resolvidos

  • FIMObrigado!

    93

  • 94

    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

    https://dev.mysql.com/doc/http://www.inf.pucrs.br/~danielc/bda/SQL1.ppthttps://www.w3schools.com/sql/http://www.josecintra.com/bloghttp://www.josecintra.com/blog