Colunas calculadas e funções em SQL: expressões CASE

Aprenda a calcular novas colunas em consultas SQL. Faça cálculos aritméticos e use apelidos claros para as colunas, converta valores entre tipos de dados, limpe e recorte textos como nomes e endereços de e-mail e calcule datas, meses, idades e prazos. Trate valores ausentes com a lógica de NULL, COALESCE e NULLIF e classifique linhas em categorias com expressões CASE. Os exemplos funcionam em SQLite e PostgreSQL, e as diferenças encontradas em MySQL, SQL Server e Oracle são apontadas ao longo do caminho.

BásicoAula 3 de 6 do curso Curso de Noções básicas de SQL

O que você vai aprender

  1. Calcule novos valores para cada linha usando operações aritméticas e funções, dê nomes claros aos resultados e evite que os tipos de dados alterem a resposta.
    • Calcular novas colunas e nomeá-las com apelidos
      Escreva expressões na lista SELECT, nomeie os resultados com AS e saiba onde esses nomes podem ser usados em uma consulta.
    • Calcular com operadores aritméticos e funções numéricas
      Use +, -, *, / e % na ordem correta, evite surpresas com a divisão inteira e arredonde resultados com ROUND e funções relacionadas.
    • Converter valores entre tipos de dados
      Reconheça o tipo de cada valor, converta-o explicitamente com CAST e identifique as conversões automáticas que alteram ordenações, comparações e resultados.
  2. Preveja o efeito de NULL em cálculos, comparações e filtros e substitua ou gere valores ausentes intencionalmente.
    • Prever o comportamento de NULL em cálculos e condições
      Explique o que significa NULL, como ele se propaga pelas expressões e por que uma condição que encontra NULL não é verdadeira nem falsa.
    • Substituir e gerar valores ausentes com COALESCE e NULLIF
      Preencha lacunas com COALESCE, transforme zeros e valores marcadores em NULL com NULLIF e escolha valores de substituição que preservem o significado dos dados.
  3. Concatene, organize, meça e recorte valores de texto para que nomes, endereços de e-mail e códigos fiquem consistentes e utilizáveis.
    • Concatenar e limpar valores de texto
      Concatene textos, altere letras maiúsculas e minúsculas, remova espaços das extremidades e substitua caracteres, além de aninhar essas funções para limpar entradas desorganizadas.
    • Medir o comprimento e extrair partes de textos
      Conte caracteres, encontre onde um caractere aparece e recorte partes de texto usando posições que começam em 1.
  4. Escreva e leia valores de data corretamente, decomponha-os e formate-os e faça cálculos com dias, meses e períodos.
    • Escrever, armazenar e ler valores de data e hora
      Conheça os tipos de data e hora, escreva datas no formato ISO sem ambiguidade, converta texto em datas e obtenha a data e a hora atuais.
    • Extrair e formatar partes de datas
      Extraia o ano, o mês ou o dia da semana, agrupe datas por período e transforme datas em texto legível.
    • Calcular com datas e filtrar intervalos de datas
      Adicione dias e meses, meça o tempo entre duas datas e escreva filtros de data que incluam todas as linhas de um período.
  5. Transforme condições em rótulos, categorias e ordens de classificação personalizadas com CASE e combine-o com outras funções em consultas completas para relatório.
    • Classificar linhas em categorias com CASE pesquisado
      Escreva CASE WHEN … THEN … ELSE … END, ordene as condições para que cada linha caia no grupo correto e trate valores de fronteira e valores NULL.
    • Usar CASE simples e aplicar CASE em diferentes partes de uma consulta
      Traduza códigos com CASE simples, crie indicadores e ordens de classificação personalizadas e reconheça as formas mais curtas oferecidas por outros bancos de dados.
    • Combinar funções em uma consulta completa para relatório
      Construa um relatório com várias colunas calculadas passo a passo, aninhe funções corretamente e confira cada coluna com linhas calculadas à mão.

Guia de estudo de Colunas calculadas e funções em SQL

5 capítulos

1

Criar colunas calculadas com expressões e apelidos

Colunas calculadas transformam os valores que já estão em uma linha em respostas úteis: o valor de um item do pedido, um desconto ou uma variação percentual. Apelidos claros tornam esses resultados legíveis, enquanto parênteses e tipos de dados determinam o que a SQL realmente calcula. Você construirá expressões em pequenas etapas, verá por que a divisão inteira pode eliminar uma fração e escolherá conversões explícitas quando a forma armazenada não for adequada à operação.

1.1 Calcular novas colunas e nomeá-las com apelidos

Uma coluna de resultado pode mostrar um valor que não está armazenado em nenhum lugar da tabela. A SQL o calcula a partir da linha atual. Uma expressão combina colunas, valores fixos, operadores e chamadas de função.

Calcule um valor para cada linha
SELECT order_id,
       quantity * unit_price AS line_total
FROM orders;

Para quantidade 3 e preço unitário 12,50, a nova coluna mostra 37.5. Cada linha fornece sua própria quantidade e seu próprio preço. A consulta deixa as colunas armazenadas inalteradas. Uma função escalar, como ROUND(unit_price, 0), também retorna um valor por linha de entrada. Adicioná-la à lista SELECT não combina linhas. Já uma função de agregação como SUM ou AVG calcula um valor para um grupo.

O nome depois de AS é um apelido de coluna: um cabeçalho para o resultado. Sem ele, SQLite usa o texto da expressão como cabeçalho; PostgreSQL usa ?column? para essa expressão aritmética. AS é opcional, mas torna mais fácil distinguir um nome de uma vírgula ausente.

Escolha nomes e aspas

Use um nome simples como line_total: letras, algarismos e sublinhados, começando com uma letra. Um nome que contenha espaço ou seja uma palavra reservada precisa de aspas duplas: AS "Line Total" ou AS "order". Aspas simples indicam valores de texto, como 'Boston'. MySQL também aceita crases para nomes, e SQL Server aceita colchetes.

PostgreSQL converte nomes sem aspas para minúsculas: AS LineTotal produz linetotal. Aspas duplas preservam a grafia em AS "LineTotal". SQLite mantém um apelido como foi digitado. Nomes em minúsculas com sublinhados funcionam bem em ambos.

Use um apelido na etapa correta

A ordem lógica é FROM, WHERE, SELECT e depois ORDER BY. A tabela é escolhida e as linhas são filtradas antes que as expressões de saída recebam seus apelidos. A ordenação acontece depois.

SELECT order_id,
       quantity * unit_price AS line_total
FROM orders
WHERE quantity * unit_price > 100
ORDER BY line_total DESC;

ORDER BY pode usar line_total. A SQL padrão, PostgreSQL e MySQL não podem usar esse novo apelido em WHERE; repita a expressão nesse ponto. SQLite aceita um apelido em WHERE como extensão, mas essa forma falhará quando for transferida para PostgreSQL.

Um novo apelido também não está disponível para outra expressão na mesma lista SELECT. Depois de unit_price * 1.08 AS with_tax, escrever with_tax - unit_price AS tax falha se a tabela não tiver uma coluna with_tax. Escreva unit_price * 1.08 - unit_price AS tax.

Investigue um resultado surpreendente

SELECT first_name last_name FROM customers; é SQL válida. Ela exibe uma coluna de primeiros nomes com o apelido last_name. Para recuperar ambas as colunas, escreva SELECT first_name, last_name FROM customers;. Assim, uma vírgula ausente pode produzir um resultado enganoso sem gerar erro.

Para verificar rapidamente uma expressão, uma tabela é desnecessária: SELECT 19.99 * 3 AS total; retorna 59.97 no SQLite e no PostgreSQL. Oracle anterior à Release 23 exige FROM DUAL para essa consulta; Release 23 e versões posteriores também permitem SELECT sem FROM.

Principais conclusões

  • Uma coluna calculada calcula um valor para cada linha sem alterar os dados armazenados.
  • Uma função escalar preserva as linhas; uma função de agregação combina valores de um grupo.
  • Use aspas duplas para nomes que precisam delas e aspas simples para valores de texto.
  • ORDER BY pode usar um apelido de saída; repita a expressão em uma cláusula WHERE portátil.
  • Um novo apelido não está disponível em outro ponto da mesma lista SELECT.
  • Uma vírgula ausente pode transformar o nome da próxima coluna em um apelido.

1.2 Calcular com operadores aritméticos e funções numéricas

Expressões aritméticas transformam quantidades originais em valores, taxas e diferenças. Os operadores são +, -, *, / e %; o módulo fornece o resto da divisão.

Controle a ordem do cálculo

Multiplicação, divisão e módulo vêm antes de adição e subtração. Operadores de mesma precedência são executados da esquerda para a direita. Assim, 10 + 3 * 2 resulta em 16, enquanto (10 + 3) * 2 resulta em 26.

Para quantidade 3, preço unitário 12,50 e percentual de desconto 10:

quantity * unit_price * (1 - discount_pct / 100.0)

Primeiro, 10 / 100.0 resulta em 0.1. Os parênteses fornecem a fração paga, 0.9. O valor bruto é 37.5, então o valor líquido é 33.75. Sem parênteses, quantity * unit_price * 1 - discount_pct / 100.0 subtrai 0.1 de 37.5 e resulta em 37.4.

Preserve frações durante a divisão

No SQLite, PostgreSQL e SQL Server, dividir um inteiro por outro descarta a fração em direção a zero: 7 / 2 resulta em 3, e -7 / 2 resulta em -3. MySQL e Oracle fornecem um resultado decimal para /. No SQLite e no PostgreSQL, torne um operando decimal antes de dividir: 7 / 2.0, 7 * 1.0 / 2 ou CAST(7 AS REAL) / 2 resulta em 3.5. CAST(7 / 2 AS REAL) chega tarde demais e resulta em 3.0.

Para uma alta de 80 para 92, (92 - 80) * 100.0 / 80 resulta em 15.0 por cento. Dividir primeiro a diferença inteira por 80 perde a fração. O módulo mantém a parte restante: 135 / 60 é 2 horas e 135 % 60 é 15 minutos. No SQLite e no PostgreSQL, -7 % 3 resulta em -1; o resto segue o sinal do operando à esquerda. Oracle usa MOD(17, 5) em vez de %.

Um divisor zero gera erro no PostgreSQL e no SQL Server; SQLite e MySQL retornam NULL. amount / NULLIF(divisor, 0) faz o caso de zero retornar NULL nesses sistemas.

Arredonde ou escolha um inteiro

ROUND(x, n) arredonda para n casas decimais. Uma luminária com preço de 24,00 e custo de 15,50 tem lucro 8.5. ROUND((price - cost) / price * 100, 1) resulta em uma margem de 35.4 por cento. PostgreSQL aceita uma quantidade negativa de casas: ROUND(1234.5678, -2) resulta em 1200; SQLite trata a quantidade de casas como zero e resulta em 1235.0.

FunçãoSignificadoExemplo
ABSDistância de zeroABS(-4.2) resulta em 4.2
CEILMenor inteiro que não é menor que o valorCEIL(4.1) resulta em 5
FLOORMaior inteiro que não é maior que o valorFLOOR(-4.1) resulta em -5
TRUNCRemove a fração em direção a zeroTRUNC(42.8) resulta em 42

PostgreSQL fornece essas funções. SQLite fornece ABS; CEIL, FLOOR e TRUNC exigem uma compilação com funções matemáticas, disponíveis a partir da versão 3.35.

Ajuste a precisão aos dados

ROUND do SQLite e ROUND para numeric do PostgreSQL arredondam valores exatamente na metade para longe de zero: ROUND(-2.5) resulta em -3. O arredondamento de ponto flutuante do PostgreSQL geralmente arredonda valores na metade para o inteiro par mais próximo; seu ROUND com dois argumentos exige numeric, então use ROUND(CAST(x AS numeric), 2) para uma coluna de precisão dupla.

Números de ponto flutuante aproximam muitas frações decimais. SQLite pode considerar 0.1 + 0.2 = 0.3 falso e fazer ROUND(2.675, 2) retornar 2.67. Os literais decimais do PostgreSQL usam numeric exato. Para valores monetários exatos, use NUMERIC/DECIMAL no PostgreSQL ou centavos armazenados como inteiros no SQLite. Declarar DECIMAL no SQLite não cria armazenamento decimal exato. Mantenha a precisão durante os cálculos e arredonde para exibição.

Principais conclusões

  • Parênteses controlam quais valores são combinados antes da multiplicação ou divisão.
  • Converta um operando antes da divisão inteira; converter o resultado não recupera os algarismos perdidos.
  • O módulo retorna um resto, como os minutos restantes após as horas completas.
  • ROUND, FLOOR, CEIL e TRUNC fazem escolhas diferentes para um valor fracionário.
  • O arredondamento de ponto flutuante e as funções numéricas disponíveis dependem do tipo e do banco de dados.
  • Use armazenamento numérico exato no PostgreSQL ou centavos armazenados como inteiros no SQLite para valores exatos.
  • NULLIF pode fazer um divisor zero produzir NULL em vez de um erro.

1.3 Converter valores entre tipos de dados

O tipo de dados de um valor afeta operações aritméticas, comparações e ordenação. O número 42 é diferente do texto '42', mesmo quando uma grade de resultados os exibe da mesma forma.

Converta um valor explicitamente

Tipos comuns incluem INTEGER para números inteiros, NUMERIC ou DECIMAL para decimais exatos no PostgreSQL, REAL ou double precision para números aproximados, TEXT ou VARCHAR para texto e DATE, TIME, TIMESTAMP e BOOLEAN quando disponíveis.

SELECT CAST('42' AS INTEGER) AS number_value,
       CAST(42 AS TEXT) AS text_value;

