Capa do Ebook gratuito Preparatório Caixa Econômica Federal - Técnico Bancário - Tecnologia da Informação

Preparatório Caixa Econômica Federal - Técnico Bancário - Tecnologia da Informação

Novo curso

20 páginas

Preparatório Caixa TI: SQL para consultas, manipulação e definição de dados

Capítulo 4

Tempo estimado de leitura: 12 minutos

+ Exercício

Visão geral: DDL, DML e DQL

Em SQL, é comum separar os comandos por finalidade: DDL (Data Definition Language) define estruturas (tabelas, colunas, restrições), DML (Data Manipulation Language) manipula dados (inserir, atualizar, excluir) e DQL (Data Query Language) consulta dados (SELECT). Em prova, a banca costuma misturar sintaxe com interpretação de resultados, principalmente em filtros, agregações, JOINs, NULL e transações.

Bloco prático 1: DDL (CREATE, ALTER, DROP)

1) CREATE TABLE: criando estruturas e restrições

O CREATE TABLE cria uma tabela e pode definir restrições de integridade. As mais cobradas: PRIMARY KEY (identificador único), UNIQUE (unicidade), NOT NULL (obrigatoriedade), CHECK (regra), FOREIGN KEY (referência a outra tabela).

Exemplo prático (tabelas típicas de domínio bancário):

CREATE TABLE cliente (  id_cliente     INTEGER PRIMARY KEY,  nome           VARCHAR(100) NOT NULL,  cpf            CHAR(11) UNIQUE NOT NULL,  dt_cadastro    DATE NOT NULL);CREATE TABLE conta (  id_conta       INTEGER PRIMARY KEY,  id_cliente     INTEGER NOT NULL,  agencia        CHAR(4) NOT NULL,  numero         CHAR(8) NOT NULL,  saldo          DECIMAL(15,2) NOT NULL DEFAULT 0,  status         CHAR(1) NOT NULL CHECK (status IN ('A','B')),  CONSTRAINT fk_conta_cliente FOREIGN KEY (id_cliente) REFERENCES cliente(id_cliente));CREATE TABLE lancamento (  id_lanc        INTEGER PRIMARY KEY,  id_conta       INTEGER NOT NULL,  dt_lanc        DATE NOT NULL,  tipo           CHAR(1) NOT NULL CHECK (tipo IN ('C','D')),  valor          DECIMAL(15,2) NOT NULL CHECK (valor > 0),  descricao      VARCHAR(200),  CONSTRAINT fk_lanc_conta FOREIGN KEY (id_conta) REFERENCES conta(id_conta));

Pontos de prova:

  • DEFAULT é aplicado quando o valor não é informado no INSERT.
  • CHECK valida domínio (ex.: status A/B).
  • FOREIGN KEY impede inserir filho sem pai (salvo regras específicas do SGBD).

2) ALTER TABLE: evoluindo o esquema

O ALTER TABLE altera uma tabela existente: adicionar coluna, alterar tipo (quando permitido), adicionar/remover restrições.

Continue em nosso aplicativo

Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.

ou continue lendo abaixo...
Download App

Baixar o aplicativo

Passo a passo prático:

  • Adicionar coluna:
ALTER TABLE cliente ADD email VARCHAR(120);
  • Adicionar restrição (ex.: email único):
ALTER TABLE cliente ADD CONSTRAINT uq_cliente_email UNIQUE (email);
  • Remover restrição (nome da constraint precisa ser conhecido):
ALTER TABLE cliente DROP CONSTRAINT uq_cliente_email;

Armadilha comum: em muitos SGBDs, alterar tipo/tamanho pode falhar se houver dados incompatíveis.

3) DROP: removendo objetos

DROP TABLE remove a tabela e seus dados. Em cenários com dependências (FK), pode falhar se houver tabelas referenciando, a menos que se use opções específicas do SGBD (não dependa disso em prova, a menos que esteja explícito).

DROP TABLE lancamento;

Bloco prático 2: DML (INSERT, UPDATE, DELETE)

1) INSERT: inserindo linhas

O INSERT adiciona registros. Em prova, atenção a: ordem das colunas, valores compatíveis, campos NOT NULL e DEFAULT.

INSERT INTO cliente (id_cliente, nome, cpf, dt_cadastro, email)VALUES (1, 'Ana Silva', '12345678901', DATE '2025-01-10', 'ana@exemplo.com');INSERT INTO conta (id_conta, id_cliente, agencia, numero, saldo, status)VALUES (10, 1, '0001', '00001234', 1500.00, 'A');

INSERT com coluna omitida: se a coluna tiver DEFAULT ou aceitar NULL, a inserção pode ocorrer.

INSERT INTO conta (id_conta, id_cliente, agencia, numero, status)VALUES (11, 1, '0001', '00005678', 'A');

