- Aprender
- Computação e TI
- Programação
- Noções básicas de SQL
- Colunas calculadas e funções em SQL
Colunas calculadas e funções em SQL: expressões CASE
BásicoAula 3 de 6 do curso Curso de Noções básicas de SQL
O que você vai aprender
- 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 apelidosEscreva 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éricasUse +, -, *, / 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 dadosReconheç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.
- Calcular novas colunas e nomeá-las com apelidos
- 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çõesExplique 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 NULLIFPreencha lacunas com COALESCE, transforme zeros e valores marcadores em NULL com NULLIF e escolha valores de substituição que preservem o significado dos dados.
- Prever o comportamento de NULL em cálculos e condições
- 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 textoConcatene 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 textosConte caracteres, encontre onde um caractere aparece e recorte partes de texto usando posições que começam em 1.
- Concatenar e limpar valores de texto
- 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 horaConheç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 datasExtraia 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 datasAdicione dias e meses, meça o tempo entre duas datas e escreva filtros de data que incluam todas as linhas de um período.
- Escrever, armazenar e ler valores de data e hora
- 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 pesquisadoEscreva 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 consultaTraduza 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órioConstrua um relatório com várias colunas calculadas passo a passo, aninhe funções corretamente e confira cada coluna com linhas calculadas à mão.
- Classificar linhas em categorias com CASE pesquisado
Guia de estudo de Colunas calculadas e funções em SQL
1Criar 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ção | Significado | Exemplo |
|---|---|---|
ABS | Distância de zero | ABS(-4.2) resulta em 4.2 |
CEIL | Menor inteiro que não é menor que o valor | CEIL(4.1) resulta em 5 |
FLOOR | Maior inteiro que não é maior que o valor | FLOOR(-4.1) resulta em -5 |
TRUNC | Remove a fração em direção a zero | TRUNC(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ão | SQLite | PostgreSQL |
|---|---|---|
CAST(3.9 AS INTEGER) | 3 | 4 |
CAST(-3.9 AS INTEGER) | -3 | -4 |
CAST('abc' AS INTEGER) | 0 | Erro |
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.
2Tratar 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ção | Resultado | Motivo |
|---|---|---|
FALSE AND UNKNOWN | FALSE | Um requisito falso torna AND falso |
TRUE AND UNKNOWN | UNKNOWN | O segundo requisito permanece indefinido |
TRUE OR UNKNOWN | TRUE | Uma alternativa verdadeira torna OR verdadeiro |
FALSE OR UNKNOWN | UNKNOWN | A alternativa restante permanece indefinida |
NOT UNKNOWN | UNKNOWN | Negar 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.
3Limpar, 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 dados | CONCAT('Ana', NULL, 'Lopez') |
|---|---|
| PostgreSQL, SQL Server, SQLite a partir da versão 3.44 | 'AnaLopez' |
| MySQL | NULL |
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.
4Trabalhar 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 SQLite | Resultado 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.
5Classificar 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.
| Pedido | Cliente | Quantidade | Preço | Desconto % | Data do pedido | Data de envio |
|---|---|---|---|---|---|---|
| 1001 | Ana Lopez | 3 | 12,50 | 10 | 2026-03-14 | 2026-03-17 |
| 1002 | Ben Okafor | 1 | 240,00 | 0 | 2026-03-30 | NULL |
| 1003 | Chen Wu | 12 | 4,25 | NULL | 2026-04-02 | 2026-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 é:
| Pedido | Cliente | Total líquido | Mês | Dias | Envio |
|---|---|---|---|---|---|
| 1001 | Ana Lopez | 33,75 | 2026-03 | 3 | standard |
| 1002 | Ben Okafor | 240,0 | 2026-03 | NULL | not shipped |
| 1003 | Chen Wu | 51,0 | 2026-04 | 1 | fast |
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
1Construir e verificar o valor de um item do pedido com desconto
16 passos
- 1Introduçã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.
- 2ExplicaçãoComece com uma expressão
Uma expressão combina valores para produzir outro valor. Aqui,
quantity * unit_priceusa 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.0no SQLite. Cada outra linha fornece suas próprias entradas; a consulta não grava esses totais de volta na tabela. - 3Conexã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, enquantoUPPER(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.
- 4DicaNomeie o resultado com clareza
AS net_totalé um apelido simples e legível. Use aspas duplas quando um nome tiver espaço, como emAS "Net Total". Aspas simples identificam valores de texto.Mantenha uma vírgula entre as expressões de saída.
SELECT quantity unit_priceretorna 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. - 5DesafioPosicione 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 usargross_total > 50? E ORDER BY pode usargross_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 usargross_total DESC. SQLite permite o apelido em WHERE como extensão, mas PostgreSQL não. - 6ExemploTransforme 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 como1 - discount_pct / 100.0.quantity * unit_price * (1 - discount_pct / 100.0)A divisão resulta em
0.2; os parênteses resultam em0.8; a multiplicação resulta em um valor líquido de48.0. Os parênteses mantêm a subtração agrupada como um multiplicador. - 7Ideia-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 calculam20 / 100como 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.0na própria divisão. Converter o quociente depois de calculado altera seu tipo, mas não recupera a fração perdida. - 8DesafioEncontre 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.0retorna e como a expressão deve calcular o percentual?---reveal---
Ela retorna
0.0: a divisão inteira9 / 12torna-se 0 primeiro. Escrevacompleted * 100.0 / assigned, que resulta em75.0. A conversão deve ocorrer antes da divisão, não apenas antes da exibição final. - 9Explicaçã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. - 10DicaVerifique 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, escrevaROUND(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.
- 11Explicaçã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 comCAST('28' AS INTEGER). O número pode se tornar texto comCAST(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. - 12ExemploMantenha identificadores separados de quantidades
Suponha que um campo armazene o código postal dos Estados Unidos
'00421'. Convertê-lo em inteiro resulta em421, 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. - 13DesafioInterprete 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.
- 14Ideia-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.
- 15DesafioVerifique 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.0no SQLite.ORDER BY net_totalé válido tanto no SQLite quanto no PostgreSQL porque a ordenação pode ver o apelido de SELECT. - 16Recapitulaçã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.
2Acompanhar dados ausentes em uma consulta
12 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoUm valor ausente altera mais do que uma célula
- 2ExplicaçãoNULL é uma entrada desconhecida
- 3ExemploUse um teste que verifique a ausência
- 4Ideia-chaveWHERE aceita apenas TRUE
- 5DesafioCombine uma condição conhecida com uma desconhecida
- 6DicaNão deixe NULL em uma lista de exclusão
- 7ExplicaçãoEscolha um valor alternativo pelo significado
- 8ExemploMantenha consistente o tipo de exibição
- 9ExemploTransforme um denominador zero em uma lacuna
- 10DesafioLimpe texto vazio antes de atribuir o rótulo
- 11DesafioSepare uma escolha de exibição de uma escolha de filtro
- 12RecapitulaçãoMantenha visível o significado de uma lacuna
3Limpar um nome e extrair um domínio de e-mail
14 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTorne o texto utilizável sem perder suas partes
- 2ExemploForneça o espaço entre os nomes
- 3ExplicaçãoDecida o efeito de uma parte ausente do nome
- 4ExemploLimpe o e-mail de dentro para fora
- 5DesafioEscolha entre remover espaços das extremidades e substituir
- 6DicaVerifique as regras de caracteres e de dialeto
- 7ExplicaçãoConte a partir de um
- 8ExemploLocalize o separador
- 9ExemploExtraia os caracteres antes e depois de @
- 10DesafioEncontre o resultado com erro de uma posição
- 11Ideia-chaveUm resultado de busca zero precisa de tratamento próprio
- 12DicaExtraia finais e preencha códigos no dialeto correto
- 13DesafioCombine limpeza com extração
- 14RecapitulaçãoAcompanhe os caracteres exatos
4Criar rótulos de data e filtros de período confiáveis
18 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoSepare o valor do calendário de seu rótulo
- 2ExplicaçãoEscolha uma representação clara de data
- 3ExemploLeia um formato local fixo
- 4DesafioExplique qual texto é ordenado por data
- 5DicaVerifique a interpretação e a referência da hora atual
- 6ExemploExtraia o mês com o tipo de retorno correto
- 7ExplicaçãoMantenha o ano no rótulo de mês
- 8ExemploCrie uma exibição sem alterar a ordenação
- 9DesafioEncontre o trimestre correto
- 10ConexãoEscolha a convenção de numeração dos dias da semana
- 11ExemploAdicione dez dias à reserva
- 12Ideia-chaveUm mês não é uma quantidade fixa de dias
- 13ExemploMeça dias e horas em unidades adequadas
- 14DesafioInclua a última tarde do mês
- 15ExplicaçãoConte aniversários que realmente chegaram
- 16DicaLeia datas relativas como limites que mudam
- 17DesafioCombine um prazo com a seleção de um mês
- 18RecapitulaçãoVerifique o tipo, a regra do calendário e os extremos
5Atribuir rótulos a pedidos e construir o relatório final
17 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoDê a cada pedido um rótulo útil
- 2ExplicaçãoEscolha a primeira condição verdadeira
- 3ExemploAcompanhe o limite exato
- 4Ideia-chaveELSE também pode capturar um valor desconhecido
- 5DesafioCorrija uma faixa pequena oculta
- 6DicaRetorne resultados compatíveis
- 7ExemploTraduza um valor de status
- 8DesafioPor que WHEN NULL não encontra a linha?
- 9ExemploOrdene a prioridade por classificação
- 10Ideia-chaveUm indicador pode unir casos conhecidos e desconhecidos
- 11ExemploComece o relatório com entradas conhecidas
- 12ExemploCalcule primeiro o valor líquido
- 13ExemploAdicione datas com uma regra separada para ausência
- 14DesafioVerifique uma segunda linha com ambas as regras
- 15ConexãoAdapte as expressões de data para PostgreSQL
- 16DesafioFiltre o valor que o relatório realmente mostra
- 17RecapitulaçãoVerifique o relatório como um conjunto de escolhas explícitas
Questões de Colunas calculadas e funções em SQL
Conjunto 1: Limpar textos e trabalhar com valores de calendário10 Questões de Prática
Questão 1 de 10
LOWER(TRIM(' RAE@Mail.COM ')) retorna no SQLite?Mostrar respostaOcultar resposta
'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
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?Mostrar respostaOcultar resposta
|| 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
SUBSTR('Seattle', 3, 3) retorna?Mostrar respostaOcultar resposta
'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
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?Mostrar respostaOcultar resposta
>= 0 também aceita um separador ausente, cuja posição é zero, e retornaria toda a cadeia malformada.Questão 5 de 10
Mostrar respostaOcultar resposta
'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
date('2027-04-31')?Mostrar respostaOcultar resposta
'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
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?Mostrar respostaOcultar resposta
'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
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?Mostrar respostaOcultar resposta
Questão 9 de 10
d no SQLite é '2027-04-24'. O que date(d, '+10 days') retorna?Mostrar respostaOcultar resposta
'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
Mostrar respostaOcultar resposta
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
units e unit_cost. Qual lista SELECT retorna o produto deles com o cabeçalho extended_cost?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
SELECT 14 + 5 * 3; retorna no SQLite?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
units = 5 e discount_pct = 12, com price = 18.0. Que resultado ROUND(units * price * (1 - discount_pct / 100), 2) produz?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
CAST('27boxes' AS INTEGER)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
delivery_date registrada?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
region: 'East', 'West', NULL e 'North'. Quantas linhas satisfazem WHERE NOT (region = 'East')?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
'unlisted' no SQLite. Qual expressão faz isso preservando os números registrados?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
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?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
score = 75: CASE WHEN score < 60 THEN 'review' WHEN score < 80 THEN 'ready' ELSE 'strong' END?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
CASE WHEN amount < 500 THEN 'regular' WHEN amount < 100 THEN 'small' ELSE 'large' END nunca retorna 'small' para valores diferentes de NULL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
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'?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
'urgent', 'normal' e 'deferred' nessa ordem, com todas as outras prioridades ou prioridades NULL por último. Qual expressão ORDER BY atende a isso?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
'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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
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?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
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
reading no PostgreSQL é DOUBLE PRECISION. Como um relatório pode arredondá-la para duas casas decimais sem um erro de assinatura de função?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
COALESCE(NULL, '', 'backup') retorna no SQLite?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
email = 'nora@research.org'. Que resultado SUBSTR(email, INSTR(email, '@')) produz?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
'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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
'2027-05-08 10:15:00' até '2027-05-08 13:45:00'. O que (unixepoch(end_time) - unixepoch(start_time)) / 3600.0 retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
d. Como ele pode calcular o trimestre para cada mês?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
(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?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Travou em uma questão sua? Ajuda com Tarefas
Termos-Chave
A
Afinidade de tipo
Aninhamento de funções
ROUND(COALESCE(amount, 0), 2), o valor alternativo é resolvido antes que a função de arredondamento receba sua entrada.Apelido de coluna
AS line_total e pode ordená-lo com ORDER BY line_total.C
Cadeia de caracteres
' New York ' inclui espaços nas extremidades e dois espaços internos que afetam seu comprimento.CASE pesquisado
CASE WHEN total < 50 THEN 'small' ELSE 'large' END escolhe um rótulo a partir do valor da linha.CASE simples
CASE status WHEN 'S' THEN 'Shipped' ELSE 'Other' END traduz um código de status armazenado.CEIL
CEIL(4.1) resulta em 5 porque quatro está abaixo da entrada e cinco é o próximo inteiro.COALESCE
COALESCE(mobile_phone, home_phone, 'no phone') usa o número residencial se o número de celular estiver ausente.Colação
'Boston' = 'boston' verdadeiro quando o SQLite padrão não o faz.Coluna calculada
quantity * unit_price AS line_total mesmo quando a tabela não tem uma coluna line_total.Comparação segura com NULL
NULL IS NOT DISTINCT FROM NULL é TRUE no PostgreSQL e no SQLite a partir da versão 3.39.Concatenação
first_name || ' ' || last_name insere um espaço entre as duas partes registradas do nome.Consulta para relatório
Conversão entre maiúsculas e minúsculas
LOWER(TRIM(email)) torna consistente um endereço de e-mail ASCII limpo para uma comparação com letras normalizadas.Conversão explícita
CAST(quantity AS REAL) / 4 altera o operando no SQLite antes que a divisão possa perder uma fração.Conversão implícita
'Order #' || 42, produzindo o rótulo 'Order #42'.D
DATE
DATE '2026-03-14' identifica explicitamente 14 de março de 2026 como um valor de data no PostgreSQL.Divisão inteira
7 / 2 produz 3; tornar o segundo operando 2.0 preserva a fração e produz 3,5.E
Expressão
quantity * unit_price é uma expressão que produz o valor do item do pedido para cada linha.EXTRACT
EXTRACT(MONTH FROM DATE '2026-03-14') do PostgreSQL retorna o valor numérico de mês 3.F
FLOOR
FLOOR(-4.1) é -5, então difere de simplesmente descartar a fração.Formato de data ISO
'2026-03-14' tem zeros iniciais e é ordenado antes de '2026-11-02' em ordem de data.Função escalar
UPPER(city) em SELECT altera o texto da cidade exibido para cada cliente retornado pela consulta.I
Idade em anos completos
Indicador numérico
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END atribui zero tanto a descontos ausentes quanto a descontos não positivos.INSTR
INSTR('ana@example.com', '@') resulta em 4, enquanto uma cadeia sem @ produz zero.Intervalo de tempo
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
ordered_at >= '2026-03-01' AND ordered_at < '2026-04-01' inclui todos os timestamps de março.IS NULL
WHERE phone IS NULL recupera clientes sem telefone registrado sem comparar um valor com NULL usando igualdade.L
LENGTH
LENGTH(' Bo ') resulta em 4 porque os dois espaços nas extremidades contam, assim como as duas letras.Literal
first_name || ' ' || last_name é um literal de texto fornecido pela consulta.Lógica de três valores
FALSE AND UNKNOWN é FALSE, mas TRUE AND UNKNOWN permanece UNKNOWN porque o segundo requisito está indefinido.M
Máscara de formatação
'%m/%d/%Y' para um rótulo de data dos Estados Unidos; TO_CHAR do PostgreSQL usa 'MM/DD/YYYY'.N
NULL
salary + bonus desconhecido mesmo que o salário do funcionário esteja registrado.NULLIF
NULLIF(visits, 0) mantém contagens positivas de visitas, mas transforma zero em um divisor ausente para uma taxa.Número de ponto flutuante
0.1 + 0.2 = 0.3 falso porque as aproximações armazenadas não somam o mesmo valor.Número do dia juliano
julianday(end_date) - julianday(start_date) em vez de subtrair cadeias de data ISO diretamente.O
Ordem lógica de processamento da consulta
P
Posição do caractere
'ana@example.com' está na posição 4, então o domínio começa na posição 5.Precedência de operadores
10 + 3 * 2, então o resultado é 16 em vez de 26.Preenchimento com caracteres
LPAD('42', 5, '0') do PostgreSQL retorna '00042', dando cinco caracteres a um código curto.Prioridade de ordenação personalizada
R
Ramo WHEN
< 200 primeiro pode impedir que um ramo posterior < 50 seja selecionado.REPLACE
REPLACE('555-0100', '-', '') remove o hífen e exibe '5550100' sem editar a tabela.Resto da divisão (módulo)
135 % 60 fornece os 15 minutos restantes após duas horas completas.Resultado alternativo de ELSE
ELSE 'large' a menos que um ramo anterior teste explicitamente total IS NULL.Rótulo de ano e mês
'2026-03' mantém março de 2026 separado de março de 2025 na exibição de um relatório.ROUND
ROUND((price - cost) / price * 100, 1) para exibir uma margem com uma casa decimal.S
strftime
strftime('%m', '2026-03-14') retorna '03', que deve ser comparado com texto ou convertido antes do uso numérico.Subcadeia de caracteres
SUBSTR('Boston', 1, 3) retorna 'Bos', extraindo três caracteres a partir da primeira posição.T
Tempo Universal Coordenado (UTC)
Tempo Unix
3600.0 para manter horas fracionárias em uma duração.Texto numérico
'10', '100' e '9' aparecem nessa ordem crescente de texto, que difere da ordem numérica.TIMESTAMP
'2026-03-31 14:05:00' é posterior à meia-noite no início de 31 de março.Tipo de dados
'42' e o inteiro 42 podem parecer iguais em uma grade, mas se comportam de forma diferente em SQL.TRIM
TRIM(' New York '), os dois espaços entre as palavras permanecem no texto retornado.U
UNKNOWN
bonus = NULL é UNKNOWN, então não pode identificar um bônus ausente em um filtro WHERE.V
Valor alternativo
Valor de fronteira
total < 50 é falso; mudar o teste para total <= 50 o torna verdadeiro.Valor marcador
NULLIF(phone, '') transforma uma cadeia de telefone vazia em NULL antes que um rótulo de exibição seja fornecido.Verificação por amostragem
LIMIT 5 durante a construção do relatório facilita localizar um espaço ausente ou um erro de divisão inteira.- 1Modelo relacional
- 2Consultas com SELECT
- 3Colunas calculadas e funções em SQL
- 4Agregação e agrupamento em SQL
- 5Junções SQL
- 6Criação de tabelas e alteração de dados
Sobre esta aula
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.