CAST(expression AS type) faz parte da SQL padrão. O primeiro resultado é um número; o segundo é texto. PostgreSQL também aceita '42'::integer. Converter NULL continua resultando em NULL.

Para divisão decimal no SQLite, escreva CAST(quantity AS REAL) / 4; no PostgreSQL, escreva CAST(quantity AS NUMERIC) / 4. Uma quantidade de 7 resulta em 1.75. CAST(7 AS NUMERIC) / 2 do SQLite ainda resulta em 3: NUMERIC deixa esse valor inteiro armazenado como inteiro. REAL é a conversão adequada no SQLite para esse fim.

Entenda o que uma conversão para inteiro faz
Entrada e conversãoSQLitePostgreSQL
CAST(3.9 AS INTEGER)34
CAST(-3.9 AS INTEGER)-3-4
CAST('abc' AS INTEGER)0Erro

SQLite remove uma fração em direção a zero. PostgreSQL arredonda um valor numérico para o inteiro mais próximo. Use ROUND, TRUNC, FLOOR ou CEIL primeiro quando a regra pretendida for importante. PostgreSQL rejeita texto que não é um número válido. SQLite lê uma parte numérica inicial: '12abc' torna-se 12 e '12.5' torna-se 12 quando convertido para INTEGER. Portanto, zero após uma conversão no SQLite não prova que o texto original era um zero válido. TRY_CAST do SQL Server retorna NULL quando uma conversão falha.

Separe quantidades de identificadores

Texto é ordenado caractere por caractere. As cadeias '9', '10' e '100' são ordenadas como '10', '100', '9'. Para ordenar quantidades realmente numéricas mantidas como texto, use ORDER BY CAST(code AS INTEGER) depois de verificar que são números válidos.

Um código postal dos Estados Unidos como '02134' é um identificador. Convertê-lo resulta em 2134 e perde o primeiro zero. Números de telefone também devem ser texto: seus algarismos identificam algo, em vez de descrever uma quantidade a ser somada ou usada em uma média.

Reconheça conversões automáticas

SQLite e PostgreSQL convertem o número em texto em 'Order #' || 42, produzindo 'Order #42'. Ambos também avaliam o literal entre aspas em '5' + 3 como número. No PostgreSQL, esse literal tem inicialmente um tipo ainda não definido; uma coluna TEXT não tem a mesma flexibilidade. Adicionar 3 a uma coluna TEXT falha, então converta a coluna explicitamente.

SQLite dá às colunas uma preferência de tipo, chamada afinidade de tipo, e pode manter diferentes tipos de valores em uma coluna comum. typeof(42), typeof(4.2), typeof('42') e typeof(NULL) informam 'integer', 'real', 'text' e 'null'. SQLite não tem um tipo DATE específico: CAST('2026-03-14' AS DATE) resulta em 2026. Use date('2026-03-14') para suas funções de data.

Oracle fornece TO_NUMBER, TO_CHAR e TO_DATE. TO_CHAR e TO_DATE do PostgreSQL recebem máscaras de formatação como 'MM/DD/YYYY'. CONVERT do SQL Server usa um código numérico de estilo: CONVERT(date, '03/14/2026', 101) lê o formato de data dos Estados Unidos.

Principais conclusões

  • CAST altera explicitamente um valor para o tipo solicitado; NULL permanece NULL.
  • SQLite trunca conversões de números para inteiros, enquanto PostgreSQL as arredonda.
  • SQLite pode transformar texto numérico inválido em um número parcial ou zero.
  • Mantenha códigos postais dos Estados Unidos e números de telefone como texto para preservar sua identidade.
  • A ordenação de texto e a ordenação numérica podem produzir ordens diferentes.
2

Tratar valores ausentes com a lógica de NULL e COALESCE

Um valor ausente pode alterar um cálculo e também mudar quais linhas um filtro mantém. Entender NULL significa acompanhar tanto os dados quanto a condição que os usa. Você distinguirá ausência de zero e de texto vazio, acompanhará TRUE, FALSE e UNKNOWN em uma consulta e escolherá valores alternativos que preservem o significado de um relatório. COALESCE e NULLIF permitem preencher lacunas ou criá-las deliberadamente.

2.1 Prever o comportamento de NULL em cálculos e condições

NULL indica um valor ausente ou desconhecido. Uma célula de resultado em branco pode exibir NULL, mas NULL não é um valor comum que você compara com =.

Acompanhe uma entrada ausente em uma expressão

Zero é um número conhecido. Texto vazio, '', é uma cadeia conhecida sem caracteres. O texto 'N/A' é um rótulo registrado. NULL indica que nenhum valor está disponível. Oracle trata texto vazio como NULL; SQLite e PostgreSQL os distinguem.

A maioria das operações aritméticas e funções propaga uma entrada ausente como NULL. Com salário de 50.000 e bônus NULL, salary + bonus resulta em NULL. O total é desconhecido porque o bônus é desconhecido. UPPER(NULL), ROUND(NULL, 2) e 'Ana ' || NULL também retornam NULL no SQLite e no PostgreSQL.

Teste NULL diretamente

bonus = NULL, bonus <> NULL e até NULL = NULL produzem UNKNOWN. Não se sabe se dois valores ausentes são iguais. Use bonus IS NULL ou bonus IS NOT NULL. Esses testes sempre retornam TRUE ou FALSE.

Condições SQL têm três resultados possíveis: TRUE, FALSE e UNKNOWN. SQLite exibe TRUE como 1, FALSE como 0 e UNKNOWN como NULL.

CondiçãoResultadoMotivo
FALSE AND UNKNOWNFALSEUm requisito falso torna AND falso
TRUE AND UNKNOWNUNKNOWNO segundo requisito permanece indefinido
TRUE OR UNKNOWNTRUEUma alternativa verdadeira torna OR verdadeiro
FALSE OR UNKNOWNUNKNOWNA alternativa restante permanece indefinida
NOT UNKNOWNUNKNOWNNegar um valor desconhecido não o esclarece
Entenda quais linhas WHERE mantém

WHERE mantém apenas TRUE. FALSE e UNKNOWN excluem a linha. Para bônus de 1000, 0, NULL, 2500 e NULL, WHERE bonus < 1000 mantém apenas o zero. WHERE bonus >= 1000 mantém 1000 e 2500. Esses filtros abrangem três linhas, não cinco. WHERE NOT (bonus < 1000) também mantém apenas os dois bônus conhecidos de pelo menos 1000.

O mesmo problema afeta <>. Com as cidades Boston, Denver, NULL, Boston e Austin, WHERE city <> 'Boston' mantém Denver e Austin. Inclua explicitamente a cidade desconhecida:

WHERE city <> 'Boston' OR city IS NULL

Isso mantém três linhas. NOT não traz automaticamente de volta os valores ausentes.

Observe listas e comparações

3 IN (1, 2, NULL) é UNKNOWN: o elemento ausente pode ser 3. Para x NOT IN (1, 2, NULL), um valor correspondente não passa em NOT IN e qualquer valor sem correspondência resulta em UNKNOWN. Em uma cláusula WHERE, essa lista fixa não mantém nenhuma linha. Remova um NULL não intencional de uma lista de exclusão antes de usá-la.

Para uma igualdade que trata dois valores NULL como iguais, use a IS NOT DISTINCT FROM b. Seu oposto, a IS DISTINCT FROM b, é TRUE quando um valor é NULL e o outro não; dois valores NULL não são distintos. PostgreSQL e SQLite a partir da versão 3.39 aceitam essas formas. SQLite também tem IS e IS NOT; MySQL escreve a igualdade segura com NULL como <=>.

Os padrões de ordenação de NULL diferem: SQLite coloca NULL primeiro em ordem crescente; PostgreSQL o coloca por último. Declare a posição quando ela for importante: ORDER BY bonus DESC NULLS LAST coloca bônus conhecidos em ordem decrescente e bônus ausentes no fim.

Principais conclusões

  • NULL é ausente ou desconhecido, não zero ou texto vazio.
  • Comparações com NULL produzem UNKNOWN; teste a ausência com IS NULL.
  • WHERE mantém apenas TRUE, então NOT e <> não recuperam linhas com resultado desconhecido.
  • AND e OR só podem resolver um valor desconhecido quando a outra condição determina o resultado.
  • Um NULL em uma lista NOT IN impede que essa condição seja TRUE.
  • IS NOT DISTINCT FROM trata dois valores NULL como iguais.
  • NULLS FIRST ou NULLS LAST torna a ordenação explícita.

2.2 Substituir e gerar valores ausentes com COALESCE e NULLIF

Às vezes, valores ausentes precisam de um valor alternativo e, às vezes, devem continuar ausentes. Essa escolha faz parte do significado de um relatório. COALESCE preenche uma lacuna; NULLIF transforma um valor marcador correspondente em uma lacuna.

Escolha o primeiro valor disponível

COALESCE(a, b, ...) verifica da esquerda para a direita e retorna o primeiro argumento que não é NULL. Ela retorna NULL se todos os argumentos forem NULL.

SELECT COALESCE(mobile_phone, home_phone, 'no phone') AS contact
FROM customers;

Sem número de celular e com telefone residencial '555-0100', o contato é '555-0100'. Se nenhum dos números estiver registrado, é 'no phone'. Um zero conhecido ou uma cadeia vazia conta como disponível: COALESCE ignora NULL, não valores que parecem vazios ou falsos.

Para remuneração, salary + COALESCE(bonus, 0) resulta em 50.000 quando o salário é 50.000 e o bônus é NULL. Isso é adequado quando um bônus ausente significa que nenhum foi pago. Uma avaliação de produto ausente não significa uma avaliação zero; substituí-la inventaria uma avaliação ruim. Deixe esse número ausente ou crie um rótulo de texto para exibição.

Mantenha os tipos dos valores alternativos compatíveis

PostgreSQL não consegue combinar o inteiro rating com o texto 'not rated' em um único resultado numérico. Converta primeiro as avaliações conhecidas em texto:

COALESCE(CAST(rating AS TEXT), 'not rated')

Uma avaliação de 4 é exibida como o texto '4'; um NULL é exibido como 'not rated'. SQLite aceita uma mistura de argumentos numéricos e de texto, mas a saída pode conter tipos diferentes. Deixe claro o tipo de resultado pretendido ao transferir uma consulta entre bancos de dados.

COALESCE faz parte da SQL padrão e aceita dois ou mais argumentos. As alternativas comuns com dois argumentos são IFNULL no SQLite e no MySQL, ISNULL no SQL Server e NVL no Oracle.

Transforme um valor marcador em NULL

NULLIF(a, b) retorna NULL se os argumentos forem iguais; caso contrário, retorna o primeiro argumento. NULLIF(0, 0) é NULL, enquanto NULLIF(5, 0) é 5.

Uma expressão útil para uma taxa é:

orders * 100.0 / NULLIF(visits, 0) AS conversion_pct

Com 12 pedidos e 300 visitas, o divisor permanece 300 e a taxa é 4.0. Com zero visitas, o divisor torna-se NULL e a taxa torna-se NULL. PostgreSQL evita um erro de divisão por zero, e o resultado indica corretamente uma taxa indefinida. Substituir essa taxa por zero faria uma afirmação diferente.

Limpe lacunas antes de fornecer um rótulo
COALESCE(NULLIF(phone, ''), 'unknown')

O NULLIF interno transforma uma cadeia vazia em NULL. O COALESCE externo então atribui o rótulo 'unknown' tanto a um NULL original quanto a uma cadeia vazia. Um número de telefone registrado passa sem alterações.

Para um nome do meio opcional, inclua seu espaço final dentro do valor alternativo:

first_name || ' ' || COALESCE(middle_name || ' ', '') || last_name

Um nome do meio NULL não acrescenta nada, produzindo 'Ana Lopez'. Um nome do meio igual a 'Maria' acrescenta 'Maria ', produzindo 'Ana Maria Lopez'.

Essas expressões alteram apenas o resultado da consulta. Elas deixam os valores originais armazenados na tabela. Um filtro como WHERE COALESCE(bonus, 0) = 0 agrupa bônus conhecidos de valor zero e bônus ausentes, então use-o quando esses forem os dois grupos desejados.

Principais conclusões

  • COALESCE retorna o primeiro argumento que não é NULL, incluindo um zero conhecido ou texto vazio.
  • Um valor alternativo deve expressar o significado dos dados ausentes e ter um tipo compatível.
  • NULLIF retorna NULL quando há igualdade e, caso contrário, retorna seu primeiro argumento.
  • Use NULLIF em torno de um divisor para que um denominador zero retorne NULL.
  • Limpe um valor marcador com NULLIF antes de aplicar um valor alternativo de exibição com COALESCE.
3

Limpar, combinar e decompor textos com funções de cadeia de caracteres

O texto de uma tabela muitas vezes precisa de uma forma utilizável: um nome completo, um endereço de e-mail consistente ou parte de um código. A SQL pode concatenar e limpar cadeias de caracteres, contar seus caracteres e extrair a parte anterior ou posterior a um separador. Você acompanhará as posições dos caracteres em cada etapa e verificará como espaços, letras maiúsculas e minúsculas e NULL afetam o resultado. SQLite e PostgreSQL compartilham muitas funções, mas diferem em vários nomes e comportamentos.

3.1 Concatenar e limpar valores de texto

A SQL trata um valor de texto como uma cadeia de caracteres. Funções de texto podem construir um nome completo ou organizar um endereço de e-mail para comparação. Seus resultados aparecem na consulta; o texto armazenado permanece inalterado.

Escreva e concatene texto

Literais de texto usam aspas simples. Para incluir um apóstrofo, duplique-o: 'O''Brien' representa “O'Brien”. Um par de aspas simples, '', é texto vazio.

