Módulo 1: Ler dados no Postgres
SELECT, WHERE, ORDER BY, LIMIT/OFFSET, DISTINCT e as manias do Postgres
Antes de começar
O básico de leitura é idêntico ao da Trilha 1: SELECT colunas FROM tabela
WHERE condição. O que muda no Postgres são detalhes que, se você não souber,
travam sua query:
- Aspas. Texto vai entre aspas simples:
'SP'. Aspas duplas são pra nome de coluna/tabela ("Nome Estranho"). Se você escrever"SP"o Postgres procura uma coluna chamada SP e dá erro. - Cast rápido com
:::'2025-03-01'::date,valor_total::int. É o jeito curto deCAST(x AS tipo). LIMIT n OFFSET m: pega n linhas, pulando as m primeiras (paginação).ILIKE: igual aoLIKE, mas ignora maiúsc./minúsc. (só existe no Postgres).
Olhar de QA: toda investigação começa com um
SELECT ... WHERE: "me mostra as linhas onde algo está estranho".
Dois exemplos pra ver funcionando
Já rodam sozinhos quando o banco carrega. Mexe à vontade e clique Rodar de novo.
Teoria
SELECT colunas FROM tabela: o quê e de onde.SELECT *= todas as colunas.WHERE condição: filtra linhas.=<>><>=<=,AND,OR,NOT.BETWEEN a AND b: intervalo inclusivo.IN (v1, v2, …): valor numa lista.LIKE 'Silva%'/ILIKE '%silva%': texto por padrão,%= qualquer coisa,_= 1 caractere.ILIKEignora caixa.ORDER BY coluna ASC|DESC: ordena.LIMIT n: corta nas n primeiras.OFFSET m: pula m.DISTINCT: remove linhas repetidas do resultado.AS: apelido de coluna,preco * 0.9 AS preco_promo.
Exemplos de aplicação
Um exemplo montado pra cada item da teoria acima. Não precisa rodar, é pra ver a cara do recurso e entender cada pedaço. Os valores são ilustrativos.
SELECT ... FROM tabela
SELECT nome, categoria, preco
FROM produtos;
SELECT diz quais colunas aparecem; FROM produtos diz de qual tabela. SELECT * traria todas. Igual ao SQLite. A diferença do Postgres começa nos tipos das colunas (aqui preco é numeric de verdade, não "número solto").
WHERE + operadores
SELECT id, status, valor_total
FROM pedidos
WHERE status <> 'cancelado' AND valor_total >= 1000;
Passa só quem satisfaz as duas condições (AND). No Postgres, texto tem que ir entre aspas simples. Aspas duplas significam nome de coluna e dariam erro.
BETWEEN / IN
SELECT nome, data_cadastro
FROM clientes
WHERE data_cadastro BETWEEN DATE '2025-01-01' AND DATE '2025-03-31'
AND estado IN ('SP', 'RJ', 'MG');
BETWEEN a AND b é intervalo inclusivo nas duas pontas. IN (...) testa se o valor é um da lista. Como data_cadastro é date, dá pra escrever DATE '2025-01-01' pra deixar claro que é data, não texto.
LIKE / ILIKE
SELECT nome, email
FROM clientes
WHERE nome ILIKE '%silva%';
LIKE compara texto com molde: % = qualquer sequência, _ = 1 caractere. ILIKE é a versão que ignora maiúscula/minúscula: '%silva%' pega "Silva", "SILVA", "da Silva". Isso é do Postgres; no SQLite não existe ILIKE.
ORDER BY / LIMIT / OFFSET
SELECT id, valor_total
FROM pedidos
ORDER BY valor_total DESC
LIMIT 10 OFFSET 10;
ORDER BY ... DESC ordena do maior pro menor. LIMIT 10 pega 10 linhas; OFFSET 10 pula as 10 primeiras antes disso, ou seja, esta query traz do 11º ao 20º pedido mais caro. É o padrão de paginação.
DISTINCT
SELECT DISTINCT estado
FROM clientes
ORDER BY estado;
Colapsa linhas repetidas: em vez do estado de cada cliente, devolve cada estado uma vez. Bom pra saber "quais valores existem nessa coluna".
AS (apelido)
SELECT nome,
preco AS preco_cheio,
preco * 0.9 AS preco_promo
FROM produtos;
AS renomeia a coluna no resultado: troca um nome ou dá nome a coluna calculada (preco * 0.9). O AS é opcional (preco AS preco_cheio = preco preco_cheio), mas escrever deixa claro.
Pegadinhas deste módulo
Os erros que quase todo mundo comete aqui. Ler agora poupa meia hora de confusão depois, e alguns deles são a causa de relatório errado em projeto real.
- Texto diferencia maiúscula de minúscula.
WHERE cidade = 'campinas'não acha'Campinas'e devolve zero linhas sem dar erro. Zero linha não é sinal de que está tudo certo: é sinal de que você precisa conferir a condição. LIMITsemORDER BYnão significa nada. "As 5 primeiras" de um resultado não ordenado são 5 linhas quaisquer, e podem mudar entre execuções. Se o enunciado fala em "maiores" ou "mais recentes", tem que haverORDER BY.LIKE '%Silva%'≠LIKE 'Silva'. Sem os%, oLIKEvira uma igualdade. É a causa mais comum de "minha busca não acha nada".- Aspas simples para texto, nada para número.
WHERE preco > '500'pode funcionar por acidente e comparar como texto, e aí'90'fica maior que'500', porque9vem depois de5no alfabeto. BETWEENinclui as duas pontas.BETWEEN 100 AND 200pega o 100 e o 200. Quando o requisito diz "acima de 100",BETWEENestá errado, e essa diferença de uma linha é exatamente o tipo de defeito que a análise de valor limite procura.- No Postgres, tipo importa de verdade. Diferente do SQLite, comparar texto com número dá erro em vez de resultado estranho. Isso é bom: o erro aparece na hora, em vez de virar número errado no relatório.
Prática
Escreva a query e clique Rodar (ou Ctrl+Enter). Tenta antes de abrir a resposta.
carregando banco…
Query livre
Espaço pra explorar. (No Postgres a lista de tabelas fica em information_schema.)