2) UPDATE: atualizando com segurança

O UPDATE altera linhas existentes. O ponto mais cobrado é o WHERE: sem WHERE, atualiza todas as linhas.

Passo a passo prático:

  • Atualizar saldo de uma conta específica:
UPDATE contaSET saldo = saldo + 200.00WHERE id_conta = 10;
  • Atualizar com múltiplas condições:
UPDATE contaSET status = 'B'WHERE id_cliente = 1 AND saldo < 0;

Tratamento de NULL no UPDATE: para preencher email ausente:

UPDATE clienteSET email = 'sem_email@exemplo.com'WHERE email IS NULL;

3) DELETE: removendo linhas

O DELETE remove linhas. Assim como no UPDATE, o WHERE é crítico.

DELETE FROM lancamentoWHERE dt_lanc < DATE '2024-01-01';

Armadilha comum: WHERE campo = NULL não funciona como esperado; use IS NULL.

Bloco prático 3: DQL (SELECT) e leitura de resultados

1) SELECT básico: projeção e FROM

O SELECT define quais colunas (projeção) e de quais tabelas (FROM). Em prova, avalie a ordem lógica de execução (conceitual): FROMWHEREGROUP BYHAVINGSELECTORDER BY.

SELECT id_cliente, nome, emailFROM cliente;

2) WHERE: filtros, operadores e precedência

O WHERE filtra linhas antes de agregações. Operadores comuns: =, <>, >, <, BETWEEN, LIKE, IN, AND, OR, NOT.

Exemplos práticos:

SELECT *FROM contaWHERE status = 'A' AND saldo >= 1000;SELECT *FROM clienteWHERE nome LIKE 'Ana%';SELECT *FROM lancamentoWHERE dt_lanc BETWEEN DATE '2025-01-01' AND DATE '2025-01-31';

Precedência: AND costuma ser avaliado antes de OR. Use parênteses para deixar explícito.

SELECT *FROM contaWHERE (status = 'A' OR status = 'B') AND saldo > 0;

3) ORDER BY: ordenação

ORDER BY ordena o resultado final. Pode ordenar por coluna, alias ou posição (esta última é menos recomendada).

SELECT id_conta, saldoFROM contaWHERE status = 'A'ORDER BY saldo DESC, id_conta ASC;

4) Agregações: COUNT, SUM, AVG (e cuidados com NULL)

Funções de agregação resumem várias linhas em um valor. Em geral, NULL é ignorado por SUM/AVG/COUNT(coluna). Já COUNT(*) conta linhas, incluindo as que têm NULL em colunas.

SELECT COUNT(*) AS total_contasFROM conta;SELECT COUNT(email) AS clientes_com_emailFROM cliente;SELECT SUM(saldo) AS soma_saldos, AVG(saldo) AS media_saldosFROM contaWHERE status = 'A';

Armadilha típica: COUNT(email) não conta clientes com email NULL.

5) GROUP BY: agregando por grupos

GROUP BY agrupa linhas para calcular agregações por categoria. Regra de prova: no SELECT, toda coluna não agregada deve estar no GROUP BY.

SELECT id_cliente, COUNT(*) AS qtd_contas, SUM(saldo) AS total_saldoFROM contaGROUP BY id_cliente;

6) HAVING: filtro após agregação

HAVING filtra grupos (após GROUP BY). Use WHERE para filtrar linhas antes de agrupar; HAVING para filtrar o resultado agregado.

SELECT id_cliente, SUM(saldo) AS total_saldoFROM contaGROUP BY id_clienteHAVING SUM(saldo) > 5000;

Comparação rápida:

  • WHERE: filtra linhas (antes do agrupamento).
  • HAVING: filtra grupos (depois do agrupamento).

7) Tratamento de NULL: IS NULL, COALESCE e lógica de três valores

Em SQL, comparações com NULL não resultam em verdadeiro/falso, mas em desconhecido. Por isso, use IS NULL e IS NOT NULL.

SELECT *FROM clienteWHERE email IS NULL;

COALESCE substitui NULL pelo primeiro valor não nulo, útil em relatórios.

SELECT nome, COALESCE(email, 'NÃO INFORMADO') AS email_exibicaoFROM cliente;

JOINs: combinando tabelas

1) INNER JOIN: apenas correspondências

INNER JOIN retorna linhas que têm correspondência nas duas tabelas (pela condição ON).

SELECT c.nome, ct.agencia, ct.numero, ct.saldoFROM cliente cINNER JOIN conta ct ON ct.id_cliente = c.id_clienteWHERE ct.status = 'A';

2) LEFT JOIN: mantém tudo da esquerda