SELECT first_name || ' ' || last_name AS full_name
FROM customers;

O operador de concatenação || junta as partes exatamente como foram escritas. Com 'Ana' e 'Lopez', o resultado é 'Ana Lopez'. O literal do meio fornece o espaço; a concatenação não insere um automaticamente.

SQLite, PostgreSQL e Oracle usam ||. O || padrão do MySQL significa OR, então use CONCAT nele. SQL Server usa + e também aceita || a partir de 2025. Para concatenar um identificador numérico de pedido, SQLite e PostgreSQL o convertem em texto em 'Order #' || order_id. Com + do SQL Server, converta o número primeiro: 'Order #' + CAST(order_id AS VARCHAR(10)).

Escolha como concatenar uma parte ausente

No SQLite e no PostgreSQL, um operando NULL torna o resultado de || NULL. Oracle trata essa parte ausente como texto vazio. CONCAT também varia conforme o banco de dados:

Banco de dadosCONCAT('Ana', NULL, 'Lopez')
PostgreSQL, SQL Server, SQLite a partir da versão 3.44'AnaLopez'
MySQLNULL

CONCAT do Oracle recebe exatamente dois argumentos. CONCAT_WS(' ', first_name, middle_name, last_name) coloca espaços entre as partes que não são NULL, então um nome do meio ausente resulta em 'Ana Lopez'. SQLite adicionou CONCAT e CONCAT_WS na versão 3.44. Ignorar NULL não remove uma cadeia vazia.

Converta maiúsculas e minúsculas e remova espaços das extremidades

UPPER('boston') resulta em 'BOSTON'; LOWER produz letras minúsculas. INITCAP('ana LOPEZ') do PostgreSQL resulta em 'Ana Lopez'. SQLite não tem INITCAP, e sua conversão integrada altera apenas as letras de A a Z: UPPER('é') permanece 'é' sem a extensão ICU. A conversão de maiúsculas e minúsculas do PostgreSQL segue sua configuração regional.

TRIM remove espaços nas duas extremidades; LTRIM os remove apenas no início e RTRIM apenas no fim. TRIM(' New York ') resulta em 'New York', mantendo os dois espaços internos. Para remover x das duas extremidades, SQLite usa TRIM('xxBostonxx', 'x'); PostgreSQL usa TRIM(BOTH 'x' FROM 'xxBostonxx').

Substitua caracteres e aninhe etapas de limpeza

REPLACE('555-0100', '-', '') resulta em '5550100'. Ela substitui cada ocorrência exata. Maiúsculas e minúsculas fazem diferença: substituir 'st' em 'Main St' não altera nada porque 'St' tem um S maiúsculo.

SELECT LOWER(TRIM(email)) AS email_clean
FROM customers;

Para ' Ana@Example.COM ', TRIM primeiro produz 'Ana@Example.COM', depois LOWER produz 'ana@example.com'. Aninhamento significa que a função mais interna fornece a entrada da próxima.

A igualdade comum de texto diferencia maiúsculas de minúsculas por padrão no SQLite e no PostgreSQL. WHERE LOWER(TRIM(email)) = 'ana@example.com' pode encontrar correspondências em entradas com diferentes usos de maiúsculas e minúsculas e com espaços nas extremidades. A colação padrão do MySQL ignora essa diferença, e LIKE do SQLite ignora a diferença entre maiúsculas e minúsculas de A a Z, embora sua comparação padrão com = não o faça.

Principais conclusões

  • Use aspas simples para texto e duplique um apóstrofo dentro de um literal.
  • A concatenação junta partes exatas; inclua separadores explicitamente.
  • O comportamento de NULL varia entre ||, CONCAT e dialetos de bancos de dados.
  • TRIM remove espaços nas extremidades, enquanto REPLACE altera os caracteres correspondentes em todo o texto.
  • Funções aninhadas são executadas de dentro para fora.
  • A conversão entre maiúsculas e minúsculas e a distinção entre elas nas correspondências dependem do banco de dados e da configuração regional.

3.2 Medir o comprimento e extrair partes de textos

Funções de texto localizam e recortam partes pela posição dos caracteres. A SQL começa as posições em 1, então o primeiro caractere está na posição 1. Uma posição encontrada e uma quantidade de caracteres são entradas diferentes.

Meça e recorte uma cadeia de caracteres

LENGTH('Boston') resulta em 6. Espaços contam: LENGTH(' Bo ') resulta em 4. Texto vazio tem comprimento 0; LENGTH(NULL) é NULL. LENGTH do MySQL conta bytes, então use CHAR_LENGTH para caracteres nesse sistema. SQL Server usa LEN, que ignora espaços no final.

SELECT SUBSTR('Boston', 1, 3) AS beginning,
       SUBSTR('Boston', 4) AS ending;

Os resultados são 'Bos' e 'ton'. A primeira chamada extrai três caracteres a partir da posição 1. A segunda omite a quantidade e extrai tudo a partir da posição 4. PostgreSQL também usa SUBSTRING('Boston' FROM 4 FOR 3). SQLite aceita SUBSTRING como nome a partir da versão 3.34. SQL Server usa SUBSTRING(text, start, count); a quantidade é obrigatória até a versão 2022 e opcional a partir da versão 2025.

SQLite pode contar a partir da direita: SUBSTR('Boston', -3) resulta em 'ton'. Posições iniciais negativas no PostgreSQL não contam de trás para a frente a partir do fim. Use RIGHT('Boston', 3) nesse sistema; LEFT extrai caracteres do início. SQLite não tem LEFT nem RIGHT.

Encontre o ponto de divisão

INSTR(text, search) do SQLite retorna a primeira posição correspondente. PostgreSQL usa STRPOS ou POSITION(search IN text). Essas funções retornam 0 quando não encontram correspondência. A busca diferencia maiúsculas de minúsculas: INSTR('Ana', 'a') é 3.

Em 'ana@example.com', o @ está na posição 4. O nome de usuário termina logo antes dele; o domínio começa logo depois:

SUBSTR(email, 1, INSTR(email, '@') - 1) AS user_name,
SUBSTR(email, INSTR(email, '@') + 1) AS domain

A primeira expressão torna-se SUBSTR(email, 1, 3) e produz 'ana'. A segunda começa na posição 5 e produz 'example.com'. Omitir - 1 inclui @ no nome de usuário. Omitir + 1 o inclui no início do domínio. No PostgreSQL, substitua INSTR por STRPOS ou use SPLIT_PART(email, '@', 2) para o domínio.

Trate um separador ausente

Para 'anaexample.com', INSTR retorna 0. A fórmula do domínio começa na posição 1 e retorna toda a cadeia, produzindo um resultado enganoso. A fórmula do nome de usuário no SQLite resulta em texto vazio; PostgreSQL rejeita seu comprimento negativo de subcadeia. Proteja a extração:

CASE
  WHEN INSTR(email, '@') > 0
  THEN SUBSTR(email, INSTR(email, '@') + 1)
END

Isso retorna NULL quando o separador está ausente. A verificação procura um separador, não todas as regras de um endereço de e-mail válido.

Crie rótulos curtos e códigos de largura fixa

SUBSTR(first_name, 1, 1) || '. ' || last_name resulta em 'A. Lopez' para Ana Lopez. WHERE LENGTH(zip_code) <> 5 encontra cadeias de códigos postais dos Estados Unidos registradas com comprimento incorreto; comprimentos NULL produzem UNKNOWN e são excluídos.

LPAD('42', 5, '0') do PostgreSQL resulta em '00042'; RPAD preenche à direita. SQLite pode construir esse código com SUBSTR('00000' || 42, -5). Manter apenas cinco caracteres também corta um valor mais longo, então essa expressão de largura fixa precisa de um código que caiba nela.

Principais conclusões

  • As posições em cadeias de caracteres SQL começam em 1; LENGTH inclui espaços.
  • SUBSTR recebe uma posição inicial e uma quantidade opcional de caracteres.
  • INSTR, STRPOS e POSITION retornam 0 quando não há correspondência.
  • Use a posição menos 1 antes de um separador e a posição mais 1 depois dele.
  • Verifique se o separador está ausente antes de extrair uma parte.
  • A extração a partir do fim e o preenchimento usam nomes diferentes no SQLite e no PostgreSQL.
4

Trabalhar com datas e horas

O trabalho com datas começa com uma distinção clara entre um dia do calendário, uma hora e um timestamp. A partir daí, a SQL pode criar rótulos de mês, calcular prazos, medir o tempo decorrido e filtrar um período completo. Você manterá valores de data separados do texto de exibição, levará em conta fins de mês e aniversários e comparará as expressões de SQLite e PostgreSQL que realizam a mesma tarefa. Casos de fronteira tornam esses cálculos confiáveis.

4.1 Escrever, armazenar e ler valores de data e hora

É mais fácil calcular com uma data quando seu armazenamento e sua forma de escrita são claros. O texto '03/04/2026' pode significar 4 de março ou 3 de abril. Uma data ISO, '2026-03-14', coloca ano, mês e dia em uma ordem sem ambiguidade.

Associe o valor ao seu tipo

PostgreSQL tem DATE para um dia do calendário, TIME para uma hora do dia e TIMESTAMP para uma data e hora. Seu TIMESTAMP WITH TIME ZONE, também chamado timestamptz, armazena um instante em UTC e o exibe no fuso horário da sessão. Um TIMESTAMP simples não associa esse significado de fuso.

SQLite armazena datas e horas como texto ISO ou como números, sem tipos específicos de data e hora. As formas numéricas incluem números de dias julianos e tempo Unix. As funções de data interpretam esses valores e retornam uma data, uma hora ou uma medida numérica.

Use texto ISO de largura fixa, como '2026-03-14', incluindo zeros iniciais. Adicione uma hora usando o formato de 24 horas: '2026-03-14 09:30:00'. O literal tipado DATE '2026-03-14' do PostgreSQL cria explicitamente uma data.

Preserve a ordem cronológica

Texto ISO de largura fixa é comparado em ordem de data porque começa pela maior parte. '2026-03-14' vem antes de '2026-11-02'. Texto de exibição no formato dos Estados Unidos não tem essa propriedade: como cadeias de caracteres, '11/02/2025' é ordenado depois de '03/14/2026', embora sua data seja anterior.

O interpretador do SQLite precisa do formato aceito. date('2026-3-14') retorna NULL porque o mês não tem dois algarismos. Ele também pode normalizar uma data impossível: date('2026-02-30') retorna '2026-03-02'. Um resultado diferente de NULL, por si só, não prova que a entrada era um dia válido do calendário. PostgreSQL rejeita DATE '2026-02-30'.

Leia texto em outro formato

PostgreSQL e Oracle usam TO_DATE('03/14/2026', 'MM/DD/YYYY') para ler o formato dos Estados Unidos. PostgreSQL também lê texto ISO com CAST('2026-03-14' AS DATE) ou '2026-03-14'::date.

SQLite não tem um interpretador TO_DATE. Para texto em d no formato fixo MM/DD/YYYY, reconstrua o texto ISO:

SUBSTR(d, 7, 4) || '-' ||
SUBSTR(d, 1, 2) || '-' || SUBSTR(d, 4, 2)

As partes são o ano '2026', o mês '03' e o dia '14'. O resultado é '2026-03-14', que as funções de data do SQLite podem ler. As posições dependem de a entrada realmente usar o formato fixo.

Obtenha a data e a hora atuais

CURRENT_DATE e CURRENT_TIMESTAMP funcionam no SQLite e no PostgreSQL. SQLite retorna texto em UTC; date('now', 'localtime') fornece a data local. Perto da meia-noite, a data do calendário em UTC e a local podem ser diferentes.

PostgreSQL usa o fuso horário da sessão. CURRENT_TIMESTAMP e NOW() refletem o início da transação atual, então esperar dentro dessa transação não faz seus valores avançarem. MySQL oferece NOW() e CURDATE(); SQL Server tem GETDATE() e SYSDATETIME(); Oracle tem SYSDATE, que inclui uma hora, e CURRENT_DATE.

Para verificar um cálculo de vencimento, use primeiro uma data fixa de referência, como DATE '2026-10-21' no PostgreSQL ou '2026-10-21' no SQLite. Assim, você pode comparar o resultado com um calendário sem que a resposta mude no dia seguinte.

Principais conclusões

  • DATE é um dia do calendário; TIMESTAMP acrescenta uma hora do dia.
  • Use YYYY-MM-DD de largura fixa para texto de data portátil e sem ambiguidade.
  • Texto ISO é ordenado cronologicamente quando seu formato e sua referência de tempo são consistentes.
  • Um resultado de data no SQLite pode normalizar uma entrada impossível em vez de rejeitá-la.
  • Funções de data atual usam regras diferentes de fuso horário e transação.

4.2 Extrair e formatar partes de datas

Extraia uma parte de uma data quando precisar de um ano ou dia da semana para calcular. Formate uma data quando precisar de texto para um leitor. Essas operações podem produzir tipos diferentes mesmo quando os caracteres exibidos parecem iguais.

Extraia um ano, mês ou dia da semana

PostgreSQL usa a forma padrão EXTRACT(part FROM value). Para DATE '2026-03-14', extrair YEAR resulta em 2026 e MONTH resulta em 3, ambos como números. MySQL e Oracle também aceitam EXTRACT.

SQLite usa strftime(format, value), que retorna texto:

Máscara do SQLiteResultado para '2026-03-14'
'%Y''2026'
'%m''03'
'%d''14'
'%w''6'

