SELECT … FROM é o primeiríssimo comando que você aprende em SQL. Toda consulta de leitura começa aqui. Em linguagem simples:
SELECT — o que você quer
FROM — de onde tirá-lo
Então SELECT name FROM users se lê como "me dê a coluna name da tabela users". Soa como um pedido normal — e 90% do trabalho com um banco de dados se constrói sobre isso.
Por que SELECT importa
Um banco de dados é um conjunto de tabelas. Para fazer qualquer coisa com elas — mostrar na tela, retornar de uma API, calcular estatísticas — você primeiro precisa ler os dados. É para isso que serve o SELECT.
Outros comandos (INSERT, UPDATE, DELETE) escrevem ou alteram dados. SELECT é leitura pura — seguro e reversível: você executa uma consulta, olha o resultado e nada no banco de dados mudou.
Sintaxe básica
SELECT column1, column2, ...
FROM table_name;
Exemplo:
SELECT name, email
FROM users;
Lê-se como: "pegue as colunas name e email da tabela users".
O resultado é uma lista de todos os usuários, mas apenas com duas colunas: nome e e-mail. As outras colunas (id, telefone, data de cadastro, etc.) não aparecem no resultado.
Pegar tudo: SELECT *
Se você quer todas as colunas, há um atalho — o asterisco:
SELECT * FROM users;
Prático durante o desenvolvimento, quando você está explorando o que há em uma tabela. Em código real (especialmente APIs e análise), é melhor listar as colunas explicitamente. O asterisco é frágil: se alguém adicionar uma coluna nova à tabela, a consulta de repente passa a retornar dados a mais e o seu aplicativo pode quebrar.
Regra prática: explorando uma tabela — SELECT *. Escrevendo código de produção — liste as colunas manualmente.
Exemplo: uma tabela de publicações de uma rede social
Digamos que exista uma tabela de publicações:
| id | author | title | likes | created_at |
|---|
| 1 | anna | My first post | 12 | 2024-03-01 |
| 2 | bob | Cute cats | 87 | 2024-03-02 |
| 3 | vera | Borscht recipe | 45 | 2024-03-03 |
Consulta:
SELECT title, likes
FROM posts;
Resultado:
| title | likes |
|---|
| My first post | 12 |
| Cute cats | 87 |
| Borscht recipe | 45 |
As colunas id, author e created_at continuam na tabela — apenas não as pedimos.
Aliases: SELECT … AS …
Às vezes o nome da coluna é feio — longo demais, em outro idioma ou simplesmente inconveniente no resultado. É para isso que serve o AS:
SELECT
title AS heading,
likes AS hearts,
created_at AS posted_on
FROM posts;
Resultado:
| heading | hearts | posted_on |
|---|
| My first post | 12 | 2024-03-01 |
| Cute cats | 87 | 2024-03-02 |
| Borscht recipe | 45 | 2024-03-03 |
Os mesmos dados — apenas os cabeçalhos de coluna na saída mudaram. AS pode ser omitido: title heading funciona da mesma forma.
Campos calculados
No SELECT você pode colocar não apenas nomes de coluna, mas expressões — o banco de dados as calcula na hora. Superútil:
SELECT
title,
likes,
likes * 2 AS doubled_likes,
LENGTH(title) AS title_length
FROM posts;
Resultado:
| title | likes | doubled_likes | title_length |
|---|
| My first post | 12 | 24 | 13 |
| Cute cats | 87 | 174 | 9 |
| Borscht recipe | 45 | 90 | 14 |
likes * 2 e LENGTH(title) não são colunas reais da tabela — são valores calculados. Vem a calhar sempre que você precisa de uma métrica ou transformação: preços com imposto, comprimento de texto, nomes concatenados, e assim por diante.
Outro exemplo: produtos de e-commerce
Tabela de produtos:
| id | name | price | weight_kg |
|---|
| 1 | iPhone 15 | 999 | 0.17 |
| 2 | Bosch kettle | 49 | 1.20 |
| 3 | Book "Clean Code" | 22 | 0.65 |
Vamos exibir o nome, o preço em dólares e o preço em euros (taxa 0,92):
SELECT
name,
price AS price_usd,
ROUND(price * 0.92, 2) AS price_eur
FROM products;
Resultado:
| name | price_usd | price_eur |
|---|
| iPhone 15 | 999 | 919.08 |
| Bosch kettle | 49 | 45.08 |
| Book "Clean Code" | 22 | 20.24 |
O banco de dados multiplicou e arredondou por nós. A coluna price_eur é calculada; não existe tal coluna na tabela.
DISTINCT — descartar duplicados
Às vezes você quer apenas valores únicos no resultado. Por exemplo, de quais países vêm os usuários:
SELECT DISTINCT country
FROM users;
Se a tabela tem 10.000 usuários de 5 países, você recebe exatamente 5 linhas de volta, sem repetições.
DISTINCT também funciona sobre várias colunas — a unicidade passa a ser por combinação:
SELECT DISTINCT country, city
FROM users;
DISTINCT é um tema grande por si só e merece o próprio artigo, mas por enquanto basta saber: "ele remove as linhas duplicadas do resultado".
Exemplo maior: antes e depois
Tabela employees:
| id | first_name | last_name | department | salary |
|---|
| 1 | Anna | Ivanova | IT | 4000 |
| 2 | Boris | Petrov | Sales | 2700 |
| 3 | Vera | Sidorova | IT | 5000 |
| 4 | Grisha | Nikiforov | HR | 2300 |
Consulta: "nome completo, departamento e salário mensal com 20% de bônus".
SELECT
first_name || ' ' || last_name AS full_name,
department,
salary,
ROUND(salary * 1.2, 0) AS salary_with_bonus
FROM employees;
(|| é o operador de concatenação de strings no PostgreSQL. No MySQL, use CONCAT(first_name, ' ', last_name) no lugar.)
Resultado:
| full_name | department | salary | salary_with_bonus |
|---|
| Anna Ivanova | IT | 4000 | 4800 |
| Boris Petrov | Sales | 2700 | 3240 |
| Vera Sidorova | IT | 5000 | 6000 |
| Grisha Nikiforov | HR | 2300 | 2760 |
Nada na tabela mudou. SELECT apenas calculou e exibiu. Execute de novo — o mesmo resultado.
Erros comuns de iniciante
1. Erros de digitação nos nomes de coluna. SQL é rigoroso com identificadores. SELECT nme FROM users falha com column "nme" does not exist. Confira a grafia duas vezes.
2. SELECT * em produção. Funciona, mas é imprevisível. Amanhã alguém adiciona uma coluna com blobs binários — e a sua consulta fica de repente 10 vezes mais lenta. Liste as colunas explicitamente.
3. Confundir a ordem de SELECT e FROM. Iniciantes às vezes escrevem FROM users SELECT name. A ordem é fixa: SELECT primeiro, depois FROM.
4. Esquecer uma vírgula entre colunas.
SELECT name email FROM users;
O banco de dados acha que email é um alias de name. Você obtém uma coluna só com o cabeçalho "email". Silenciosamente, sem erro. Horas de depuração depois você percebe.
5. Aspas em volta dos nomes de coluna. Se o nome da coluna for uma palavra normal sem espaços — não precisa de aspas: SELECT name. Para nomes com espaços ou caracteres especiais (uma má ideia, mas acontece), o PostgreSQL usa aspas duplas: SELECT "first name". O MySQL usa crases: SELECT `first name`.
6. Esperar uma ordem fixa. SELECT * FROM users sem ORDER BY pode retornar as linhas em qualquer ordem — até ordens diferentes para duas consultas idênticas. Se você precisa de uma ordenação, adicione ORDER BY.
Resumo rápido
SELECT … FROM é a base de qualquer consulta de leitura.
- No
SELECT você pode colocar colunas, expressões, funções e constantes.
* significa "todas as colunas". Conveniente para exploração, arriscado em produção.
AS renomeia uma coluna na saída. Palavra-chave opcional.
DISTINCT remove linhas duplicadas do resultado.
SELECT não altera o banco de dados — leitura pura.
Experimente você mesmo
Sobre a mesma tabela employees:
- Exiba apenas os nomes e salários de todos os funcionários.
- Adicione uma coluna com o salário anual (mensal × 12) chamada
annual_salary.
- Obtenha a lista de departamentos únicos via
DISTINCT.
Escreva primeiro as consultas por conta própria e depois confira. SQL se lê da esquerda para a direita — SELECT o quê FROM onde, como uma frase normal. Cada exercício o torna mais automático.
SELECT … FROMé o primeiríssimo comando que você aprende em SQL. Toda consulta de leitura começa aqui. Em linguagem simples:SELECT— o que você querFROM— de onde tirá-loEntão
SELECT name FROM usersse lê como "me dê a colunanameda tabelausers". Soa como um pedido normal — e 90% do trabalho com um banco de dados se constrói sobre isso.Por que SELECT importa
Um banco de dados é um conjunto de tabelas. Para fazer qualquer coisa com elas — mostrar na tela, retornar de uma API, calcular estatísticas — você primeiro precisa ler os dados. É para isso que serve o
SELECT.Outros comandos (
INSERT,UPDATE,DELETE) escrevem ou alteram dados.SELECTé leitura pura — seguro e reversível: você executa uma consulta, olha o resultado e nada no banco de dados mudou.Sintaxe básica
SELECT column1, column2, ... FROM table_name;Exemplo:
SELECT name, email FROM users;Lê-se como: "pegue as colunas
nameeemailda tabelausers".O resultado é uma lista de todos os usuários, mas apenas com duas colunas: nome e e-mail. As outras colunas (id, telefone, data de cadastro, etc.) não aparecem no resultado.
Pegar tudo: SELECT *
Se você quer todas as colunas, há um atalho — o asterisco:
SELECT * FROM users;Prático durante o desenvolvimento, quando você está explorando o que há em uma tabela. Em código real (especialmente APIs e análise), é melhor listar as colunas explicitamente. O asterisco é frágil: se alguém adicionar uma coluna nova à tabela, a consulta de repente passa a retornar dados a mais e o seu aplicativo pode quebrar.
Regra prática: explorando uma tabela —
SELECT *. Escrevendo código de produção — liste as colunas manualmente.Exemplo: uma tabela de publicações de uma rede social
Digamos que exista uma tabela de publicações:
Consulta:
SELECT title, likes FROM posts;Resultado:
As colunas
id,authorecreated_atcontinuam na tabela — apenas não as pedimos.Aliases: SELECT … AS …
Às vezes o nome da coluna é feio — longo demais, em outro idioma ou simplesmente inconveniente no resultado. É para isso que serve o
AS:SELECT title AS heading, likes AS hearts, created_at AS posted_on FROM posts;Resultado:
Os mesmos dados — apenas os cabeçalhos de coluna na saída mudaram.
ASpode ser omitido:title headingfunciona da mesma forma.Campos calculados
No
SELECTvocê pode colocar não apenas nomes de coluna, mas expressões — o banco de dados as calcula na hora. Superútil:SELECT title, likes, likes * 2 AS doubled_likes, LENGTH(title) AS title_length FROM posts;Resultado:
likes * 2eLENGTH(title)não são colunas reais da tabela — são valores calculados. Vem a calhar sempre que você precisa de uma métrica ou transformação: preços com imposto, comprimento de texto, nomes concatenados, e assim por diante.Outro exemplo: produtos de e-commerce
Tabela de produtos:
Vamos exibir o nome, o preço em dólares e o preço em euros (taxa 0,92):
SELECT name, price AS price_usd, ROUND(price * 0.92, 2) AS price_eur FROM products;Resultado:
O banco de dados multiplicou e arredondou por nós. A coluna
price_euré calculada; não existe tal coluna na tabela.DISTINCT — descartar duplicados
Às vezes você quer apenas valores únicos no resultado. Por exemplo, de quais países vêm os usuários:
SELECT DISTINCT country FROM users;Se a tabela tem 10.000 usuários de 5 países, você recebe exatamente 5 linhas de volta, sem repetições.
DISTINCTtambém funciona sobre várias colunas — a unicidade passa a ser por combinação:SELECT DISTINCT country, city FROM users;DISTINCT é um tema grande por si só e merece o próprio artigo, mas por enquanto basta saber: "ele remove as linhas duplicadas do resultado".
Exemplo maior: antes e depois
Tabela
employees:Consulta: "nome completo, departamento e salário mensal com 20% de bônus".
SELECT first_name || ' ' || last_name AS full_name, department, salary, ROUND(salary * 1.2, 0) AS salary_with_bonus FROM employees;(
||é o operador de concatenação de strings no PostgreSQL. No MySQL, useCONCAT(first_name, ' ', last_name)no lugar.)Resultado:
Nada na tabela mudou.
SELECTapenas calculou e exibiu. Execute de novo — o mesmo resultado.Erros comuns de iniciante
1. Erros de digitação nos nomes de coluna. SQL é rigoroso com identificadores.
SELECT nme FROM usersfalha comcolumn "nme" does not exist. Confira a grafia duas vezes.2. SELECT * em produção. Funciona, mas é imprevisível. Amanhã alguém adiciona uma coluna com blobs binários — e a sua consulta fica de repente 10 vezes mais lenta. Liste as colunas explicitamente.
3. Confundir a ordem de SELECT e FROM. Iniciantes às vezes escrevem
FROM users SELECT name. A ordem é fixa:SELECTprimeiro, depoisFROM.4. Esquecer uma vírgula entre colunas.
-- Bug: falta a vírgula entre name e email SELECT name email FROM users;O banco de dados acha que
emailé um alias dename. Você obtém uma coluna só com o cabeçalho "email". Silenciosamente, sem erro. Horas de depuração depois você percebe.5. Aspas em volta dos nomes de coluna. Se o nome da coluna for uma palavra normal sem espaços — não precisa de aspas:
SELECT name. Para nomes com espaços ou caracteres especiais (uma má ideia, mas acontece), o PostgreSQL usa aspas duplas:SELECT "first name". O MySQL usa crases:SELECT `first name`.6. Esperar uma ordem fixa.
SELECT * FROM userssemORDER BYpode retornar as linhas em qualquer ordem — até ordens diferentes para duas consultas idênticas. Se você precisa de uma ordenação, adicioneORDER BY.Resumo rápido
SELECT … FROMé a base de qualquer consulta de leitura.SELECTvocê pode colocar colunas, expressões, funções e constantes.*significa "todas as colunas". Conveniente para exploração, arriscado em produção.ASrenomeia uma coluna na saída. Palavra-chave opcional.DISTINCTremove linhas duplicadas do resultado.SELECTnão altera o banco de dados — leitura pura.Experimente você mesmo
Sobre a mesma tabela
employees:annual_salary.DISTINCT.Escreva primeiro as consultas por conta própria e depois confira. SQL se lê da esquerda para a direita —
SELECT o quê FROM onde, como uma frase normal. Cada exercício o torna mais automático.