LEFT JOIN retorna todas as linhas da tabela da esquerda, mesmo sem correspondência; colunas da direita vêm como NULL quando não há match. Muito cobrado para achar “sem relacionamento”.

SELECT c.id_cliente, c.nome, ct.id_contaFROM cliente cLEFT JOIN conta ct ON ct.id_cliente = c.id_clienteWHERE ct.id_conta IS NULL;

Esse padrão encontra clientes sem conta.

3) RIGHT JOIN: mantém tudo da direita

RIGHT JOIN é o espelho do LEFT JOIN (mantém tudo da direita). Em prova, pode aparecer, mas muitas vezes pode ser reescrito invertendo as tabelas e usando LEFT JOIN.

SELECT c.nome, ct.id_contaFROM cliente cRIGHT JOIN conta ct ON ct.id_cliente = c.id_cliente;

4) Cuidados com filtros em JOINs

Em LEFT JOIN, colocar filtro da tabela da direita no WHERE pode “transformar” o resultado em algo parecido com INNER JOIN (porque elimina as linhas com NULL). Alternativa: mover o filtro para o ON quando a intenção é preservar a tabela da esquerda.

SELECT c.nome, ct.id_contaFROM cliente cLEFT JOIN conta ct ON ct.id_cliente = c.id_cliente AND ct.status = 'A';

Subconsultas, IN, EXISTS

1) Subconsulta com IN

IN testa pertencimento a uma lista (ou resultado de subconsulta). É comum para filtrar por conjunto de chaves.

SELECT nomeFROM clienteWHERE id_cliente IN (  SELECT id_cliente  FROM conta  WHERE saldo > 1000);

Observação de prova: se a subconsulta retornar NULL, o comportamento pode afetar comparações em alguns cenários; em geral, prefira EXISTS quando a intenção é “existe relacionamento”.

2) Subconsulta correlacionada com EXISTS

EXISTS verifica se a subconsulta retorna ao menos uma linha. É muito usado para “clientes que possuem ao menos uma conta” ou “contas que possuem lançamentos”.

SELECT c.id_cliente, c.nomeFROM cliente cWHERE EXISTS (  SELECT 1  FROM conta ct  WHERE ct.id_cliente = c.id_cliente);

3) NOT EXISTS: ausência de relacionamento

SELECT c.id_cliente, c.nomeFROM cliente cWHERE NOT EXISTS (  SELECT 1  FROM conta ct  WHERE ct.id_cliente = c.id_cliente);

Operações de conjunto (quando pertinentes)

Operações de conjunto combinam resultados de SELECTs compatíveis (mesmo número e tipos de colunas). As mais comuns:

  • UNION: une e remove duplicatas.
  • UNION ALL: une e mantém duplicatas (geralmente mais eficiente).
  • INTERSECT e EXCEPT/MINUS: podem existir conforme o padrão/implementação; em prova, foque no conceito.
SELECT id_cliente FROM conta WHERE status = 'A'UNIONSELECT id_cliente FROM conta WHERE saldo > 1000;

Interpretação: clientes que têm conta ativa ou saldo acima de 1000 (sem duplicar ids).

Transações, ACID e bloqueios (conceitual)

1) O que é transação e por que importa

Transação é um conjunto de operações SQL que deve ser tratado como uma unidade lógica de trabalho. Em ambiente bancário, isso é essencial para evitar inconsistências (ex.: debitar de uma conta e creditar em outra).

2) COMMIT e ROLLBACK

  • COMMIT: confirma as alterações feitas na transação.
  • ROLLBACK: desfaz alterações não confirmadas.
UPDATE conta SET saldo = saldo - 100.00 WHERE id_conta = 10;UPDATE conta SET saldo = saldo + 100.00 WHERE id_conta = 11;COMMIT;

Se ocorrer erro entre as operações, o correto é desfazer para não ficar “meia transferência”:

UPDATE conta SET saldo = saldo - 100.00 WHERE id_conta = 10;-- ocorreu um erro antes do créditoROLLBACK;

3) ACID (conceitos cobrados)

  • Atomicidade: tudo ou nada (ou confirma tudo, ou desfaz tudo).
  • Consistência: regras de integridade são preservadas (constraints, chaves, checks).
  • Isolamento: transações concorrentes não devem interferir de forma indevida (evitar leituras sujas, etc.).
  • Durabilidade: após COMMIT, a alteração persiste mesmo com falhas.

4) Bloqueios (locks) em nível conceitual

Para garantir isolamento, o SGBD usa bloqueios. Ideia central para prova:

  • Leituras e escritas concorrentes podem gerar anomalias.
  • Bloqueios podem impedir que duas transações alterem o mesmo dado ao mesmo tempo.
  • Dependendo do nível de isolamento, o SGBD pode permitir ou evitar certos fenômenos (ex.: leitura suja, leitura não repetível, phantom).