%w do SQLite e DOW do PostgreSQL numeram os dias de domingo como 0 até sábado como 6. 14 de março de 2026 é sábado. Já ISODOW do PostgreSQL numera os dias de segunda-feira como 1 até domingo como 7. Um filtro de fim de semana no SQLite é WHERE strftime('%w', order_date) IN ('0', '6').

Compare os tipos corretos

strftime('%m', order_date) = 3 é falso para uma data de março no SQLite: a função retorna o texto '03', não o número 3. Compare-o com = '03' ou converta primeiro:

CAST(strftime('%m', order_date) AS INTEGER) = 3

Isso também é útil na expressão de trimestre (CAST(strftime('%m', d) AS INTEGER) + 2) / 3. A divisão inteira resulta no trimestre 1 para março e no trimestre 4 para novembro. PostgreSQL tem EXTRACT(QUARTER FROM d) diretamente.

Identifique um mês como um período completo

strftime('%Y-%m', order_date) cria um rótulo no SQLite como '2026-03'. date(order_date, 'start of month') cria '2026-03-01'. PostgreSQL pode usar TO_CHAR(order_date, 'YYYY-MM') para um rótulo ou DATE_TRUNC('month', order_date) para o primeiro instante desse mês.

Mantenha o ano em um rótulo de período. Um valor de mês isolado igual a 3 combinaria marços de anos diferentes. O valor do primeiro dia do mês pode continuar sendo usado para cálculo e ordenação, enquanto uma expressão separada fornece a exibição.

Formate na etapa de saída

No PostgreSQL, TO_CHAR(DATE '2026-03-14', 'MM/DD/YYYY') resulta em '03/14/2026', e a máscara 'Mon DD, YYYY' resulta em 'Mar 14, 2026'. Oracle também usa essas máscaras. O formato dos Estados Unidos no SQLite é strftime('%m/%d/%Y', '2026-03-14').

As letras das máscaras dependem do banco de dados. MM no PostgreSQL significa mês e MI significa minuto. %m no SQLite significa mês e %M significa minuto; mudar a letra maiúscula altera a informação solicitada.

SELECT TO_CHAR(order_date, 'MM/DD/YYYY') AS order_day
FROM orders
ORDER BY order_date;

Aqui PostgreSQL exibe texto legível, mas ordena as datas reais. Ordenar por order_day ordenaria as cadeias de exibição primeiro pelo mês e poderia colocar datas de anos diferentes fora de ordem.

Principais conclusões

  • EXTRACT do PostgreSQL retorna partes numéricas; strftime do SQLite retorna texto.
  • Compare um mês do SQLite com zero inicial com texto ou converta-o em número.
  • A numeração dos dias da semana depende da convenção solicitada.
  • Mantenha o ano nos rótulos de mês e formate apenas para exibição.

4.3 Calcular com datas e filtrar intervalos de datas

Cálculos com o calendário devem levar em conta a duração dos meses, os componentes de hora e o tipo de resposta necessário. Uma quantidade de dias, um mês do calendário e um ano completo de idade são medidas diferentes.

Adicione dias e meses do calendário

PostgreSQL usa DATE '2026-03-14' + 30; SQLite usa date('2026-03-14', '+30 days'). Ambos chegam a 13 de abril: 17 dias completam março e outros 13 chegam a 13 de abril. Já a expressão direta do SQLite '2026-03-14' + 30 resulta em 2056, pois a operação aritmética lê o ano inicial como número.

Fins de mês exigem uma regra explícita. DATE '2026-01-31' + INTERVAL '1 month' do PostgreSQL resulta em 28 de fevereiro à meia-noite, usando o último dia disponível. date('2026-01-31', '+1 month') do SQLite transfere os dias excedentes para março e resulta em '2026-03-03'. A partir do SQLite 3.46, adicione 'floor' após o deslocamento para escolher '2026-02-28'. ADD_MONTHS do Oracle também passa para o último dia do mês mais curto.

Meça o tempo decorrido

A subtração de valores DATE no PostgreSQL retorna dias completos: DATE '2026-04-13' - DATE '2026-03-14' é 30. SQLite subtrai valores numéricos de dias: julianday('2026-04-13') - julianday('2026-03-14') é 30.0. SQL Server usa DATEDIFF(day, start, end); MySQL usa DATEDIFF(end, start).

Para timestamps de 14 de março das 09:30 às 18:00, a subtração no PostgreSQL resulta em um intervalo de 08:30:00; EXTRACT(EPOCH FROM interval) / 3600 o expressa como 8,5 horas. SQLite a partir da versão 3.38 pode usar:

(unixepoch('2026-03-14 18:00') -
 unixepoch('2026-03-14 09:30')) / 3600.0

Isso resulta em 8.5. Uma diferença de dias julianos multiplicada por 24 pode resultar em 8.49999999627471 devido à aproximação de ponto flutuante; arredonde para exibição. Uma duração fracionária entre timestamps não deve ser convertida para INTEGER antes de calcular a unidade desejada.

Conte aniversários completos

Uma pessoa nascida em 2 de novembro de 1990 tem 35 anos em 21 de outubro de 2026. Os números dos anos diferem em 36, mas o aniversário ainda não chegou. PostgreSQL usa EXTRACT(YEAR FROM AGE(DATE '2026-10-21', DATE '1990-11-02')), resultando em 35.

SQLite subtrai um se o aniversário deste ano ainda estiver por vir:

strftime('%Y', '2026-10-21') - strftime('%Y', birth_date)
- (strftime('%m-%d', '2026-10-21') < strftime('%m-%d', birth_date))

A comparação produz 1 quando o aniversário ainda está por vir e 0 caso contrário. Dividir os dias decorridos por 365 não é confiável: em 1º de novembro de 2026, essa pessoa viveu 13.148 dias, que divididos por 365 resultam em 36,02, embora o 36º aniversário seja amanhã. DATEDIFF do SQL Server conta fronteiras: passar de 31 de dezembro para 1º de janeiro conta como uma fronteira de ano, não como um ano completo de idade.

Inclua todos os timestamps de um período

BETWEEN inclui ambos os extremos. Para colunas DATE, de 1º a 31 de março abrange março. Para timestamps, um limite superior de '2026-03-31' significa meia-noite no início do último dia e deixa o restante dele de fora.

WHERE ordered_at >= '2026-03-01'
  AND ordered_at < '2026-04-01'

Esse intervalo fechado à esquerda e aberto à direita inclui o início e exclui o início do próximo período, abrangendo todos os horários de março sem escolher uma fração final de segundo.

Datas vencidas satisfazem due_date < CURRENT_DATE. O limite inferior para os últimos 30 dias no PostgreSQL é CURRENT_DATE - 30; no SQLite é date('now', '-30 days'). Os dias até um prazo são dados por due_date - CURRENT_DATE para valores DATE no PostgreSQL e por julianday(due_date) - julianday(date('now')) no SQLite.

Principais conclusões

  • Use funções de cálculo com datas ou datas tipadas, não operações aritméticas sobre texto de data no SQLite.
  • Decida como a adição de um mês deve tratar um dia que não existe no mês seguinte.
  • Diferenças entre valores DATE contam dias; diferenças entre timestamps podem incluir frações.
  • A idade conta aniversários completos, não os dias decorridos divididos por 365.
  • Um intervalo de timestamps fechado à esquerda e aberto à direita inclui o início do período e exclui o início do próximo.
  • Use um valor atual apenas de data para calcular prazos em dias completos.
5

Classificar linhas com expressões CASE

Um relatório muitas vezes precisa de uma regra que transforme dados em um rótulo ou uma taxa: um pedido pequeno, um envio pendente ou uma prioridade. CASE expressa essa escolha dentro de uma consulta. Você acompanhará qual condição prevalece, colocará valores exatos de fronteira e valores ausentes na categoria correta e traduzirá códigos com CASE simples. O relatório final combina classificação com operações aritméticas, texto, datas e valores alternativos, conferindo cada saída com linhas conhecidas.

5.1 Classificar linhas em categorias com CASE pesquisado

Uma expressão CASE escolhe um resultado para cada linha. Você pode usá-la para atribuir um rótulo a uma faixa de preço, calcular uma taxa ou marcar um registro que exige atenção.

Leia a forma pesquisada
CASE
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END AS size_band

Cada WHEN fornece uma condição, e THEN fornece o valor a retornar se essa condição for TRUE. O banco de dados verifica de cima para baixo e escolhe a primeira condição verdadeira. END fecha a expressão; um apelido pode vir depois. Se nenhuma condição for TRUE e ELSE estiver ausente, o resultado é NULL.

Um total de 35 atende à primeira condição e recebe 'small'. Um total de 50 não passa na primeira, mas atende à segunda, recebendo 'medium'. O mesmo acontece com 199,99. Um total de 200 chega ao ELSE e recebe 'large'.

Faça a ordem e as fronteiras corresponderem à regra

O segundo ramo não precisa de total >= 50: um valor abaixo de 50 já retornou do primeiro ramo. Limites crescentes com < funcionam porque os ramos anteriores removem os valores menores. Limites decrescentes com >= podem funcionar pelo mesmo motivo.

Colocar WHEN total < 200 primeiro torna um ramo posterior < 50 inalcançável. Um total de 35 já satisfaz < 200, então para nesse ponto. CASE não escolhe a condição mais específica nem verifica qual rótulo parece melhor.

Compare a regra de negócio com cada extremo. < 50 coloca exatamente 50 na faixa média; <= 50 o coloca na faixa pequena. Verifique 49,99, 50, 199,99 e 200 para observar os dois lados e as fronteiras. Se as condições forem escritas como intervalos explícitos, ajuste seus extremos sem deixar lacunas ou sobreposições indesejadas.

Trate NULL antes dos intervalos comuns

Um total NULL torna ambas as comparações UNKNOWN. Na primeira expressão, ele chega ao ELSE e recebe 'large', o que é enganoso. Capture a ausência primeiro:

CASE
  WHEN total IS NULL THEN 'unknown'
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END

ELSE significa “nenhuma condição foi verdadeira”, então pode capturar entradas ausentes e também valores conhecidos fora dos intervalos testados.

Retorne um tipo consistente de valor

PostgreSQL precisa de tipos compatíveis em THEN e ELSE. CASE WHEN quantity > 0 THEN unit_price ELSE 'n/a' END falha se unit_price for numérico, pois 'n/a' não pode se tornar um número. Use NULL para um resultado numérico indisponível ou converta o preço em texto se toda a saída for um rótulo de exibição. SQLite permite tipos de resultado mistos, o que pode complicar cálculos posteriores.

Uma condição pode combinar colunas:

CASE
  WHEN country = 'US' AND subtotal >= 100 THEN 0
  ELSE 7.99
END AS shipping_fee

A taxa retornada pode aparecer dentro de subtotal + CASE ... END AS amount_due. Um CASE é uma expressão de valor, não um comando que edita várias colunas; cada coluna de resultado precisa de sua própria expressão.

CASE também pode proteger uma divisão em cada linha: CASE WHEN visits = 0 THEN NULL ELSE orders * 100.0 / visits END. Uma linha com zero seleciona o ramo NULL. orders * 100.0 / NULLIF(visits, 0) expressa a mesma regra para uma taxa ausente de forma mais breve.

Principais conclusões

  • CASE retorna o valor da primeira condição que for TRUE.
  • Ordene condições de intervalo sobrepostas para que um teste amplo não esconda um mais restrito.
  • Escolha < ou <= para colocar uma fronteira exata na faixa pretendida.
  • Teste NULL explicitamente antes de um intervalo quando ELSE não deve atribuir-lhe um rótulo.
  • Mantenha os tipos de resultado compatíveis e use CASE onde uma expressão de valor for permitida.

5.2 Usar CASE simples e aplicar CASE em diferentes partes de uma consulta

A forma CASE simples traduz um valor em outro. CASE pesquisado testa condições; CASE simples compara a mesma expressão com uma série de valores.

Traduza códigos com CASE simples
CASE status
  WHEN 'S' THEN 'Shipped'
  WHEN 'P' THEN 'Pending'
  WHEN 'C' THEN 'Canceled'
  ELSE 'Other'
END AS status_label

Os testes implícitos são status = 'S', depois status = 'P' e depois status = 'C'. Um status fora desses códigos recebe 'Other'. A forma pesquisada pode escrever os mesmos testes de igualdade explicitamente. Escolha CASE pesquisado para intervalos, padrões LIKE, testes de NULL ou condições envolvendo várias colunas.

CASE region WHEN NULL THEN 'missing' ELSE region END não consegue capturar uma região NULL. Seu region = NULL implícito é UNKNOWN, então a linha chega ao ELSE e permanece NULL. Escreva CASE WHEN region IS NULL THEN 'missing' ELSE region END.

Atribua uma prioridade de ordenação personalizada

A ordem alfabética das prioridades é high, low, medium. Para ordenar por urgência, traduza os rótulos em números:

SELECT ticket_id, priority
FROM tickets
ORDER BY CASE priority
           WHEN 'high' THEN 1
           WHEN 'medium' THEN 2
           WHEN 'low' THEN 3
           ELSE 4
         END;

A ordem crescente agora coloca high antes de medium e medium antes de low, com outros valores ou valores ausentes por último. O CASE é uma expressão de ordenação; ele não precisa ser uma coluna exibida. Usar DESC inverteria a classificação numérica.

Crie um indicador numérico
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END AS is_discounted

Um percentual positivo recebe 1; um zero conhecido recebe 0. Um percentual NULL também recebe 0 porque > 0 é UNKNOWN e ELSE o captura. Portanto, esse indicador significa “há um desconto positivo registrado”. Ele não preserva a distinção entre nenhum desconto e um desconto desconhecido. Se essa distinção for necessária, adicione um ramo IS NULL com seu próprio resultado.

