Consultando o banco do Alumnus que criamos na aula passada
SELECT: projeção, DISTINCT, aliasWHERE: comparações, BETWEEN, IN, LIKE, IS NULLAND, OR, NOTORDER BY, LIMIT, OFFSETDDL (CREATE/ALTER/DROP) e DML (INSERT/UPDATE/DELETE) — estrutura e dados.
Modelamos e populamos o banco do Alumnus: grupos, pesquisadores, relacionamentos, notas, lembretes e deadlines.
Hoje a pergunta muda: como extrair informação útil do banco?
SELECT é o comando que mais importaUm banco só vale a pena se você consegue perguntar coisas a ele — e SELECT é a forma como se faz perguntas em SQL.
SELECTSELECT <colunas> -- o que mostrar (projeção) FROM <tabela> -- de onde tirar WHERE <condição> -- quais linhas (filtro) ORDER BY <colunas> -- em que ordem LIMIT <n>; -- quantas linhas trazer
SQL é declarativo: você descreve o que quer, não como buscar. O SGBD decide o plano de execução.
DISTINCT-- Todas as colunas (use com parcimônia) SELECT * FROM pesquisador; -- Só o que interessa SELECT nome, status FROM pesquisador; -- Alias: renomeia a coluna no resultado SELECT nome AS "Pesquisador", status AS "Nível" FROM pesquisador; -- DISTINCT: elimina duplicatas no resultado SELECT DISTINCT status FROM pesquisador; -- → graduacao, mestrado, doutorado, postdoc
WHERE — filtrando linhas-- Igualdade e comparação SELECT nome FROM pesquisador WHERE status = 'doutorado'; SELECT * FROM lembrete WHERE data_vencimento < CURRENT_DATE; -- BETWEEN: intervalo inclusivo nas duas pontas SELECT * FROM nota WHERE data BETWEEN '2026-05-01' AND '2026-05-31'; -- IN: pertence a uma lista SELECT nome FROM pesquisador WHERE status IN ('mestrado', 'doutorado'); -- LIKE: padrão de texto (% = qualquer trecho _ = um caractere) SELECT nome FROM pesquisador WHERE email LIKE '%@ufpa.br'; -- IS NULL / IS NOT NULL — nunca use "= NULL" SELECT * FROM lembrete WHERE concluido_em IS NULL;
NULLNULL não é "vazio" nem "zero" — é desconhecido. Qualquer comparação com NULL dá NULL, que não é verdadeiro.
-- ❌ não retorna nada, mesmo que existam nulos SELECT * FROM lembrete WHERE concluido_em = NULL; -- ✅ a forma correta SELECT * FROM lembrete WHERE concluido_em IS NULL; -- "diferente" também precisa cuidar do NULL SELECT * FROM pesquisador WHERE orientador_id <> 1 OR orientador_id IS NULL;
AND, OR, NOT-- AND: as duas condições precisam ser verdadeiras SELECT nome FROM pesquisador WHERE status = 'doutorado' AND grupo_id = 1; -- OR: pelo menos uma é verdadeira SELECT nome FROM pesquisador WHERE status = 'mestrado' OR status = 'doutorado'; -- NOT: nega a condição SELECT * FROM lembrete WHERE NOT concluido_em IS NULL; -- Misturando — parênteses evitam ambiguidade SELECT nome FROM pesquisador WHERE (status = 'mestrado' OR status = 'doutorado') AND email LIKE '%@ufpa.br';
AND tem precedência sobre OR — quando em dúvida, parentize.
ORDER BY — ordenando o resultado-- Crescente é o padrão (ASC) SELECT nome, status FROM pesquisador ORDER BY nome; -- Decrescente SELECT texto, data FROM nota ORDER BY data DESC; -- Múltiplas colunas: primeiro grupo, depois nome dentro do grupo SELECT grupo_id, nome FROM pesquisador ORDER BY grupo_id ASC, nome ASC; -- Por uma expressão / alias SELECT nome, LENGTH(nome) AS tam FROM pesquisador ORDER BY tam DESC;
Sem ORDER BY, a ordem das linhas não é garantida — mesmo que pareça consistente.
LIMIT e OFFSET — só as N linhas que importam-- As 5 notas mais recentes SELECT texto, data FROM nota ORDER BY data DESC LIMIT 5; -- A próxima deadline a vencer SELECT nome, data_limite FROM deadline WHERE data_limite >= CURRENT_DATE ORDER BY data_limite ASC LIMIT 1; -- Paginação: pula 10 e pega as próximas 5 SELECT nome FROM pesquisador ORDER BY nome LIMIT 5 OFFSET 10;
LIMIT sem ORDER BY traz "5 quaisquer" — pode mudar entre execuções. Sempre ordene antes de limitar.
Suba o banco da aula passada no DB Fiddle (PostgreSQL) e resolva as consultas a seguir.
Suba o banco do Alumnus da aula passada no DB Fiddle (PostgreSQL).
~5 min
Resolva as 8 consultas do próximo slide, do mais simples ao mais composto.
~50 min, em dupla
Cada dupla apresenta uma consulta e explica o porquê de cada cláusula.
~25 min
1. Todos os pesquisadores de doutorado, ordenados por nome.
2. Lembretes ainda pendentes (sem data de conclusão).
3. Notas escritas em maio de 2026, da mais recente para a mais antiga.
4. Pesquisadores cujo e-mail não é da UFPA.
5. Pesquisadores de mestrado ou doutorado cujo nome começa com "A".
6. As 3 deadlines mais próximas ainda por vencer.
7. Lembretes que vencem na semana atual (use BETWEEN).
8. Para cada pesquisador, mostre nome e o domínio do e-mail.
Desafio: a nota mais recente escrita sobre a pesquisadora "Ana Souza" — uma única linha como resposta.
Recebem um valor por linha e devolvem um valor por linha. Diferente de agregações (próxima aula), que colapsam várias linhas em uma.
UPPER, LOWER, LENGTH, TRIM, CONCAT, SUBSTRING
ABS, ROUND, CEIL, FLOOR, MOD
CURRENT_DATE, NOW(), EXTRACT, COALESCE, CAST
-- Padronizar caixa SELECT UPPER(nome), LOWER(email) FROM pesquisador; -- Tamanho do texto SELECT nome, LENGTH(nome) AS tam FROM pesquisador; -- Tirar espaços nas pontas (útil em dados sujos) SELECT TRIM(nome) FROM pesquisador; -- Concatenar (PostgreSQL usa ||) SELECT nome || ' <' || email || '>' AS contato FROM pesquisador; -- Pegar um pedaço do texto SELECT SUBSTRING(email FROM '@(.*)$') AS dominio FROM pesquisador;
-- Número SELECT ROUND(3.567, 2), CEIL(3.2), FLOOR(3.8); -- Hoje e agora SELECT CURRENT_DATE, NOW(); -- Dias até a deadline SELECT nome, data_limite - CURRENT_DATE AS dias_restantes FROM deadline WHERE data_limite >= CURRENT_DATE; -- Extrair parte de uma data SELECT EXTRACT(YEAR FROM data) AS ano, EXTRACT(MONTH FROM data) AS mes FROM nota; -- COALESCE: primeiro valor não-nulo (default na consulta) SELECT texto, COALESCE(concluido_em::text, 'pendente') AS situacao FROM lembrete;
= NULL em vez de IS NULLComparar com NULL sempre dá NULL (não verdadeiro). Resultado: a consulta "funciona" mas vem vazia.
ORDER BY com LIMIT"Os 5 mais recentes" sem ORDER BY data DESC traz 5 linhas quaisquer.
AND e OR sem parêntesesAND tem precedência. A OR B AND C é A OR (B AND C) — quase nunca o que você quis.
SELECT * em tudoEsconde colunas que você nem sabe que vieram e dificulta ler o resultado. Liste só o que precisa.
-- Você escreve: SELECT nome, UPPER(status) FROM pesquisador WHERE status IN ('mestrado', 'doutorado') ORDER BY nome LIMIT 10; -- O SGBD executa (conceitualmente): -- 1. FROM → lê a tabela -- 2. WHERE → filtra linhas -- 3. SELECT → projeta colunas -- 4. ORDER BY → ordena o resultado -- 5. LIMIT → corta as N primeiras
Por isso o alias de SELECT funciona em ORDER BY, mas não em WHERE.
SELECT … FROM … WHERE … ORDER BY … LIMIT é o esqueleto de quase toda consultaWHERE filtra linhas; SELECT escolhe colunasNULL precisa de IS NULL — nunca = NULLLIMIT só faz sentido junto de ORDER BY