Blog do SQL Arena
Tutoriais de SQL
Fundamentos: SELECT e filtragem
4 artigosO que é SELECT … FROM no SQL? Ler de uma tabela para iniciantes
SELECT é o coração do SQL. Toda consulta começa aqui. Cobrimos a sintaxe, a escolha de colunas específicas, os aliases, os campos calculados, os erros comuns e três exercícios práticos.
O que é WHERE no SQL? Filtragem de linhas para iniciantes
WHERE é o filtro de linhas no SQL. Em linguagem simples e com muitos exemplos: =, IN, BETWEEN, LIKE, IS NULL e AND/OR. Tabelas antes e depois, armadilhas para iniciantes e uma prática rápida no final.
O que é LIMIT no SQL? Limitar o número de linhas para iniciantes
LIMIT limita o resultado de uma consulta a N linhas. Essencial para a paginação, as consultas top-N e as prévias. Cobrimos a sintaxe, OFFSET, as diferenças entre PostgreSQL e MySQL, os erros comuns e três exercícios práticos.
O que é ORDER BY no SQL? Ordenar os resultados de uma consulta para iniciantes
ORDER BY ordena o resultado de uma consulta SQL. Cobrimos ASC e DESC, a ordenação por várias colunas, os NULL na ordenação e o clássico ORDER BY + LIMIT para o top-N. Muitos exemplos e três exercícios.
Junção de tabelas (JOIN)
7 artigosO que é INNER JOIN no SQL? Juntar tabelas para iniciantes
INNER JOIN combina linhas de duas tabelas por uma chave compartilhada. O JOIN mais simples e mais comum. Cobrimos a sintaxe, a cláusula ON, as junções de várias tabelas, os erros comuns e três exercícios práticos.
O que é LEFT JOIN no SQL? Um guia para iniciantes
LEFT JOIN mantém todas as linhas da tabela esquerda; as correspondências ausentes à direita viram NULL. Cobrimos a sintaxe, a diferença em relação ao INNER JOIN, a busca de órfãos e três exercícios.
Aliases (AS) no SQL: aliases de tabelas e colunas para iniciantes
Os aliases são nomes curtos para tabelas e colunas no SQL. Tornam as consultas legíveis e se tornam obrigatórios ao fazer JOIN de tabelas com nomes de coluna compartilhados. Sintaxe, casos imprescindíveis, erros comuns e três exercícios.
SQL FULL OUTER JOIN: reconciliar dados e simular no MySQL
Um olhar prático sobre o FULL OUTER JOIN: obter todas as linhas dos dois lados, onde surgem os NULL, por que ele é perfeito para reconciliação e como simulá-lo no MySQL.
SQL CROSS JOIN: produtos cartesianos, geração de combinações e calendários
Um olhar prático sobre o CROSS JOIN: produtos cartesianos, geração de todas as combinações e calendários sem lacunas, além de como detectar cross joins acidentais.
Self-joins em SQL: juntando uma tabela com ela mesma
Use aliases de tabela para juntar uma tabela com ela mesma: hierarquias funcionário→gerente, comparar linhas dentro de uma tabela e gerar pares sem duplicatas.
Anti-joins em SQL: encontrar linhas sem correspondência
Três formas de encontrar linhas sem correspondência — LEFT JOIN / IS NULL, NOT EXISTS e NOT IN — e por que NOT IN quebra com NULL.
Agregação e agrupamento
25 artigosO que são COUNT, SUM, AVG, MIN, MAX em SQL? Funções de agregação para iniciantes
As funções de agregação são ferramentas para "calcular algo sobre um grupo de linhas". COUNT — quantas linhas, SUM — o total, AVG — a média, MIN/MAX — o menor e o maior. Em palavras simples: a diferença entre COUNT(*) e COUNT(coluna), como NULL afeta os agregados, cenários comuns e erros frequentes.
O que é GROUP BY em SQL? Agrupando linhas para iniciantes
GROUP BY é o comando do SQL para "colapsar linhas em grupos e agregar". Em palavras simples: como obter "quantos pedidos cada cliente tem" em uma única consulta. O que você pode e o que não pode colocar no SELECT, a diferença em relação ao DISTINCT, GROUP BY sobre várias colunas e os erros mais comuns.
O que é HAVING em SQL? Filtrando grupos para iniciantes
HAVING é o filtro que roda depois do GROUP BY e se aplica aos agregados. Em palavras simples: WHERE filtra as linhas de entrada, HAVING filtra os grupos de saída. Vamos ver a diferença, os padrões típicos (top-N, anomalias) e por que WHERE e HAVING são confundidos.
STRING_AGG no SQL: concatenar linhas agrupadas com um delimitador e ORDER BY
Como transformar muitas linhas em uma única string delimitada e na ordem certa, usando STRING_AGG do PostgreSQL, GROUP_CONCAT do MySQL e arrayStringConcat(groupArray()) do ClickHouse.
COUNT(*) FILTER (WHERE ...): agregados condicionais em uma unica passada
Como a clausula FILTER calcula varias metricas segmentadas em uma unica passada e substitui o CASE dentro do agregado.
ARRAY_AGG no PostgreSQL: agrupar valores em um array com ORDER BY e FILTER
Transforme as linhas de um grupo em um array ordenado com ARRAY_AGG, filtre e remova duplicatas, volte para linhas e conheca a alternativa no MySQL.
GROUPING SETS no SQL: subtotais e totais gerais em uma consulta
Use GROUPING SETS para calcular varios niveis de agrupamento em uma unica passagem e separar subtotais de NULLs reais.
ROLLUP no SQL: subtotais hierarquicos e um total geral em uma unica consulta
Como GROUP BY ROLLUP adiciona subtotais e uma linha de total geral a agregacao comum, e como ler os NULL finais com GROUPING().
PERCENTILE_CONT no PostgreSQL: mediana e percentis com WITHIN GROUP
Calcule a mediana e o p95 com uma unica agregacao PERCENTILE_CONT, com interpolacao, compare com PERCENTILE_DISC e veja por que ela supera o AVG.
UNNEST no PostgreSQL: expandir um array em linhas, WITH ORDINALITY e ARRAY_AGG
Expanda um array em linhas com UNNEST, obtenha um indice com WITH ORDINALITY, desaninhe varios arrays em paralelo e junte tudo de volta com ARRAY_AGG.
COUNT(DISTINCT) no SQL: contar valores unicos e seu custo
Como contar valores unicos com COUNT(DISTINCT), por que fica caro em escala e quando usar alternativas aproximadas com HLL.
BOOL_AND e BOOL_OR no PostgreSQL: agregados booleanos por grupo
Verifique "todas as linhas do grupo sao verdadeiras" com BOOL_AND e "ao menos uma" com BOOL_OR, veja como os NULL se comportam e como emular no MySQL e no ClickHouse.
EVERY no SQL: validar uma condicao para todo o grupo
EVERY e o sinonimo padrao de BOOL_AND: true quando a condicao vale para cada linha contada, NULL sobre um grupo vazio.
STDDEV no SQL: STDDEV_SAMP vs STDDEV_POP e deteccao de outliers
Como STDDEV_SAMP difere de STDDEV_POP, por que STDDEV puro e amostral, como calcular media +/- sd e achar outliers.
VARIANCE no SQL: VAR_SAMP versus VAR_POP e a relacao com STDDEV
Como VAR_SAMP e VAR_POP funcionam no PostgreSQL, por que VARIANCE equivale a VAR_SAMP e como a variancia se liga ao desvio padrao.
MODE() WITHIN GROUP no SQL: o valor mais frequente em uma expressao
Como achar o valor mais frequente com MODE() WITHIN GROUP, como empates sao resolvidos e por que e melhor que GROUP BY + COUNT + LIMIT 1.
PERCENTILE_DISC no SQL: percentis discretos sem interpolacao
Como PERCENTILE_DISC retorna um valor real dos seus dados sem interpolacao, como difere de PERCENTILE_CONT e quando escolher a variante discreta.
BIT_OR e BIT_AND no PostgreSQL: agregados bit a bit sobre mascaras de flags
Como BIT_OR reune todos os bits ativos de um grupo, BIT_AND encontra os comuns a todas as linhas e como ler o resultado com & em mascaras de permissoes.
JSON_AGG e JSONB_AGG no PostgreSQL: montar um array JSON para a resposta de API
Transforme linhas em um array JSON com JSON_AGG e JSONB_AGG, ordene o agregado, monte uma resposta de API aninhada em uma consulta e ignore os NULL.
JSONB_OBJECT_AGG no PostgreSQL: transforme linhas chave-valor em um unico objeto JSON
Transforme linhas chave-valor em um unico objeto JSON com JSONB_OBJECT_AGG, entenda o comportamento com chaves duplicadas e a diferenca para o JSONB_AGG.
CORR no SQL: o coeficiente de correlacao de Pearson em uma consulta
Como CORR(y, x) calcula a correlacao de Pearson, o que significam sinal e magnitude, como pares NULL sao tratados e como obter a reta de tendencia com REGR_*.
REGR_SLOPE e REGR_INTERCEPT no PostgreSQL: linha de tendencia e previsao em uma consulta
Construa uma linha de minimos quadrados no SQL com REGR_SLOPE e REGR_INTERCEPT, cuide da ordem (y, x), confira REGR_COUNT e faca previsoes sem um pacote estatistico externo.
REGR_R2 no SQL: R-quadrado e qualidade do ajuste da regressao
Como REGR_R2 mede a qualidade de uma regressao linear no SQL e por que ler esse valor junto com REGR_SLOPE.
Pivotar linhas em colunas com MAX/SUM FILTER no SQL
Transforme uma tabela longa em uma tabela cruzada larga com um unico GROUP BY usando agregados e a clausula FILTER.
CUBE no SQL: todas as combinacoes de agrupamento em uma passada para relatorios cross-tab
Como GROUP BY CUBE calcula todas as combinacoes de colunas de uma vez, por dimensao e total geral, e como ler subtotais NULL com GROUPING() e diferenciar CUBE de ROLLUP.
Subconsultas e DISTINCT
4 artigosO que é DISTINCT em SQL? Valores únicos para iniciantes
DISTINCT significa "remover duplicados". Em palavras simples: valores únicos de uma coluna ou de uma combinação de colunas, a diferença em relação ao GROUP BY, o tratamento de NULL e o DISTINCT ON específico do PostgreSQL para "uma linha por grupo". Com tabelas de antes/depois e erros comuns.
O que é IN com uma subconsulta em SQL? Verificação de pertencimento para iniciantes
IN com uma subconsulta filtra "linhas em que o valor de uma coluna aparece no resultado de outra consulta". Em palavras simples: filtrar por uma lista dinâmica, a diferença em relação a uma lista literal, a armadilha de NOT IN com NULL e a comparação com EXISTS. Com tabelas e erros comuns.
O que é EXISTS em SQL? Verificação de existência para iniciantes
EXISTS pergunta "existe pelo menos uma linha que satisfaça a condição?". Em palavras simples: um filtro sobre a presença de um registro relacionado (por exemplo, "clientes com pelo menos um pedido"), a diferença em relação a IN com uma subconsulta, NOT EXISTS e o comportamento com NULL.
O que é uma subconsulta escalar em SQL? Um único valor no SELECT para iniciantes
Uma subconsulta escalar é um SELECT que retorna exatamente um valor e se encaixa na posição de uma coluna ou em uma expressão WHERE. Em palavras simples: extrair um campo de uma tabela relacionada, adicionar um número de resumo a cada linha de um relatório, usá-la como constante em uma condição. Com tabelas e erros comuns.
Funções de janela
10 artigosO que é ROW_NUMBER no SQL? Numeração de linhas para iniciantes
ROW_NUMBER atribui "um número sequencial a cada linha". Em poucas palavras: a primeira função de janela que vale a pena aprender. Numeração decrescente, numeração dentro de grupos com PARTITION BY, o padrão clássico top-N por grupo e a remoção de duplicados. Com tabelas e erros comuns.
O que são RANK e DENSE_RANK no SQL? Classificação com empates para iniciantes
RANK e DENSE_RANK são funções de classificação em que valores iguais recebem a mesma posição. Em poucas palavras: a diferença entre ROW_NUMBER (sempre único), RANK (os empates recebem a mesma posição e depois deixam lacunas) e DENSE_RANK (a mesma posição sem lacunas). Com tabelas, um exemplo de estilo olímpico e erros comuns.
O que é PARTITION BY no SQL? Grupos dentro de uma janela para iniciantes
PARTITION BY é a parte de OVER que divide as linhas em grupos para as funções de janela. Em poucas palavras: é como GROUP BY, mas as linhas não são colapsadas: cada linha é mantida, com o agregado do seu grupo adicionado. A diferença em relação ao GROUP BY, os padrões típicos e o comportamento dos agregados dentro das janelas.
O que são LAG e LEAD no SQL? Linhas vizinhas em uma janela para iniciantes
LAG e LEAD retornam o valor da linha **anterior** ou **seguinte** de uma janela. Em poucas palavras: variação dia a dia, tempo até o próximo evento, mudança de preço: tarefas que antes exigiam juntar uma tabela com ela mesma. Com tabelas e erros comuns.
Frames de janela em SQL: ROWS/RANGE, totais acumulados e a armadilha do LAST_VALUE
Entenda como funcionam os frames ROWS e RANGE BETWEEN, construa totais acumulados e médias móveis, e evite a clássica armadilha do frame padrão do LAST_VALUE.
Funções de janela no SQL: ROW_NUMBER, RANK, LAG/LEAD na prática
As funções de janela são a ferramenta que um analista mais usa no SQL. Vamos destrinchar ROW_NUMBER, RANK, LAG/LEAD e PARTITION BY por meio de casos reais: top-N por grupo, métricas de um dia para o outro, somas acumuladas.
NTILE no SQL: quartis, decis e coortes em baldes iguais
Como NTILE(n) divide linhas ordenadas em n baldes quase iguais, para onde vai o resto e como difere de WIDTH_BUCKET.
FIRST_VALUE e LAST_VALUE no PostgreSQL: primeiro e ultimo valor por particao e a armadilha do frame
Pegue o primeiro e o ultimo valor de uma particao com FIRST_VALUE e LAST_VALUE e entenda por que LAST_VALUE retorna a linha atual sem um frame amplo.
PERCENT_RANK e CUME_DIST: percentis de um ranking no SQL
Como calcular a posicao relativa de uma linha no intervalo 0..1 com PERCENT_RANK e CUME_DIST de forma deterministica.
NTH_VALUE no PostgreSQL: o n-esimo valor da janela e o segundo maior por grupo
Pegue o n-esimo valor do quadro com NTH_VALUE, amplie o quadro como no LAST_VALUE, saiba onde FROM LAST e IGNORE NULLS realmente funcionam e calcule o segundo maior por grupo.
CTEs (WITH)
5 artigosO que é WITH … AS (CTE) em SQL? Expressões de tabela comuns para iniciantes
WITH … AS é um "resultado intermediário nomeado", também conhecido como CTE (Common Table Expression). Em palavras simples: uma forma de dividir consultas complexas em passos legíveis, reutilizar valores calculados e escrever SQL que você de fato vai querer reler mais tarde. Com tabelas e erros comuns.
Várias CTEs em uma única consulta: cadeias de WITH para iniciantes
Várias CTEs separadas por vírgulas permitem construir uma consulta como uma cadeia de etapas: você calcula uma coisa, constrói a próxima sobre ela e depois monta o resultado final. Em palavras simples: CTEs encadeadas, reaproveitamento de resultados intermediários e CTEs recursivas para hierarquias.
CTEs recursivas em SQL: WITH RECURSIVE para árvores, grafos e séries numéricas
Como o WITH RECURSIVE funciona: uma âncora mais um passo recursivo unidos por UNION ALL, percorrendo organogramas e grafos, gerando séries numéricas e ficando a salvo de loops infinitos.
LATERAL JOIN no PostgreSQL: top-N por grupo e subconsultas correlacionadas no FROM
Como LATERAL permite que uma subconsulta referencie colunas de tabelas anteriores do FROM, resolve o top-N por grupo e por que LEFT JOIN LATERAL ... ON true mantem as linhas externas.
generate_series no SQL: calendarios, sequencias numericas e preencher lacunas com zeros
Como o generate_series cria uma sequencia continua de inteiros, datas e timestamps e por que e a melhor forma de obter um eixo sem buracos.
Alteração de dados (DML)
10 artigosO que é INSERT em SQL? Adicionar linhas para iniciantes
INSERT é o comando SQL para "adicionar uma nova linha". Em palavras simples: sintaxe básica, inserções em lote de várias linhas de uma só vez, INSERT FROM SELECT, RETURNING para obter os IDs gerados e UPSERT por meio de ON CONFLICT para operações idempotentes. Com tabelas de antes/depois e erros comuns.
O que é UPDATE em SQL? Modificar linhas para iniciantes
UPDATE é o comando SQL para "alterar dados em linhas existentes". Em palavras simples: o que alterar, por que o WHERE é inegociável e como atualizar várias colunas de uma vez. Tabelas de antes/depois, erros típicos de iniciante, uma revisão rápida e três exercícios práticos no final.
O que é DELETE em SQL? Remover linhas para iniciantes
DELETE é o comando SQL para "remover linhas da tabela". Em palavras simples: o que remover, por que o WHERE é inegociável, soft-delete versus hard-delete, a diferença em relação a TRUNCATE e ON DELETE CASCADE. Tabelas de antes/depois, erros comuns, uma revisão rápida e três exercícios práticos.
UPSERT no PostgreSQL: INSERT ... ON CONFLICT na prática
Como inserir ou atualizar em um único comando com INSERT ... ON CONFLICT, usar EXCLUDED, escrever inserções idempotentes e construir contadores atômicos.
MERGE no PostgreSQL 15+: MATCHED / NOT MATCHED, upserts e sincronização de tabelas
Um olhar prático sobre o MERGE no PostgreSQL 15+: os ramos MATCHED e NOT MATCHED, os padrões de upsert e sincronização, e quando recorrer a ele em vez de ON CONFLICT.
INSERT ... ON CONFLICT DO NOTHING no PostgreSQL: insercoes idempotentes sem erros
Como ON CONFLICT DO NOTHING torna o INSERT idempotente, como o conflict target difere do nome de uma restricao, por que o RETURNING ignora linhas puladas e como semear dados em lote.
RETURNING no PostgreSQL: pegar ids e linhas alteradas sem um segundo round-trip
Como a clausula RETURNING em INSERT/UPDATE/DELETE devolve ids gerados e colunas alteradas em um unico round-trip, sem um SELECT extra.
DELETE ... USING no SQL: exclusoes com JOIN sem subconsulta
Como o DELETE ... USING filtra linhas contra outra tabela com um join, por que supera o WHERE IN com subconsulta e a forma multitabela do MySQL.
UPDATE ... FROM: atualizacoes em massa com join e subconsulta
Atualize uma tabela com dados de outra ou de um agregado, evitando a armadilha do WHERE ausente.
CTE + DELETE ... RETURNING: mova linhas em um unico comando
Arquive e mova linhas de forma atomica com CTEs que modificam dados, sem janela de corrida entre DELETE e INSERT.
Estrutura (DDL)
10 artigosO que é CREATE TABLE em SQL? Criar uma tabela para iniciantes
CREATE TABLE é o comando SQL para "criar uma nova tabela". Em palavras simples: quais colunas e de quais tipos, o que fazem NOT NULL, DEFAULT, PRIMARY KEY e FOREIGN KEY, e por que vale a pena pensar no esquema desde o início. Com tabelas de antes/depois, erros típicos de iniciante e três exercícios.
O que é ALTER TABLE no SQL? Alterar a estrutura de uma tabela para iniciantes
ALTER TABLE é o comando SQL para "alterar a estrutura de uma tabela existente". Em poucas palavras: adicionar uma coluna, removê-la, renomeá-la, mudar um tipo, adicionar e remover restrições. Além disso, a principal dor de cabeça em produção: os bloqueios prolongados de tabelas e o padrão adicionar → preencher → remover para migrações seguras.
Restricoes CHECK no SQL: invariantes no nivel do banco
Use CHECK para fixar regras de negocio no esquema: valores positivos, status validos, intervalos de datas e validacoes multicoluna.
FOREIGN KEY ON DELETE: CASCADE, SET NULL e RESTRICT na pratica
O que acontece com as linhas filhas ao apagar um pai e como escolher entre CASCADE, SET NULL, RESTRICT e NO ACTION sem perder dados.
NOT VALID + VALIDATE: adicionar restricoes sem locks longos
Adicione uma chave estrangeira ou CHECK a uma tabela grande em dois passos, sem parar as escritas.
Colunas geradas no PostgreSQL: GENERATED ALWAYS AS STORED
Como manter um valor derivado em um unico lugar com GENERATED ALWAYS AS (...) STORED, indexa-lo e escolhe-lo no lugar de um trigger ou uma view.
Indices UNIQUE parciais: unicidade sobre um subconjunto de linhas
Imponha unicidade apenas sobre algumas linhas: um registro ativo por chave, re-registro apos soft-delete e um unico default por grupo.
Particionamento por intervalo no PostgreSQL: tabelas temporais
Divida uma tabela enorme por intervalo de datas, descarte dados antigos em milissegundos e faca o planejador ler so as particoes necessarias.
Triggers no SQL: BEFORE/AFTER, NEW/OLD e o padrao updated_at
Como funcionam triggers BEFORE/AFTER e ROW/STATEMENT, o que a funcao retorna, o padrao auto-updated_at, o log de auditoria e quando triggers atrapalham.
Visoes materializadas no SQL: cache de consultas caras
Como uma visao materializada faz cache do resultado de uma consulta pesada, como o REFRESH funciona e quando uma view comum ou tabela resumo encaixa melhor.
Strings e datas
41 artigosO que são LOWER, UPPER e LENGTH no SQL? Funções de string para iniciantes
As funções de string são uma ferramenta diária do SQL: normalização de maiúsculas e minúsculas (LOWER, UPPER), comprimento (LENGTH), remoção de espaços (TRIM), substrings (SUBSTRING), substituição (REPLACE). Em poucas palavras: busca sem distinção de maiúsculas, limpeza de dados e armadilhas com Unicode.
O que é CONCAT no SQL? Concatenação de strings para iniciantes
CONCAT significa "juntar strings". Em poucas palavras: três formas (||, CONCAT, CONCAT_WS), como cada uma trata o valor NULL de maneira diferente e por que CONCAT_WS é a melhor escolha para endereços e nomes. Com tabelas e erros comuns.
O que é EXTRACT no SQL? Ano, mês e dia de uma data para iniciantes
EXTRACT extrai uma parte de uma data: ano, mês, dia, hora, dia da semana. Em poucas palavras: como agrupar por ano/mês, filtrar por dia da semana e contar segundos com EPOCH. Comparado com DATE_TRUNC e as diferenças entre PostgreSQL e MySQL.
DATE_TRUNC no SQL: truncar timestamps em periodos para series temporais
Como o DATE_TRUNC arredonda um timestamp para baixo ate hora, dia, semana, mes ou ano para agrupar series temporais.
NOW, CURRENT_DATE e aritmetica com INTERVAL no SQL
Como filtrar linhas dos ultimos 7 dias e do mes atual usando NOW(), CURRENT_DATE e aritmetica de INTERVAL no PostgreSQL, MySQL e ClickHouse.
Conversao de tipos em SQL: CAST e o operador :: no PostgreSQL
Como converter tipos em SQL com CAST e o atalho ::, arredondar numeric com cuidado, evitar erros de conversao e lidar com as diferencas entre PostgreSQL, MySQL e ClickHouse.
TRIM, SUBSTRING e REPLACE: limpeza de strings no SQL
Como aparar espacos, fatiar substrings e trocar caracteres para montar chaves normalizadas e remover formatacao.
SPLIT_PART no PostgreSQL: dividir uma string e pegar o N-esimo campo
Extraia o dominio de um email, um segmento de um caminho ou um codigo de um SKU com uma chamada a SPLIT_PART, alem dos equivalentes em MySQL e ClickHouse.
ILIKE no PostgreSQL: busca sem diferenciar maiusculas
Como o ILIKE funciona no PostgreSQL, por que supera lower(col) LIKE lower(...) e como acelera-lo com indices pg_trgm.
LEFT e RIGHT no SQL: primeiros e ultimos caracteres de uma string no PostgreSQL
Como LEFT e RIGHT pegam os primeiros ou ultimos N caracteres de uma string no PostgreSQL: mascarar cartoes, prefixos, comprimento negativo e comparacao com SUBSTRING.
POSITION e STRPOS no SQL: achar o indice de uma substring
Como achar a posicao de uma substring no SQL com POSITION e STRPOS, por que o resultado comeca em 1, o que significa 0 e como cortar com SUBSTRING.
LPAD e RPAD no SQL: preencher strings ate uma largura fixa
Como usar LPAD e RPAD para preencher strings ate uma largura fixa, fazer zero-padding de ids e numeros de nota, e montar colunas de largura fixa para exportacoes.
INITCAP no PostgreSQL: primeira letra de cada palavra em maiuscula
Como o INITCAP deixa a primeira letra de cada palavra em maiuscula no PostgreSQL, onde ele falha com apostrofos e hifens, e como imita-lo no MySQL.
REPEAT no SQL: repetir strings para separadores, placeholders e graficos de barras
Como REPEAT(str, n) repete uma string n vezes e por que e uma ferramenta util para separadores, placeholders e graficos de barras no SQL.
REVERSE no PostgreSQL: inverter strings, busca por sufixo e palindromos
Como REVERSE inverte uma string caractere a caractere, habilita busca por sufixo com indice, verifica palindromos e lida com multibyte.
char_length no SQL: contando caracteres, nao bytes
char_length retorna o numero de caracteres de uma string, octet_length o seu tamanho em bytes, e LENGTH conta caracteres ou bytes conforme PostgreSQL, MySQL ou ClickHouse.
REGEXP_REPLACE no SQL: limpeza de strings com regex e os flags g e i
Como o REGEXP_REPLACE troca substrings por padrao, o que fazem os flags g e i, como usar retroreferencias e onde POSIX e PCRE divergem.
REGEXP_MATCHES no PostgreSQL: grupos de captura e o flag g
Como REGEXP_MATCHES retorna grupos de captura em um array, o que o flag g faz e por que sem correspondencia a linha some.
REGEXP_SPLIT_TO_ARRAY: dividir strings por um delimitador regex
Como dividir strings por regex em array ou linhas e por que isso supera SPLIT_PART em dados baguncados.
TRANSLATE no SQL: mapeamento de caracteres, remocao e transliteracao
Como o TRANSLATE mapeia um conjunto de caracteres para outro, remove os excedentes e por que difere do REPLACE.
BTRIM, LTRIM e RTRIM no SQL: removendo espacos e qualquer caractere
Como remover espacos e caracteres arbitrarios das bordas de uma string com BTRIM, LTRIM e RTRIM e a relacao com o TRIM padrao.
A funcao FORMAT no SQL: templates de string com %s, %I e %L no PostgreSQL
Como montar strings a partir de um template com FORMAT no PostgreSQL: os especificadores %s, %I e %L, SQL dinamico seguro e por que supera a concatenacao.
STARTS_WITH no PostgreSQL: um teste de prefixo legivel em vez de LIKE
Por que STARTS_WITH le melhor que LIKE 'x%', como lida com caixa e indices, e como emula-lo em MySQL e ClickHouse.
ascii e chr no SQL: codigos e caracteres
ascii() retorna o ponto de codigo do primeiro caractere e chr() monta um caractere a partir de um codigo; no PostgreSQL ambos lidam com Unicode completo, enquanto MySQL e ClickHouse diferem.
to_hex no PostgreSQL: converter um inteiro em string hexadecimal
Como to_hex(int) transforma um numero em string hex para cores, mascaras de bits e depuracao de flags, como inverter e como MySQL e ClickHouse diferem.
AGE no SQL: diferenca entre datas como intervalo e idade em anos
A funcao AGE do PostgreSQL devolve a diferenca entre datas como anos, meses e dias, nao como dias brutos.
DATE_PART no SQL: partes numericas da data, dia da semana e campo dinamico
Como o DATE_PART retorna uma parte numerica da data, como difere do EXTRACT e por que dow numera o domingo como 0.
EXTRACT(EPOCH FROM ...) no SQL: duracoes em segundos e tempo Unix
Como EXTRACT(EPOCH FROM ...) transforma um intervalo em segundos totais e um timestamp em tempo Unix, por que esses dois casos diferem e como voltar com to_timestamp.
TO_CHAR no SQL: formatar datas e numeros como texto com modelos
Como o TO_CHAR converte uma data ou um numero em texto com um modelo: YYYY-MM-DD, HH24:MI, nomes de mes, separadores de milhar e as diferencas com o MySQL.
TO_DATE no PostgreSQL: converter uma string em data com modelo
Como converter uma string em data com TO_DATE e um modelo explicito, por que e mais seguro que um cast ::date, como mudou a validacao de intervalos no PostgreSQL 16 e a armadilha do ano de dois digitos.
TO_TIMESTAMP no SQL: parsear strings e montar timestamps a partir do epoch Unix
Dois modos do TO_TIMESTAMP: parsear uma string por modelo para timestamptz ou montar um momento a partir de segundos do epoch Unix, com seus detalhes de fuso.
CURRENT_TIMESTAMP e LOCALTIMESTAMP no SQL
Como CURRENT_TIMESTAMP difere de LOCALTIMESTAMP, por que ambos congelam na transacao e quando usar clock_timestamp().
CURRENT_DATE e CURRENT_TIME no SQL: a data de hoje e a hora atual
CURRENT_DATE e CURRENT_TIME sao valores especiais do SQL sem parenteses: a data de hoje e a hora com fuso.
Aritmetica de datas no SQL: somar dias, subtrair datas e intervalos
Como somar inteiros a datas, subtrair datas em dias e somar intervalos a timestamps no PostgreSQL, MySQL e ClickHouse.
make_date e make_time no SQL: montar datas e horas a partir de partes inteiras
Como montar uma data ou hora a partir de colunas inteiras separadas sem strings de formato e por que make_date valida partes fora do intervalo.
make_timestamp e make_interval no SQL: montar datas e intervalos por partes
make_timestamp monta uma data a partir de numeros e make_interval cria um intervalo com argumentos nomeados em vez de concatenar strings.
AT TIME ZONE no SQL: converter UTC armazenado para o horario local do usuario
O duplo comportamento do AT TIME ZONE: em timestamptz retorna o horario de parede local, em timestamp naive interpreta o valor naquela zona e retorna timestamptz.
JUSTIFY_INTERVAL no PostgreSQL: normalizando intervalos em dias e meses
JUSTIFY_HOURS, JUSTIFY_DAYS e JUSTIFY_INTERVAL transformam um intervalo bruto em dias e meses legiveis.
DATE_BIN no PostgreSQL: baldes de tempo de largura arbitraria para metricas
Como o DATE_BIN do PostgreSQL 14 arredonda um timestamp para o inicio de um balde de largura arbitraria a partir de uma origem, e quando ele supera o DATE_TRUNC.
O operador OVERLAPS no SQL: cruzamento de periodos e deteccao de conflitos
Como usar OVERLAPS para verificar se dois periodos de tempo se cruzam e encontrar conflitos de reservas e turnos no PostgreSQL.
timestamptz versus timestamp no SQL: guardar a hora certo
Por que eventos quase sempre devem ser timestamptz, como ele difere do timestamp ingenuo e como evitar perder a zona em silencio ao misturar os dois.
CASE e NULL
4 artigosO que é CASE WHEN em SQL? Lógica condicional para iniciantes
CASE WHEN é o "if/else dentro do SQL". Em palavras simples: como colocar condições diretamente no SELECT, a diferença entre o CASE de busca e o CASE simples, agrupar números em categorias, pivotar com uma única fórmula e os agregados condicionais. Com tabelas e erros comuns.
O que é COALESCE em SQL? Lidando com NULL para iniciantes
COALESCE retorna o primeiro valor não NULL de uma lista. Em palavras simples: valores padrão para dados ausentes, cadeias de fallback (apelido → nome → 'Convidado'), aritmética segura e a combinação com NULLIF. Com tabelas e erros comuns.
O que é NULLIF em SQL? Divisão segura e limpeza de dados para iniciantes
NULLIF retorna NULL se dois valores forem iguais. Em palavras simples: divisão segura por meio de NULLIF(x, 0), limpeza de valores marcadores como '' ou 'unknown', e a combinação com COALESCE para um tratamento limpo dos dados. Com tabelas e erros comuns.
NULL e IS DISTINCT FROM: comparacao segura com NULL no SQL
Por que = NULL nunca e verdadeiro e como IS DISTINCT FROM oferece igualdade segura com NULL.
Outros
53 artigosO operador JSONB @> no PostgreSQL: contencao de documentos e aceleracao com GIN
Como o operador @> verifica se um documento JSONB contem um fragmento, casa objetos aninhados e membros de arrays, usa indice GIN e difere de filtros com ->>.
ROUND(x, n) no SQL: arredondar casas decimais, n negativo e formatar moeda
Como ROUND(x, n) arredonda para n casas decimais, o que um n negativo faz e por que o PostgreSQL exige numeric em vez de double precision na forma de dois argumentos.
Indexando JSONB com GIN: jsonb_ops versus jsonb_path_ops
Como acelerar filtros sobre JSONB no PostgreSQL com indices GIN e quando escolher jsonb_path_ops no lugar da classe padrao.
Indices compostos no SQL: regra do prefixo a esquerda e ordem das colunas
Como um indice composto funciona pela regra do prefixo a esquerda, como ordenar colunas para filtro, ordenacao e intervalo, e quando ele vence dois indices simples.
Predicados sargaveis: como escrever um WHERE amigavel a indices
Por que envolver uma coluna em uma funcao anula o indice e como reescrever o WHERE em intervalos para o PostgreSQL usa-lo.
ROUND no SQL: arredondar para o inteiro mais proximo, arredondamento bancario e dinheiro
Como o ROUND arredonda para o inteiro mais proximo, por que half-away-from-zero difere do bancario e por que numeric supera double para dinheiro.
CEIL e CEILING no SQL: arredondar para cima ao inteiro
Como CEIL/CEILING arredonda para cima, calcula paginas de paginacao e cria buckets, e como difere de FLOOR e ROUND.
Apagar de JSONB no PostgreSQL: os operadores - e #-
Como os operadores - e #- removem chaves, elementos de array e valores aninhados de um JSONB.
JSONB_BUILD_OBJECT no PostgreSQL: montar um objeto JSON a partir de colunas com tipos
Monte um objeto JSON a partir de pares chave/valor com tipos preservados, modele payloads por linha, aninhe objetos e arrays e compare com to_jsonb.
jsonb_build_array no PostgreSQL: montando arrays JSON com tipos mistos
Como montar arrays JSON a partir de argumentos de qualquer tipo, aninhar com jsonb_build_object e nao confundir com to_jsonb de um array SQL.
Operadores seta do JSONB: -> e ->> no PostgreSQL
Como funcionam -> e ->>: ler campos de objeto e elementos de array, descer por estruturas aninhadas encadeando e converter o resultado ao tipo certo.
ABS no SQL: valor absoluto, diferencas e checagens com tolerancia
Como ABS calcula a magnitude, mede a diferenca entre dois valores, atua no WHERE com tolerancia e combina com SIGN.
jsonb_array_length no PostgreSQL: contar elementos de um array JSON com seguranca
Como jsonb_array_length conta elementos de um array JSON, por que gera o erro non-array, como proteger com jsonb_typeof e filtrar linhas por tamanho.
jsonb_array_elements: expandir um array JSON em linhas no PostgreSQL
Como expandir um array JSON em uma linha por elemento, filtrar e juntar por itens, obter o indice com WITH ORDINALITY e quando usar a variante _text.
EXP e LN no SQL: exponencial, logaritmo natural e medias geometricas
Como EXP e LN calculam e^x e o logaritmo natural, por que o par log/exp serve para medias geometricas e taxas de crescimento, e por que LN(0) falha.
JSONB_AGG no PostgreSQL: agrupar linhas em um array JSON para suas JSON APIs
Transforme as linhas de um grupo em um array JSON com ORDER BY e FILTER, aninhe um documento com uma subconsulta correlacionada e troque o grupo vazio por '[]'.
FLOOR no SQL: arredondar para baixo ate o inteiro anterior e agrupar em buckets
Como o FLOOR arredonda um numero para baixo ate o inteiro anterior, por que negativos se afastam do zero e como difere de TRUNC.
UNION e UNION ALL no SQL: combinando resultados de consultas
Como UNION e UNION ALL se diferenciam, quais regras de compatibilidade de colunas seguir e como ordenar o resultado combinado.
GREATEST e LEAST no SQL: maximo e minimo por linha entre colunas
Como GREATEST e LEAST retornam o maximo e o minimo dentro de uma linha, limitam um valor a um intervalo e tratam NULL de forma diferente em PostgreSQL, MySQL e ClickHouse.
Divisao inteira no SQL: DIV, MOD e a armadilha do cast
Como funciona a divisao inteira no PostgreSQL e no MySQL, quando usar DIV e como combina-la com MOD para obter quociente e resto juntos.
INTERSECT no SQL: linhas presentes em ambas as consultas
Como o operador INTERSECT encontra linhas comuns a duas consultas, como difere do INTERSECT ALL e quando um JOIN ou EXISTS encaixa melhor.
EXCEPT no SQL: diferenca de conjuntos e o equivalente MINUS do Oracle
Como o EXCEPT retorna as linhas da primeira consulta que nao estao na segunda, como difere de EXCEPT ALL e quando usar NOT EXISTS.
Extraindo JSONB como texto: o operador ->> no PostgreSQL
Como obter um campo escalar de JSONB como texto com ->>, como ele difere de ->, como converter o resultado e filtrar por campos JSON.
CREATE INDEX CONCURRENTLY: indexar sem downtime no PostgreSQL
Como construir um indice em uma tabela quente sem um lock de escrita pesado e o que fazer com o indice INVALID que uma construcao falha deixa para tras.
EXPLAIN (ANALYZE, BUFFERS) no PostgreSQL: lendo o plano real da consulta
Como ler EXPLAIN (ANALYZE, BUFFERS): linhas e tempo reais contra estimados, loops, e o desvio que denuncia estatisticas obsoletas ou indice ausente.
SELECT ... FOR UPDATE: bloqueio pessimista de linhas no SQL
Como bloquear linhas com SELECT ... FOR UPDATE, evitar deadlocks e montar uma transferencia de dinheiro correta.
UPDATE condicional no SQL: verificacao e escrita atomica com WHERE
Codifique uma precondicao no WHERE de um unico UPDATE, detecte a falha pela contagem de linhas afetadas e evite updates perdidos: compare-and-swap no SQL.
Contador atomico: UPDATE SET n = n + 1 sem perder atualizacoes
Por que read-modify-write perde incrementos sob carga e como um unico UPDATE SET n = n + 1 mantem o contador correto sob concorrencia.
GRANT no SQL: privilegios em tabelas, esquemas e colunas com menor privilegio
Como conceder privilegios em tabelas, esquemas e colunas com GRANT, a diferenca entre privilegios de objeto e participacao em papel, e como projetar acesso com menor privilegio.
REVOKE no SQL: revogar privilegios concedidos com seguranca
Como usar REVOKE para retirar privilegios concedidos, lidar com CASCADE e RESTRICT e nao esquecer do acesso via PUBLIC e papeis.
CREATE ROLE no PostgreSQL: usuarios, grupos e heranca de permissoes
Como uma unica instrucao CREATE ROLE modela pessoas e grupos: LOGIN versus NOLOGIN, pertinencia a roles, heranca e atributos como CREATEDB.
Role somente leitura no PostgreSQL: permissoes corretas para analytics e BI
Como criar uma role somente leitura para analistas: USAGE no schema, SELECT nas tabelas e ALTER DEFAULT PRIVILEGES para as tabelas futuras.
WIDTH_BUCKET no SQL: histogramas de largura fixa e distribuicoes
Como o WIDTH_BUCKET distribui valores em faixas de largura fixa, trata os limites e gera distribuicoes com GROUP BY.
TRUNC no SQL: descartar a parte fracionaria em direcao a zero sem arredondar
Como o TRUNC corta a parte fracionaria em direcao a zero, como TRUNC(x, n) recorta casas decimais e por que difere do FLOOR em negativos.
to_jsonb no PostgreSQL: transformar uma linha inteira em objeto JSON
Como to_jsonb converte qualquer valor, linha ou array em jsonb preservando os tipos, e como difere de json_build_object e row_to_json.
SQRT no SQL: raiz quadrada, distancia euclidiana e desvio padrao
Como o SQRT funciona no PostgreSQL, por que um argumento negativo gera erro e como calcular distancia euclidiana e desvio padrao na mao.
SIGN no SQL: o sinal de um numero e ramificacao por direcao
Como SIGN retorna -1/0/1, como ramificar pela direcao da mudanca e por que combinar SIGN com ABS.
A funcao POWER no SQL: potencias, raizes e crescimento composto
Como usar POWER para potencias, raizes fracionarias e calculos de crescimento composto no PostgreSQL, MySQL e ClickHouse.
MOD e o operador % no SQL: o resto da divisao na pratica
Como MOD e o operador % calculam o resto: par/impar, cada N-esima linha, sharding por id e a regra do sinal com negativos.
LOG no SQL: logaritmo na base 10 e base arbitraria, e a armadilha do MySQL
Como LOG(x) na base 10 e LOG(b, x) em base arbitraria funcionam no PostgreSQL, por que LOG no MySQL e uma armadilha e onde logaritmos ajudam.
JSONB_TYPEOF no PostgreSQL: lidar com JSON dinamico sem quebrar
Como o jsonb_typeof retorna o tipo de um valor JSON como texto e protege jsonb_array_length, aritmetica e validacao de dados.
JSONB_SET no PostgreSQL: atualizar um campo dentro de um documento JSON
Substitua um valor por caminho no JSONB, adicione uma chave ausente com create_missing, atualize um campo aninhado com UPDATE e remova chaves com o operador menos.
jsonb_pretty no PostgreSQL: saida JSONB legivel
Como formatar JSONB com indentacao usando jsonb_pretty para depurar no psql e quando nao usar.
Operadores de caminho JSONB no PostgreSQL: #> e #>> para valores aninhados
Como ler valores JSONB profundamente aninhados no PostgreSQL com os operadores de caminho #> e #>>, misturar chaves e indices e quando usar jsonb_path_query.
JSONB_OBJECT_KEYS no PostgreSQL: listar as chaves de um objeto JSON como linhas
Expanda as chaves de nivel superior de um objeto JSONB em linhas, descubra o formato dos dados, verifique quais campos existem e reuna chaves com array_agg.
Operadores de existencia de chaves JSONB no PostgreSQL: ?, ?| e ?&
Como verificar chaves em JSONB com ?, ?| e ?&, acelerar com indice GIN e escapar da armadilha dos placeholders.
JSONB_EACH no PostgreSQL: expanda um objeto JSON em linhas chave-valor
Use jsonb_each para expandir um objeto JSON em linhas (chave, valor), percorrer chaves dinamicas, filtrar e agregar entradas e saber quando usar a variante _text.
O operador JSONB || no PostgreSQL: mesclar documentos e aplicar patches
Como o operador || faz uma mesclagem rasa de JSONB onde as chaves da direita vencem, adiciona a um array e aplica um patch parcial em uma so expressao.
RANDOM() no SQL: amostragem aleatoria, inteiros e seed
Como o RANDOM() funciona no PostgreSQL, por que ORDER BY RANDOM() e lento em escala e o que usar no lugar.
NOT EXISTS x NOT IN: a armadilha do NULL e anti-joins
Por que NOT IN retorna vazio em silencio quando a subconsulta tem um NULL, e quando escolher NOT EXISTS ou LEFT JOIN ... IS NULL.
Índices parciais no PostgreSQL: indexando apenas as linhas quentes
Como CREATE INDEX ... WHERE permite cobrir apenas as linhas ativas para um índice menor e mais rápido, além de um UNIQUE parcial que combina bem com exclusões lógicas.
Como ler planos de consulta: EXPLAIN e EXPLAIN (ANALYZE, BUFFERS)
Um guia prático sobre os planos de consulta do PostgreSQL: Seq Scan versus Index Scan, linhas estimadas versus reais e como detectar um índice ausente.
Filas de tarefas em SQL: SELECT ... FOR UPDATE SKIP LOCKED
Como fazer uma dúzia de workers puxarem tarefas de uma tabela de fila com segurança, sem bloquearem uns aos outros, usando FOR UPDATE SKIP LOCKED no PostgreSQL.