Indicadores podem ser selecionados, ordenados, filtrados ou incluídos em operações aritméticas. Em uma cláusula WHERE portátil, repita a expressão ou use sua condição original em vez de se referir a um apelido de saída recém-definido.

Reconheça funções condicionais relacionadas

COALESCE(bonus, 0) é uma forma curta de CASE WHEN bonus IS NOT NULL THEN bonus ELSE 0 END. NULLIF(a, b) corresponde a CASE WHEN a = b THEN NULL ELSE a END. Seus nomes comunicam diretamente essas finalidades comuns.

SQLite a partir da versão 3.32 e SQL Server têm IIF(condition, true_value, false_value); MySQL tem IF. DECODE do Oracle traduz correspondências de igualdade, por exemplo, DECODE(status, 'S', 'Shipped', 'P', 'Pending', 'Other'). DECODE trata dois valores NULL como iguais, ao contrário das comparações de igualdade no CASE simples. CASE padrão funciona nesses sistemas.

Um CASE pode conter outro CASE, mas condições combinadas muitas vezes tornam uma expressão sem aninhamento mais clara. Uma regra de envio pode usar diretamente WHEN country = 'US' AND subtotal >= 100 THEN 0, mantendo juntos os testes de país e subtotal.

Principais conclusões

  • CASE simples compara uma expressão com valores usando igualdade.
  • Use CASE pesquisado para testes de NULL, intervalos e condições combinadas.
  • Um CASE numérico em ORDER BY cria uma classificação personalizada.
  • Um indicador com ELSE 0 também atribui zero quando sua condição é UNKNOWN.
  • COALESCE e NULLIF expressam casos especiais comuns de CASE.
  • DECODE do Oracle trata dois valores NULL como iguais; CASE simples não.

5.3 Combinar funções em uma consulta completa para relatório

Um relatório pode limpar nomes, calcular totais líquidos, identificar meses e atribuir rótulos à velocidade de envio em um único SELECT. Construa cada expressão a partir de suas entradas e confira o resultado antes de combiná-la com as outras.

Trabalhe com linhas conhecidas

Uma tabela de pedidos contém estes registros. As datas são texto ISO para a consulta SQLite abaixo; quantity é um inteiro e unit_price é numérico.

PedidoClienteQuantidadePreçoDesconto %Data do pedidoData de envio
1001Ana Lopez312,50102026-03-142026-03-17
1002Ben Okafor1240,0002026-03-30NULL
1003Chen Wu124,25NULL2026-04-022026-04-03

Aqui um desconto ausente significa que não há desconto. Comece recuperando os campos originais. Adicione uma coluna calculada de cada vez e use LIMIT 5 enquanto verifica uma pequena amostra.

Acompanhe um cálculo aninhado
ROUND(quantity * unit_price *
      (1 - COALESCE(discount_pct, 0) / 100.0), 2)

COALESCE fornece primeiro um desconto conhecido. Dividir por 100.0 preserva sua fração. Subtrair de 1 fornece a fração paga, a multiplicação fornece o valor líquido e ROUND define a precisão final. O valor de Ana é 33,75, o de Ben é 240,0 e o de Chen é 51,0. O desconto NULL de Chen torna-se zero; já uma data de envio ausente deve permanecer ausente na contagem de dias.