Sem entrar em sintaxe específica, o que a banca costuma cobrar é reconhecer que concorrência exige controle e que COMMIT/ROLLBACK delimitam a efetivação das mudanças.

Bateria de consultas típicas de prova (com plano lógico)

Consulta 1: listar contas ativas com saldo acima de um valor, ordenando

SELECT id_conta, agencia, numero, saldoFROM contaWHERE status = 'A' AND saldo > 1000ORDER BY saldo DESC;

Plano lógico: FROM (conta) → WHERE filtra status e saldo → SELECT projeta colunas → ORDER BY ordena por saldo desc.

Consulta 2: total de contas por cliente (com agregação)

SELECT id_cliente, COUNT(*) AS qtd_contasFROM contaGROUP BY id_cliente;

Plano lógico: FROM → GROUP BY cria grupos por id_cliente → COUNT calcula por grupo → SELECT retorna uma linha por cliente.

Consulta 3: clientes com total de saldo acima de 5000 (HAVING)

SELECT c.id_cliente, c.nome, SUM(ct.saldo) AS total_saldoFROM cliente cINNER JOIN conta ct ON ct.id_cliente = c.id_clienteGROUP BY c.id_cliente, c.nomeHAVING SUM(ct.saldo) > 5000ORDER BY total_saldo DESC;

Plano lógico: FROM + JOIN combina cliente/conta → GROUP BY agrupa por cliente → HAVING filtra grupos pelo SUM → SELECT projeta → ORDER BY ordena pelo total.

Consulta 4: clientes sem conta (LEFT JOIN + IS NULL)

SELECT c.id_cliente, c.nomeFROM cliente cLEFT JOIN conta ct ON ct.id_cliente = c.id_clienteWHERE ct.id_conta IS NULL;

Plano lógico: FROM cliente → LEFT JOIN tenta casar conta → WHERE mantém apenas os casos sem correspondência (ct.id_conta NULL).

Consulta 5: contas que tiveram ao menos um lançamento de débito (EXISTS)

SELECT ct.id_conta, ct.agencia, ct.numeroFROM conta ctWHERE EXISTS (  SELECT 1  FROM lancamento l  WHERE l.id_conta = ct.id_conta AND l.tipo = 'D');

Plano lógico: FROM conta → WHERE EXISTS testa, para cada conta, se há ao menos um lançamento do tipo D.

Consulta 6: contas sem lançamentos (NOT EXISTS)

SELECT ct.id_contaFROM conta ctWHERE NOT EXISTS (  SELECT 1  FROM lancamento l  WHERE l.id_conta = ct.id_conta);

Plano lógico: FROM conta → WHERE NOT EXISTS mantém contas para as quais a subconsulta não retorna linhas.

Consulta 7: diferença entre COUNT(*) e COUNT(coluna)

SELECT COUNT(*) AS total_linhas, COUNT(descricao) AS descricoes_preenchidasFROM lancamento;

Plano lógico: FROM lancamento → agregações calculadas sobre o conjunto inteiro; COUNT(descricao) ignora NULL em descricao.

Consulta 8: filtrar por lista (IN) e reforçar precedência

SELECT id_conta, status, saldoFROM contaWHERE status IN ('A','B') AND (saldo < 0 OR saldo > 10000);

Plano lógico: FROM → WHERE aplica IN e parênteses para controlar AND/OR → SELECT projeta.

Consulta 9: unir conjuntos (UNION vs UNION ALL)

SELECT id_cliente FROM conta WHERE status = 'A'UNION ALLSELECT id_cliente FROM conta WHERE saldo > 1000;

Plano lógico: executa os dois SELECTs separadamente e concatena resultados; com UNION ALL, duplicatas permanecem (um mesmo cliente pode aparecer duas vezes).

Consulta 10: relatório com NULL tratado (COALESCE) e ordenação

SELECT nome, COALESCE(email, 'NÃO INFORMADO') AS email_exibicaoFROM clienteORDER BY nome ASC;

Plano lógico: FROM cliente → SELECT calcula coluna derivada com COALESCE → ORDER BY ordena por nome.

Agora responda o exercício sobre o conteúdo:

Em uma consulta com LEFT JOIN entre cliente (à esquerda) e conta (à direita), qual alternativa evita que um filtro na tabela da direita elimine os clientes sem conta, preservando todas as linhas de cliente?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

No LEFT JOIN, um filtro da tabela da direita no WHERE pode remover linhas onde a direita veio como NULL, aproximando o resultado de um INNER JOIN. Colocar o filtro no ON preserva todas as linhas da esquerda.

Próximo capitúlo

Preparatório Caixa TI: Redes de Computadores e fundamentos de comunicação

Arrow Right Icon
Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.