Monte o relatório no SQLite
SELECT order_id,
       first_name || ' ' || last_name AS customer,
       ROUND(quantity * unit_price *
         (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net_total,
       strftime('%Y-%m', order_date) AS order_month,
       CAST(julianday(shipped_date) - julianday(order_date)
         AS INTEGER) AS days_to_ship,
       CASE
         WHEN shipped_date IS NULL THEN 'not shipped'
         -- fast = shipped within 2 days
         WHEN julianday(shipped_date) - julianday(order_date) <= 2
           THEN 'fast'
         ELSE 'standard'
       END AS shipping
FROM orders
ORDER BY order_id;

Cada expressão tem um apelido de saída claro. A diferença numérica de dias é convertida para INTEGER porque esses valores contêm apenas datas. O ramo IS NULL vem antes da comparação de velocidade, então um pedido não enviado recebe um rótulo útil.

A saída é:

PedidoClienteTotal líquidoMêsDiasEnvio
1001Ana Lopez33,752026-033standard
1002Ben Okafor240,02026-03NULLnot shipped
1003Chen Wu51,02026-041fast
Adapte tipos e cláusulas da consulta

Para colunas DATE no PostgreSQL, use TO_CHAR(order_date, 'YYYY-MM') para o mês e shipped_date - order_date para a contagem de dias e a comparação no CASE. Mantenha unit_price como numeric exato para ROUND com dois argumentos. A concatenação, o valor alternativo do desconto e a regra de classificação mantêm o mesmo significado.

Para filtrar totais arredondados acima de 50 em ambos os bancos de dados, repita a expressão completa do valor líquido em WHERE. Os pedidos 1002 e 1003 permanecem. SQLite também permite WHERE net_total > 50, mas PostgreSQL não consegue ver esse novo apelido na etapa de filtragem. ORDER BY net_total DESC funciona em ambos.

Ao transferir um relatório, confira os tipos e nomes de funções em cada expressão. Uma função de texto deve receber texto, um cálculo de data deve receber um valor de data aceito e um valor alternativo numérico deve expressar a regra pretendida. Mantenha cada saída em sua própria linha; um comentário curto pode definir um limite de negócio sem obscurecer a SQL.

Principais conclusões

  • Construa e verifique uma coluna calculada de cada vez em uma pequena amostra.
  • Funções aninhadas passam seus resultados para fora; mantenha adequado o tipo de cada entrada.
  • Um desconto ausente e uma data de envio ausente podem exigir tratamentos diferentes.
  • Use expressões de data adequadas ao dialeto, mantendo consistentes as regras do relatório.
  • Filtre com a expressão completa e ordene pelo seu apelido de saída quando adequado.

Exercícios resolvidos de Colunas calculadas e funções em SQL

5 Lições Interativas

1

Construir e verificar o valor de um item do pedido com desconto

16 passos
Calcule um valor, nomeie-o, preserve sua fração e verifique os tipos que determinam o resultado.
  1. 1
    IntroduçãoTransforme uma linha em um valor útil

    Um item do pedido registra oito unidades a 7,50 cada, com desconto de 20 por cento. O relatório precisa de um valor líquido, mas a tabela armazena apenas os dados de entrada. Você construirá a expressão em etapas, nomeará sua saída e verificará o que a divisão inteira faz com o desconto.

    Os exemplos usam SQLite e PostgreSQL. Onde suas regras de tipo diferem, o nome do banco de dados identifica o resultado.

  2. 2
    ExplicaçãoComece com uma expressão

    Uma expressão combina valores para produzir outro valor. Aqui, quantity * unit_price usa duas colunas da linha atual.

    SELECT quantity * unit_price AS gross_total
    FROM order_lines;
    

    gross_total é o apelido de saída. Para a linha de exemplo, o novo valor é 60.0 no SQLite. Cada outra linha fornece suas próprias entradas; a consulta não grava esses totais de volta na tabela.

  3. 3
    ConexãoCada valor continua pertencendo a uma linha

    Uma função escalar retorna um valor para cada linha de entrada. ROUND(unit_price, 0) altera o preço exibido para uma linha, enquanto UPPER(item_name) altera seu texto exibido.

    Essas funções não combinam os itens do pedido. Uma função de agregação como SUM combina valores de um grupo, então responde a um tipo diferente de pergunta. Um cálculo em SELECT pode manter o detalhe de cada pedido.

  4. 4
    DicaNomeie o resultado com clareza

    AS net_total é um apelido simples e legível. Use aspas duplas quando um nome tiver espaço, como em AS "Net Total". Aspas simples identificam valores de texto.

    Mantenha uma vírgula entre as expressões de saída. SELECT quantity unit_price retorna uma coluna de quantidades com o cabeçalho unit_price: sem vírgula, o segundo nome torna-se um apelido. Essa consulta pode ser executada com sucesso e mostrar menos colunas do que o pretendido.

  5. 5
    DesafioPosicione o apelido na consulta

    A tabela tem apenas quantity e unit_price. Uma consulta define quantity * unit_price AS gross_total. Um filtro WHERE no PostgreSQL pode usar gross_total > 50? E ORDER BY pode usar gross_total DESC?

    ---reveal---

    WHERE não consegue ver esse novo apelido porque precede SELECT na ordem lógica. Repita quantity * unit_price > 50. ORDER BY vem depois de SELECT e pode usar gross_total DESC. SQLite permite o apelido em WHERE como extensão, mas PostgreSQL não.

  6. 6
    ExemploTransforme um desconto na fração paga

    O valor bruto é 8 * 7.50, ou 60. Um desconto de 20 por cento deixa 80 por cento a pagar. Expresse isso como 1 - discount_pct / 100.0.

    quantity * unit_price * (1 - discount_pct / 100.0)
    

    A divisão resulta em 0.2; os parênteses resultam em 0.8; a multiplicação resulta em um valor líquido de 48.0. Os parênteses mantêm a subtração agrupada como um multiplicador.

  7. 7
    Ideia-chaveUm decimal posterior não corrige uma divisão anterior

    Suponha que discount_pct seja um inteiro e que o divisor seja escrito como 100. SQLite e PostgreSQL calculam 20 / 100 como divisão inteira e obtêm 0. O multiplicador torna-se 1, então o valor líquido permanece incorretamente em 60.

    O preço decimal em outra parte não corrige essa divisão interna. Use 100.0 na própria divisão. Converter o quociente depois de calculado altera seu tipo, mas não recupera a fração perdida.

  8. 8
    DesafioEncontre o cálculo que perdeu sua fração

    Uma linha no SQLite tem completed inteiro igual a 9 e assigned inteiro igual a 12. O que completed / assigned * 100.0 retorna e como a expressão deve calcular o percentual?

    ---reveal---

    Ela retorna 0.0: a divisão inteira 9 / 12 torna-se 0 primeiro. Escreva completed * 100.0 / assigned, que resulta em 75.0. A conversão deve ocorrer antes da divisão, não apenas antes da exibição final.

  9. 9
    ExplicaçãoEscolha a regra para obter um inteiro

    ROUND escolhe um valor arredondado próximo. FLOOR desce até um inteiro, CEIL sobe e TRUNC descarta a fração em direção a zero.

    Para -6.4, FLOOR resulta em -7, enquanto CEIL e TRUNC resultam em -6. A direção importa para entradas negativas. PostgreSQL fornece essas funções; CEIL, FLOOR e TRUNC no SQLite exigem uma compilação com funções matemáticas. ABS, que fornece a distância de zero, é integrado ao SQLite.

  10. 10
    DicaVerifique o tipo numérico antes de arredondar

    No PostgreSQL, ROUND com dois argumentos recebe numeric, não double precision. Para uma coluna de ponto flutuante, escreva ROUND(CAST(amount AS numeric), 2). SQLite aceita sua própria forma numérica de ROUND.

    Valores aproximados de ponto flutuante podem produzir resultados surpreendentes em valores na metade. Para valores exatos, NUMERIC/DECIMAL no PostgreSQL armazena decimais exatos; SQLite pode manter centavos inteiros como números inteiros. Arredonde o resultado exibido após o cálculo.

  11. 11
    ExplicaçãoTorne explícita uma mudança de tipo

    CAST(expression AS type) solicita uma conversão. O texto '28' pode se tornar o inteiro 28 com CAST('28' AS INTEGER). O número pode se tornar texto com CAST(28 AS TEXT).

    Para divisão fracionária, SQLite precisa de REAL para obter um operando não inteiro de forma confiável. CAST(7 AS NUMERIC) ainda pode ser o inteiro 7 nesse sistema. NUMERIC do PostgreSQL fornece um tipo decimal exato. Uma conversão de NULL permanece NULL.

  12. 12
    ExemploMantenha identificadores separados de quantidades

    Suponha que um campo armazene o código postal dos Estados Unidos '00421'. Convertê-lo em inteiro resulta em 421, perdendo os zeros iniciais. Ele é um identificador, então operações aritméticas não são a tarefa.

    Uma coluna de texto que realmente contém quantidades pode precisar de conversão para ordenação numérica. Os textos '12', '3' e '80' são ordenados nessa ordem; a ordenação numérica resulta em 3, 12, 80. Escolha a conversão de acordo com o significado da coluna.

  13. 13
    DesafioInterprete uma conversão sem confiar nela como validação

    SQLite executa CAST('31units' AS INTEGER) com sucesso. Que valor ele retorna, e esse sucesso mostra que o texto original era um inteiro válido?

    ---reveal---

    Ele retorna 31 ao ler a parte numérica inicial. O sucesso não valida a cadeia inteira. PostgreSQL rejeita o mesmo texto como inteiro. SQLite também pode transformar texto sem prefixo numérico em zero, escondendo uma entrada inválida.

  14. 14
    Ideia-chaveUma conversão para inteiro não é a mesma operação em todos os sistemas

    Para o valor numérico 4.7, CAST(... AS INTEGER) do SQLite trunca para 4, enquanto PostgreSQL arredonda para 5. Se um relatório exige “unidades inteiras que não excedam esse valor”, expresse isso com FLOOR antes da conversão.

    Uma conversão implícita também depende do banco de dados. PostgreSQL pode inferir um número a partir de um literal entre aspas em operações aritméticas, mas uma coluna TEXT precisa de conversão explícita. Os caracteres visíveis, por si só, não estabelecem o tipo do operando.

  15. 15
    DesafioVerifique a expressão completa do valor líquido

    Para oito itens a 7,50 com discount_pct inteiro igual a 20, um relatório usa ROUND(quantity * unit_price * (1 - discount_pct / 100.0), 2) AS net_total. Qual é o resultado e esse apelido pode ordenar a saída?

    ---reveal---

    O valor bruto é 60, a fração paga é 0,8 e o valor líquido é 48.0 no SQLite. ORDER BY net_total é válido tanto no SQLite quanto no PostgreSQL porque a ordenação pode ver o apelido de SELECT.

  16. 16
    RecapitulaçãoLeia as entradas, o cálculo e o nome de saída

    Um valor calculado segue um caminho: a linha fornece valores, operações aritméticas e funções produzem o resultado, e um apelido o nomeia. Verifique a ordem das operações e os tipos dos operandos antes de aceitar um número exibido.

    Quando um resultado for inesperado, examine primeiro uma divisão ou conversão interna. Para filtrar um valor calculado em diferentes bancos de dados, repita sua expressão em WHERE; para ordená-lo, use o apelido de saída em ORDER BY.

2

Acompanhar dados ausentes em uma consulta

12 passos
Acompanhe condições UNKNOWN e depois escolha e combine COALESCE e NULLIF.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoUm valor ausente altera mais do que uma célula
  2. 2
    ExplicaçãoNULL é uma entrada desconhecida
  3. 3
    ExemploUse um teste que verifique a ausência
  4. 4
    Ideia-chaveWHERE aceita apenas TRUE
  5. 5
    DesafioCombine uma condição conhecida com uma desconhecida
  6. 6
    DicaNão deixe NULL em uma lista de exclusão
  7. 7
    ExplicaçãoEscolha um valor alternativo pelo significado
  8. 8
    ExemploMantenha consistente o tipo de exibição
  9. 9
    ExemploTransforme um denominador zero em uma lacuna
  10. 10
    DesafioLimpe texto vazio antes de atribuir o rótulo
  11. 11
    DesafioSepare uma escolha de exibição de uma escolha de filtro
  12. 12
    RecapitulaçãoMantenha visível o significado de uma lacuna
3

Limpar um nome e extrair um domínio de e-mail

14 passos
Concatene textos, aninhe funções de limpeza e acompanhe as posições dos caracteres ao redor de um separador.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoTorne o texto utilizável sem perder suas partes
  2. 2
    ExemploForneça o espaço entre os nomes
  3. 3
    ExplicaçãoDecida o efeito de uma parte ausente do nome
  4. 4
    ExemploLimpe o e-mail de dentro para fora
  5. 5
    DesafioEscolha entre remover espaços das extremidades e substituir
  6. 6
    DicaVerifique as regras de caracteres e de dialeto
  7. 7
    ExplicaçãoConte a partir de um
  8. 8
    ExemploLocalize o separador
  9. 9
    ExemploExtraia os caracteres antes e depois de @
  10. 10
    DesafioEncontre o resultado com erro de uma posição
  11. 11
    Ideia-chaveUm resultado de busca zero precisa de tratamento próprio
  12. 12
    DicaExtraia finais e preencha códigos no dialeto correto
  13. 13
    DesafioCombine limpeza com extração
  14. 14
    RecapitulaçãoAcompanhe os caracteres exatos
4

Criar rótulos de data e filtros de período confiáveis

18 passos
Leia valores de data, formate-os para exibição e calcule prazos, durações e períodos completos.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoSepare o valor do calendário de seu rótulo
  2. 2
    ExplicaçãoEscolha uma representação clara de data
  3. 3
    ExemploLeia um formato local fixo
  4. 4
    DesafioExplique qual texto é ordenado por data
  5. 5
    DicaVerifique a interpretação e a referência da hora atual
  6. 6
    ExemploExtraia o mês com o tipo de retorno correto
  7. 7
    ExplicaçãoMantenha o ano no rótulo de mês
  8. 8
    ExemploCrie uma exibição sem alterar a ordenação
  9. 9
    DesafioEncontre o trimestre correto
  10. 10
    ConexãoEscolha a convenção de numeração dos dias da semana
  11. 11
    ExemploAdicione dez dias à reserva
  12. 12
    Ideia-chaveUm mês não é uma quantidade fixa de dias
  13. 13
    ExemploMeça dias e horas em unidades adequadas
  14. 14
    DesafioInclua a última tarde do mês
  15. 15
    ExplicaçãoConte aniversários que realmente chegaram
  16. 16
    DicaLeia datas relativas como limites que mudam
  17. 17
    DesafioCombine um prazo com a seleção de um mês
  18. 18
    RecapitulaçãoVerifique o tipo, a regra do calendário e os extremos
5

Atribuir rótulos a pedidos e construir o relatório final

17 passos
Escolha ramos CASE, traduza prioridades e combine várias saídas calculadas.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoDê a cada pedido um rótulo útil
  2. 2
    ExplicaçãoEscolha a primeira condição verdadeira
  3. 3
    ExemploAcompanhe o limite exato
  4. 4
    Ideia-chaveELSE também pode capturar um valor desconhecido
  5. 5
    DesafioCorrija uma faixa pequena oculta
  6. 6
    DicaRetorne resultados compatíveis
  7. 7
    ExemploTraduza um valor de status
  8. 8
    DesafioPor que WHEN NULL não encontra a linha?
  9. 9
    ExemploOrdene a prioridade por classificação
  10. 10
    Ideia-chaveUm indicador pode unir casos conhecidos e desconhecidos
  11. 11
    ExemploComece o relatório com entradas conhecidas
  12. 12
    ExemploCalcule primeiro o valor líquido
  13. 13
    ExemploAdicione datas com uma regra separada para ausência
  14. 14
    DesafioVerifique uma segunda linha com ambas as regras
  15. 15
    ConexãoAdapte as expressões de data para PostgreSQL
  16. 16
    DesafioFiltre o valor que o relatório realmente mostra
  17. 17
    RecapitulaçãoVerifique o relatório como um conjunto de escolhas explícitas

Questões de Colunas calculadas e funções em SQL

40 Questões de Prática em 4 conjuntos

Conjunto 1: Limpar textos e trabalhar com valores de calendário10 Questões de Prática

Questão 1 de 10

O que LOWER(TRIM(' RAE@Mail.COM ')) retorna no SQLite?
  1. ' rae@mail.com '
  2. 'RAE@Mail.COM' (maiúsculas e minúsculas mantidas)
  3. 'rae@mail.com'
  4. 'rae@mail.com '
Mostrar respostaOcultar resposta
Resposta: C
TRIM primeiro remove os espaços das duas extremidades, depois LOWER converte as letras ASCII para minúsculas. O resultado é o texto limpo 'rae@mail.com'. Manter o espaço final significaria que apenas a extremidade esquerda foi limpa; TRIM comum trata ambas as extremidades e não precisa de um RTRIM separado.

Questão 2 de 10

Uma linha no SQLite 3.44 ou posterior tem first_name = 'Mira', middle_name = NULL e last_name = 'Shah'. O que first_name || ' ' || middle_name || ' ' || last_name e CONCAT_WS(' ', first_name, middle_name, last_name) retornam, nessa ordem?
  1. NULL; 'Mira Shah'
  2. 'Mira Shah'; 'Mira Shah'
  3. NULL; NULL
  4. 'Mira Shah'; 'Mira Shah'
Mostrar respostaOcultar resposta
Resposta: A
A expressão || propaga a entrada NULL do nome do meio, tornando todo o nome NULL. CONCAT_WS ignora a parte ausente e coloca um separador entre Mira e Shah. Dois espaços resultariam da manutenção de uma posição vazia para o nome do meio, mas a entrada aqui é NULL e CONCAT_WS a ignora.

Questão 3 de 10

No SQLite, o que SUBSTR('Seattle', 3, 3) retorna?
  1. 'attl'
  2. 'tle'
  3. 'eat'
  4. 'att'
Mostrar respostaOcultar resposta
Resposta: D
As posições em SQL começam em 1, então a posição 3 é o primeiro t em Seattle. Extrair três caracteres a partir dessa posição resulta em 'att'. O trecho 'eat' começa na posição 2 e resultaria de tratar a posição inicial informada como um caractere antes de sua posição real.

Questão 4 de 10

No PostgreSQL, uma coluna TEXT email pode conter NULL ou texto sem @. Para texto que contém @, retorne tudo após seu primeiro @; caso contrário, retorne NULL. Qual expressão atende a isso?
  1. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@')) END
  2. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  3. CASE WHEN STRPOS(email, '@') >= 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  4. CASE WHEN email IS NOT NULL THEN SUBSTR(email, STRPOS(email, '@') + 1) END
Mostrar respostaOcultar resposta
Resposta: B
Um resultado positivo de STRPOS confirma que um separador foi encontrado; adicionar 1 faz a extração começar depois dele. Sem correspondência, WHEN é falso, e com NULL é UNKNOWN, então ambos retornam o NULL implícito. Testar >= 0 também aceita um separador ausente, cuja posição é zero, e retornaria toda a cadeia malformada.

Questão 5 de 10

Qual texto de data ISO representa 6 de novembro de 2027?
  1. '2027-11-06'
  2. '11/06/2027'
  3. '2027-06-11'
  4. '2027-11-6'
Mostrar respostaOcultar resposta
Resposta: A
Texto de data ISO usa ano, mês e dia, com mês e dia de dois algarismos. Novembro é o mês 11 e o sexto dia é 06, então o resultado é '2027-11-06'. O final invertido 06-11 representa 11 de junho, enquanto um dia final de um algarismo não segue o formato de largura fixa.

Questão 6 de 10

O que a versão atual do SQLite retorna para date('2027-04-31')?
  1. '2027-04-30'
  2. Um erro de data inválida
  3. '2027-05-01'
  4. NULL
Mostrar respostaOcultar resposta
Resposta: C
SQLite normaliza o dia excedente de abril para maio, resultando em '2027-05-01'. Portanto, um resultado de data diferente de NULL não garante que o dia original existia naquele mês. PostgreSQL rejeita o literal DATE tipado equivalente, mas esse comportamento rigoroso de entrada não deve ser presumido para a função de data do SQLite.

Questão 7 de 10

No SQLite, d contém '2027-08-19'. Quais são os resultados de strftime('%m', d) = 8 e CAST(strftime('%m', d) AS INTEGER) = 8, nessa ordem?
  1. TRUE; TRUE
  2. FALSE; TRUE
  3. FALSE; FALSE
  4. TRUE; FALSE
Mostrar respostaOcultar resposta
Resposta: B
strftime retorna o texto '08', que não é igual ao número 8 na primeira expressão. Converter esse texto para INTEGER produz 8 e torna a segunda comparação verdadeira. O zero inicial faz parte do texto retornado; exibir um mês como algarismos não torna numérico o resultado da função.

Questão 8 de 10

Uma coluna DATE event_date no PostgreSQL abrange vários anos. Um relatório exibe datas como MM/DD/YYYY e deve manter a ordem cronológica. Como ele deve selecionar e ordenar a coluna?
  1. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY day_label;
  2. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY EXTRACT(MONTH FROM event_date), EXTRACT(DAY FROM event_date);
  3. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY CAST(TO_CHAR(event_date, 'MM/DD/YYYY') AS TEXT);
  4. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY event_date;
Mostrar respostaOcultar resposta
Resposta: D
TO_CHAR fornece o texto de exibição solicitado, enquanto ordenar pelo DATE original mantém ano, mês e dia em ordem cronológica. Ordenar pelo apelido de exibição começa pelos caracteres do mês e pode intercalar anos. Ordenar apenas pelo mês e dia extraídos tem o mesmo problema de ausência do ano, embora essas partes sejam numéricas.

Questão 9 de 10

Uma data d no SQLite é '2027-04-24'. O que date(d, '+10 days') retorna?
  1. '2027-05-03'
  2. '2027-04-34'
  3. '2027-05-04'
  4. '2027-05-05'
Mostrar respostaOcultar resposta
Resposta: C
Seis dias após 24 de abril chegam a 30 de abril, e mais quatro chegam a 4 de maio, então o resultado é '2027-05-04'. 3 de maio conta a data inicial como um dos dez dias adicionados. Um deslocamento de data mede os dias após o ponto inicial e leva os dias restantes para o mês seguinte.

Questão 10 de 10

Uma coluna TIMESTAMP no PostgreSQL não tem fuso horário e registra horários ao longo de junho de 2027. Qual filtro inclui todos os valores de junho e nenhum valor de julho?
  1. logged_at >= '2027-06-01' AND logged_at < '2027-07-01'
  2. logged_at BETWEEN '2027-06-01' AND '2027-06-30'
  3. logged_at >= '2027-06-01' AND logged_at <= '2027-07-01'
  4. logged_at > '2027-06-01' AND logged_at < '2027-07-01'
Mostrar respostaOcultar resposta
Resposta: A
O limite inferior inclusivo de 1º de junho mantém o primeiro instante, e o limite superior exclusivo de 1º de julho inclui todos os horários anteriores ao próximo mês. BETWEEN terminando em 30 de junho alcança apenas a meia-noite no início desse dia. Incluir 1º de julho admitiria um valor de fronteira indesejado, enquanto excluir 1º de junho perderia seu registro da meia-noite.
Conjunto 2: Calcular valores e tratar dados ausentes10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Uma tabela no PostgreSQL tem apenas units e unit_cost. Qual lista SELECT retorna o produto deles com o cabeçalho extended_cost?
  1. units + unit_cost AS extended_cost
  2. units * unit_cost AS extended_cost
  3. units * unit_cost, extended_cost
  4. units * 'unit_cost' AS extended_cost
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

A tabela lines contém apenas units e price. Uma consulta deve funcionar no SQLite e no PostgreSQL. Como ela deve manter linhas com produto acima de 90 e ordenar primeiro o maior produto?
  1. SELECT units * price AS amount FROM lines WHERE amount > 90 ORDER BY amount DESC;
  2. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount ASC;
  3. SELECT units * price AS amount FROM lines ORDER BY amount DESC WHERE units * price > 90;
  4. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount DESC;
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

O que SELECT 14 + 5 * 3; retorna no SQLite?
  1. 29
  2. 57
  3. 33
  4. 75
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

No SQLite, old_count e new_count são inteiros que contêm 60 e 69. Qual é o resultado de (new_count - old_count) / old_count * 100?
  1. 15
  2. 0.15
  3. 0
  4. 9
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Uma linha de fatura no SQLite tem os inteiros units = 5 e discount_pct = 12, com price = 18.0. Que resultado ROUND(units * price * (1 - discount_pct / 100), 2) produz?
  1. 79.2
  2. 90.0
  3. 89.88
  4. 78.0
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

O que SQLite retorna para CAST('27boxes' AS INTEGER)?
  1. 27
  2. 0
  3. Um erro de inteiro inválido
  4. NULL
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Qual condição encontra linhas sem delivery_date registrada?
  1. delivery_date = NULL
  2. delivery_date <> NULL
  3. delivery_date = ''
  4. delivery_date IS NULL
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Uma tabela contém exatamente quatro valores de region: 'East', 'West', NULL e 'North'. Quantas linhas satisfazem WHERE NOT (region = 'East')?
  1. 3
  2. 2
  3. 1
  4. 4
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Uma cadeia de telefone vazia e NULL devem ser exibidos como 'unlisted' no SQLite. Qual expressão faz isso preservando os números registrados?
  1. NULLIF(COALESCE(phone, ''), 'unlisted')
  2. COALESCE(phone, '', 'unlisted')
  3. COALESCE(NULLIF(phone, ''), 'unlisted')
  4. COALESCE(NULLIF(phone, 'unlisted'), '')
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um relatório no PostgreSQL tem sales e visits inteiros. Uma taxa deve manter percentuais fracionários e permanecer NULL quando visits for zero. Ela não deve inventar uma taxa zero. Qual expressão atende a isso?
  1. COALESCE(sales * 100.0 / NULLIF(visits, 0), 0)
  2. sales / NULLIF(visits, 0) * 100.0
  3. sales * 100.0 / COALESCE(visits, 1)
  4. sales * 100.0 / NULLIF(visits, 0)
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 3: Classificar linhas e diagnosticar a lógica de relatórios10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Qual rótulo este CASE produz para score = 75: CASE WHEN score < 60 THEN 'review' WHEN score < 80 THEN 'ready' ELSE 'strong' END?
  1. 'review'
  2. 'strong'
  3. NULL
  4. 'ready'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Por que CASE WHEN amount < 500 THEN 'regular' WHEN amount < 100 THEN 'small' ELSE 'large' END nunca retorna 'small' para valores diferentes de NULL?
  1. CASE verifica primeiro o último intervalo correspondente.
  2. Todo valor abaixo de 100 já passa no teste anterior de menos de 500.
  3. O ramo ELSE substitui um intervalo correspondente posterior.
  4. A segunda condição é testada apenas para valores iguais a 500.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Um balance numérico pode ser NULL. Os rótulos exigidos são 'unknown' para valor ausente, 'credit' abaixo de 0, 'settled' em 0 e 'due' acima de 0. Qual CASE atende a todas as regras?
  1. CASE WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  2. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance <= 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  3. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  4. CASE balance WHEN NULL THEN 'unknown' WHEN 0 THEN 'settled' ELSE 'due' END
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Um valor de state igual a 'H' significa retido e 'R' significa liberado. O que CASE state WHEN 'H' THEN 'held' WHEN 'R' THEN 'released' ELSE 'other' END retorna para 'R'?
  1. 'released'
  2. 'held'
  3. 'other'
  4. NULL
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um relatório deve ordenar 'urgent', 'normal' e 'deferred' nessa ordem, com todas as outras prioridades ou prioridades NULL por último. Qual expressão ORDER BY atende a isso?
  1. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END DESC
  2. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END DESC
  3. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 3 WHEN 'deferred' THEN 2 ELSE 4 END ASC
  4. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END ASC
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Uma linha no SQLite tem qty = 4, price = 15.0, discount_pct = NULL e shipped_date = NULL. Desconto ausente significa nenhum desconto. Qual par resulta de ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) e CASE WHEN shipped_date IS NULL THEN 'open' ELSE 'sent' END?
  1. NULL; 'open'
  2. 0.0; 'open'
  3. 60.0; 'open'
  4. 60.0; 'sent'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Um relatório no SQLite mostra LOWER(TRIM(customer)) AS name e date(due_date, '+7 days') AS reminder_date. O valor original de customer é ' IVAN ' e due_date é '2027-09-26'. Qual par de saída uma verificação por amostragem deve encontrar?
  1. 'ivan'; '2027-10-03'
  2. ' ivan '; '2027-10-03'
  3. 'ivan'; '2027-10-02'
  4. 'IVAN' (maiúsculas mantidas); '2027-10-03'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Uma tabela no PostgreSQL contém os valores de x 2, 7, NULL e 11. Quais são as quantidades de linhas para WHERE x NOT IN (2, NULL) e WHERE x <> 2 OR x IS NULL, respectivamente?
  1. 2 e 3
  2. 0 e 3
  3. 0 e 2
  4. 3 e 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Uma pessoa nasceu em '1998-12-18'. Em '2027-12-17', qual é sua idade em anos completos e por que subtrair os dois números dos anos pode estar errado?
  1. 28; o aniversário ainda não ocorreu em 2027.
  2. 29; um novo ano civil completa um ano de idade.
  3. 28; nascimentos em dezembro sempre contam um ano a menos.
  4. 29; os dias decorridos divididos por 365 dão a idade.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Uma coluna INTEGER rating no PostgreSQL pode ser NULL. Uma coluna de exibição deve mostrar a avaliação como texto ou 'unrated'. Qual expressão atende a isso?
  1. CAST(COALESCE(rating, 'unrated') AS TEXT)
  2. NULLIF(CAST(rating AS TEXT), 'unrated')
  3. COALESCE(CAST(rating AS TEXT), 'unrated')
  4. CAST(NULLIF(rating, 0) AS TEXT)
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 4: Verificar relatórios completos e fronteiras delicadas10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Uma tabela no PostgreSQL tem apenas qty inteiro, price NUMERIC e discount_pct inteiro. Desconto ausente significa nenhum desconto. Um relatório deve manter totais líquidos arredondados acima de 75 e ordená-los do maior para o menor. Qual consulta completa atende a isso?
  1. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE net > 75 ORDER BY net DESC;
  2. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net DESC;
  3. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) > 75 ORDER BY net DESC;
  4. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net ASC;
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Uma coluna reading no PostgreSQL é DOUBLE PRECISION. Como um relatório pode arredondá-la para duas casas decimais sem um erro de assinatura de função?
  1. ROUND(reading, 2)
  2. CAST(ROUND(reading) AS NUMERIC)
  3. ROUND(CAST(reading AS NUMERIC), 2)
  4. ROUND(CAST(reading AS INTEGER), 2)
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

O que COALESCE(NULL, '', 'backup') retorna no SQLite?
  1. ''
  2. 'backup'
  3. NULL
  4. 'NULL'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

No SQLite, uma linha tem email = 'nora@research.org'. Que resultado SUBSTR(email, INSTR(email, '@')) produz?
  1. 'research.org'
  2. 'nora'
  3. 'nora@'
  4. '@research.org'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Para '2027-01-31', compare date(d, '+1 month') no SQLite 3.46 ou posterior, date(d, '+1 month', 'floor') no SQLite e DATE '2027-01-31' + INTERVAL '1 month' no PostgreSQL. Quais datas do calendário resultam, nessa ordem?
  1. 28 de fevereiro; 28 de fevereiro; 28 de fevereiro
  2. 3 de março; 3 de março; 28 de fevereiro
  3. 3 de março; 28 de fevereiro; 28 de fevereiro
  4. 28 de fevereiro; 3 de março; 3 de março
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Um stock INTEGER no PostgreSQL pode ser NULL. Indicador numérico exigido: NULL para estoque desconhecido, 1 para estoque abaixo de 5 e 0 caso contrário. Qual expressão atende a isso?
  1. CASE WHEN stock < 5 THEN 1 ELSE 0 END
  2. CASE WHEN stock IS NULL THEN NULL WHEN stock < 5 THEN 1 ELSE 0 END
  3. CASE WHEN stock IS NULL THEN NULL WHEN stock <= 5 THEN 1 ELSE 0 END
  4. CASE stock WHEN NULL THEN NULL WHEN 5 THEN 0 ELSE 1 END
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

SQLite 3.38 ou posterior registra uma sessão de '2027-05-08 10:15:00' até '2027-05-08 13:45:00'. O que (unixepoch(end_time) - unixepoch(start_time)) / 3600.0 retorna?
  1. 3.0
  2. 210.0
  3. 12600.0
  4. 3.5
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Um pedido no SQLite tem qty = 6 inteiro, price = 8.0, discount_pct = 25, foi feito em '2027-07-10' e enviado em '2027-07-12'. O valor líquido usa ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2). Um CASE atribui 'open' a envio NULL, 'fast' a dias decorridos <= 2 e 'standard' caso contrário. Quais são o valor líquido e o rótulo resultantes?
  1. 36.0; 'fast'
  2. 48.0; 'fast'
  3. 36.0; 'standard'
  4. 12.0; 'fast'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um relatório no SQLite precisa dos números de trimestre de 1 a 4 para qualquer data válida d. Como ele pode calcular o trimestre para cada mês?
  1. CAST(strftime('%m', d) AS INTEGER) / 3 + 1
  2. (CAST(strftime('%m', d) AS INTEGER) + 1) / 3
  3. ROUND(CAST(strftime('%m', d) AS INTEGER) / 3.0)
  4. (CAST(strftime('%m', d) AS INTEGER) + 2) / 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Uma tabela no SQLite tem as linhas A (qty 3, price 22.0, discount_pct NULL), B (qty 4, price 20.0, discount_pct 25) e C (qty 2, price 40.0, discount_pct 10). Desconto ausente significa nenhum desconto. Ela calcula ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net, mantém net > 60 usando a expressão completa em WHERE e ordena por net DESC. Qual é a ordem das linhas?
  1. B, C, A
  2. C, A
  3. C, A, B
  4. A, C
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Travou em uma questão sua? Ajuda com Tarefas

Termos-Chave

61 Termos-Chave, cada um com sua definição

A

Afinidade de tipo
A afinidade de tipo é a preferência do SQLite pela forma como uma coluna armazena valores; uma coluna comum ainda pode conter valores de tipos diferentes.
Uma declaração NUMERIC no SQLite pode manter 7 como inteiro, então não garante divisão decimal.
Aninhamento de funções
O aninhamento de funções coloca uma chamada de função dentro de outra, de modo que o resultado interno se torna um argumento da chamada que a envolve.
Em ROUND(COALESCE(amount, 0), 2), o valor alternativo é resolvido antes que a função de arredondamento receba sua entrada.
Apelido de coluna
Um apelido de coluna é um nome atribuído a uma coluna de saída de uma consulta, muitas vezes com AS, para que o resultado tenha um cabeçalho claro.
A consulta nomeia seu valor calculado com AS line_total e pode ordená-lo com ORDER BY line_total.

C

Cadeia de caracteres
Uma cadeia de caracteres é um valor de texto formado por caracteres, incluindo letras, algarismos, pontuação e espaços, escrito em SQL como um literal entre aspas simples.
A cadeia ' New York ' inclui espaços nas extremidades e dois espaços internos que afetam seu comprimento.
CASE pesquisado
Um CASE pesquisado testa condições na ordem escrita e retorna o resultado da primeira condição TRUE para a linha atual.
CASE WHEN total < 50 THEN 'small' ELSE 'large' END escolhe um rótulo a partir do valor da linha.
CASE simples
Um CASE simples compara uma expressão com uma sequência de valores por igualdade e retorna o resultado do primeiro valor correspondente.
CASE status WHEN 'S' THEN 'Shipped' ELSE 'Other' END traduz um código de status armazenado.
CEIL
CEIL é uma função numérica que retorna o menor inteiro maior ou igual à sua entrada; CEILING é outro nome.
O cálculo CEIL(4.1) resulta em 5 porque quatro está abaixo da entrada e cinco é o próximo inteiro.
COALESCE
COALESCE é uma função da SQL padrão que retorna o primeiro argumento que não é NULL, ou NULL quando todos os seus argumentos são NULL.
COALESCE(mobile_phone, home_phone, 'no phone') usa o número residencial se o número de celular estiver ausente.
Colação
Uma colação fornece regras para comparar e ordenar texto, incluindo se letras com diferentes usos de maiúsculas e minúsculas são comparadas como iguais.
A colação padrão do MySQL, que não diferencia maiúsculas de minúsculas, pode tornar 'Boston' = 'boston' verdadeiro quando o SQLite padrão não o faz.
Coluna calculada
Uma coluna calculada em uma consulta é uma coluna de saída cujo valor é calculado para cada linha, sem alterar os dados armazenados.
O resultado pode mostrar quantity * unit_price AS line_total mesmo quando a tabela não tem uma coluna line_total.
Comparação segura com NULL
Uma comparação segura com NULL fornece um resultado de comparação definido mesmo para entradas ausentes e pode tratar dois valores NULL como iguais.
NULL IS NOT DISTINCT FROM NULL é TRUE no PostgreSQL e no SQLite a partir da versão 3.39.
Concatenação
A concatenação junta partes de texto de ponta a ponta, preservando seus caracteres e exigindo que qualquer separador desejado seja fornecido.
first_name || ' ' || last_name insere um espaço entre as duas partes registradas do nome.
Consulta para relatório
Uma consulta para relatório seleciona e apresenta dados para uma finalidade, muitas vezes combinando valores calculados, rótulos limpos, datas e classificações.
Um relatório de pedidos pode mostrar um total líquido ao lado de um mês de pedido e de um rótulo CASE para a velocidade de envio.
Conversão entre maiúsculas e minúsculas
A conversão entre maiúsculas e minúsculas altera letras para maiúsculas ou minúsculas com funções como UPPER e LOWER, sujeitas às regras de caracteres do banco de dados.
LOWER(TRIM(email)) torna consistente um endereço de e-mail ASCII limpo para uma comparação com letras normalizadas.
Conversão explícita
Uma conversão explícita é uma mudança de tipo solicitada pela consulta, geralmente com CAST, para que a operação pretendida fique clara.
A expressão CAST(quantity AS REAL) / 4 altera o operando no SQLite antes que a divisão possa perder uma fração.
Conversão implícita
Uma conversão implícita é uma mudança de tipo feita automaticamente pelo banco de dados ao resolver uma operação ou expressão.
SQLite e PostgreSQL convertem 42 em texto em 'Order #' || 42, produzindo o rótulo 'Order #42'.

D

DATE
DATE é um tipo de dados para um dia do calendário no PostgreSQL e na SQL padrão; ele não tem componente de hora do dia.
DATE '2026-03-14' identifica explicitamente 14 de março de 2026 como um valor de data no PostgreSQL.
Divisão inteira
A divisão inteira divide operandos inteiros e descarta a parte fracionária em direção a zero no SQLite e no PostgreSQL.
Uma consulta que usa 7 / 2 produz 3; tornar o segundo operando 2.0 preserva a fração e produz 3,5.

E

Expressão
Uma expressão combina valores, nomes de colunas, operadores ou chamadas de função para produzir um valor que a SQL pode usar.
Em uma consulta de pedidos, quantity * unit_price é uma expressão que produz o valor do item do pedido para cada linha.
EXTRACT
EXTRACT é uma função da SQL padrão que extrai uma parte nomeada, como ano ou mês, de um valor de data e hora como número.
EXTRACT(MONTH FROM DATE '2026-03-14') do PostgreSQL retorna o valor numérico de mês 3.

F

FLOOR
FLOOR é uma função numérica que retorna o maior inteiro menor ou igual à sua entrada, avançando em direção a valores menores.
Para uma entrada negativa, FLOOR(-4.1) é -5, então difere de simplesmente descartar a fração.
Formato de data ISO
O formato de data ISO YYYY-MM-DD coloca ano, mês e dia de largura fixa em ordem decrescente de unidade e evita ambiguidades de formatos locais.
O texto '2026-03-14' tem zeros iniciais e é ordenado antes de '2026-11-02' em ordem de data.
Função escalar
Uma função escalar retorna um valor para cada linha de entrada; também é chamada de função de uma única linha e não agrupa linhas.
Usar UPPER(city) em SELECT altera o texto da cidade exibido para cada cliente retornado pela consulta.

I

Idade em anos completos
A idade em anos completos conta os aniversários completos alcançados até uma data de referência, então a diferença entre os números dos anos pode precisar da subtração de um ano.
Uma pessoa nascida em 2 de novembro de 1990 ainda tem 35 anos em 21 de outubro de 2026, antes do aniversário desse ano.
Indicador numérico
Um indicador numérico é uma saída como 1 ou 0 que registra se uma condição especificada era verdadeira para uma linha.
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END atribui zero tanto a descontos ausentes quanto a descontos não positivos.
INSTR
INSTR é uma função do SQLite que retorna a primeira posição de uma cadeia procurada dentro de um texto, ou zero quando não há correspondência.
INSTR('ana@example.com', '@') resulta em 4, enquanto uma cadeia sem @ produz zero.
Intervalo de tempo
Um intervalo de tempo é um valor do PostgreSQL que representa uma duração, como um mês do calendário ou a diferença entre timestamps.
Adicionar INTERVAL '1 month' a uma DATE no PostgreSQL retorna um timestamp e segue sua regra para fins de mês.
Intervalo fechado à esquerda e aberto à direita
Um intervalo fechado à esquerda e aberto à direita inclui sua fronteira inicial e exclui sua fronteira final, permitindo que períodos adjacentes de timestamps se encaixem.
ordered_at >= '2026-03-01' AND ordered_at < '2026-04-01' inclui todos os timestamps de março.
IS NULL
IS NULL é um teste de valor ausente que retorna TRUE quando seu operando é NULL e FALSE quando um valor está presente.
WHERE phone IS NULL recupera clientes sem telefone registrado sem comparar um valor com NULL usando igualdade.

L

LENGTH
LENGTH conta caracteres, incluindo espaços, em textos no SQLite e no PostgreSQL; texto vazio tem comprimento zero e NULL resulta em NULL.
LENGTH(' Bo ') resulta em 4 porque os dois espaços nas extremidades contam, assim como as duas letras.
Literal
Um literal é um valor escrito diretamente em SQL, como um número ou texto entre aspas, em vez de ser lido de uma coluna.
O espaço em first_name || ' ' || last_name é um literal de texto fornecido pela consulta.
Lógica de três valores
A lógica de três valores combina TRUE, FALSE e UNKNOWN em condições SQL, de modo que a negação nem sempre produz um resultado conhecido.
FALSE AND UNKNOWN é FALSE, mas TRUE AND UNKNOWN permanece UNKNOWN porque o segundo requisito está indefinido.

M

Máscara de formatação
Uma máscara de formatação especifica quais partes de data e hora exibir e como organizá-las, usando símbolos definidos pelo banco de dados.
SQLite usa '%m/%d/%Y' para um rótulo de data dos Estados Unidos; TO_CHAR do PostgreSQL usa 'MM/DD/YYYY'.

N

NULL
NULL é um marcador de valor ausente ou desconhecido, distinto de zero e, no SQLite e no PostgreSQL, de uma cadeia vazia.
Um bônus ausente torna salary + bonus desconhecido mesmo que o salário do funcionário esteja registrado.
NULLIF
NULLIF é uma função da SQL padrão que retorna NULL quando seus dois argumentos são iguais e, caso contrário, retorna o primeiro argumento.
NULLIF(visits, 0) mantém contagens positivas de visitas, mas transforma zero em um divisor ausente para uma taxa.
Número de ponto flutuante
Um número de ponto flutuante é uma representação numérica aproximada que pode introduzir pequenos erros ao armazenar frações decimais.
SQLite pode considerar 0.1 + 0.2 = 0.3 falso porque as aproximações armazenadas não somam o mesmo valor.
Número do dia juliano
Um número do dia juliano representa uma data e hora como uma contagem numérica de dias; subtrair dois valores mede os dias decorridos.
SQLite usa julianday(end_date) - julianday(start_date) em vez de subtrair cadeias de data ISO diretamente.

O

Ordem lógica de processamento da consulta
A ordem lógica de processamento da consulta descreve como as cláusulas constroem um resultado: FROM escolhe as linhas, WHERE filtra, SELECT calcula e ORDER BY ordena.
Um apelido de saída está disponível para ORDER BY, mas uma condição WHERE portátil repete a expressão calculada por trás desse apelido.

P

Posição do caractere
Uma posição do caractere identifica onde um caractere aparece em uma cadeia; as posições em texto SQL começam em 1, incluindo espaços.
O @ em 'ana@example.com' está na posição 4, então o domínio começa na posição 5.
Precedência de operadores
A precedência de operadores é a hierarquia que determina quais operações ocorrem primeiro quando uma expressão não tem parênteses que alterem essa ordem.
A SQL multiplica antes de somar em 10 + 3 * 2, então o resultado é 16 em vez de 26.
Preenchimento com caracteres
O preenchimento com caracteres adiciona caracteres para atingir uma largura escolhida de cadeia; uma operação de largura fixa também pode cortar um valor longo demais.
LPAD('42', 5, '0') do PostgreSQL retorna '00042', dando cinco caracteres a um código curto.
Prioridade de ordenação personalizada
Uma prioridade de ordenação personalizada atribui posições numéricas a valores para que ORDER BY siga uma sequência pretendida em vez da ordem alfabética.
Um CASE de prioridade associa high a 1, medium a 2 e low a 3 e depois ordena o resultado em ordem crescente.

R

Ramo WHEN
Um ramo WHEN é uma escolha de condição e resultado em CASE, em que THEN fornece o valor selecionado se essa condição for a primeira verdadeira.
Colocar um ramo amplo < 200 primeiro pode impedir que um ramo posterior < 50 seja selecionado.
REPLACE
REPLACE é uma função de cadeia de caracteres que substitui cada ocorrência exata de um trecho de texto por outro no valor retornado.
REPLACE('555-0100', '-', '') remove o hífen e exibe '5550100' sem editar a tabela.
Resto da divisão (módulo)
O módulo retorna o resto da divisão e é escrito com % no SQLite e no PostgreSQL ou MOD em vários dialetos.
Para 135 minutos, 135 % 60 fornece os 15 minutos restantes após duas horas completas.
Resultado alternativo de ELSE
Um resultado alternativo de ELSE é o resultado de CASE usado quando nenhuma condição WHEN é TRUE, inclusive quando as condições são UNKNOWN.
Um total NULL pode chegar a ELSE 'large' a menos que um ramo anterior teste explicitamente total IS NULL.
Rótulo de ano e mês
Um rótulo de ano e mês é uma representação em texto de um ano e um mês que identifica um período de relatório sem misturar anos.
O rótulo '2026-03' mantém março de 2026 separado de março de 2025 na exibição de um relatório.
ROUND
ROUND é uma função numérica que escolhe o valor mais próximo na precisão decimal solicitada, com regras para valores na metade que dependem do tipo.
O relatório usa ROUND((price - cost) / price * 100, 1) para exibir uma margem com uma casa decimal.

S

strftime
strftime é uma função de data e hora do SQLite que retorna texto selecionado por uma máscara de formatação, incluindo partes de data com zeros iniciais.
strftime('%m', '2026-03-14') retorna '03', que deve ser comparado com texto ou convertido antes do uso numérico.
Subcadeia de caracteres
Uma subcadeia de caracteres é uma parte consecutiva de uma cadeia, extraída usando uma posição inicial e, quando necessário, uma quantidade de caracteres.
SUBSTR('Boston', 1, 3) retorna 'Bos', extraindo três caracteres a partir da primeira posição.

T

Tempo Universal Coordenado (UTC)
UTC é a referência comum de tempo que SQLite usa para CURRENT_DATE e CURRENT_TIMESTAMP, que pode diferir de uma data local do calendário.
Um relatório perto da meia-noite local pode mostrar um dia diferente quando usa CURRENT_DATE do SQLite em vez de localtime.
Tempo Unix
O tempo Unix mede o tempo em segundos a partir de uma origem fixa em UTC; diferenças entre tempos Unix podem ser convertidas em horas decorridas.
SQLite subtrai dois resultados de unixepoch e divide por 3600.0 para manter horas fracionárias em uma duração.
Texto numérico
Texto numérico é uma cadeia que contém caracteres de números; sua forma de texto afeta a ordenação até que ela seja convertida para uso numérico.
As cadeias '10', '100' e '9' aparecem nessa ordem crescente de texto, que difere da ordem numérica.
TIMESTAMP
TIMESTAMP contém uma data e uma hora do dia, permitindo que uma consulta distinga instantes dentro do mesmo dia do calendário.
Um registro em '2026-03-31 14:05:00' é posterior à meia-noite no início de 31 de março.
Tipo de dados
Um tipo de dados descreve a espécie de valor e ajuda a determinar quais operações, conversões, comparações e regras de ordenação se aplicam.
O literal de texto '42' e o inteiro 42 podem parecer iguais em uma grade, mas se comportam de forma diferente em SQL.
TRIM
TRIM é uma função de cadeia de caracteres que remove espaços nas duas extremidades por padrão, deixando inalterados os espaços dentro do texto.
Após TRIM(' New York '), os dois espaços entre as palavras permanecem no texto retornado.

U

UNKNOWN
UNKNOWN é o terceiro resultado de uma condição SQL, produzido quando informações ausentes impedem uma comparação definida como verdadeira ou falsa.
A condição bonus = NULL é UNKNOWN, então não pode identificar um bônus ausente em um filtro WHERE.

V

Valor alternativo
Um valor alternativo é a substituição escolhida quando os dados preferenciais estão ausentes; ele deve ser adequado ao significado e ao tipo da saída.
Um relatório pode usar zero para um bônus não pago e manter uma avaliação não registrada como ausente em vez de inventar uma nota.
Valor de fronteira
Um valor de fronteira está em um limite entre categorias, então a escolha de < ou <= determina qual categoria o contém.
No limite 50, total < 50 é falso; mudar o teste para total <= 50 o torna verdadeiro.
Valor marcador
Um valor marcador é um valor registrado usado para representar informação ausente, como texto vazio, que pode precisar ser convertido em NULL.
NULLIF(phone, '') transforma uma cadeia de telefone vazia em NULL antes que um rótulo de exibição seja fornecido.
Verificação por amostragem
Uma verificação por amostragem compara saídas calculadas com resultados calculados à mão para algumas linhas conhecidas antes de confiar no relatório completo.
Adicionar LIMIT 5 durante a construção do relatório facilita localizar um espaço ausente ou um erro de divisão inteira.

Sobre esta aula

Por StudeliRelatar um erro

Crie seus próprios Materiais de Estudo

Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.

Começar