SELECT … FROM es el primerísimo comando que aprendes en SQL. Toda consulta de lectura empieza aquí. En lenguaje llano:
SELECT — qué quieres
FROM — de dónde sacarlo
Así que SELECT name FROM users se lee como «dame la columna name de la tabla users». Suena como una petición normal — y el 90 % del trabajo con una base de datos se construye sobre esto.
Por qué importa SELECT
Una base de datos es un conjunto de tablas. Para hacer cualquier cosa con ellas —mostrarlas en pantalla, devolverlas desde una API, calcular estadísticas— primero necesitas leer los datos. Para eso está SELECT.
Otros comandos (INSERT, UPDATE, DELETE) escriben o modifican datos. SELECT es pura lectura — seguro y reversible: ejecutas una consulta, miras el resultado y nada en la base de datos ha cambiado.
Sintaxis básica
SELECT column1, column2, ...
FROM table_name;
Ejemplo:
SELECT name, email
FROM users;
Se lee como: «toma las columnas name e email de la tabla users».
El resultado es una lista de todos los usuarios, pero solo con dos columnas: nombre y correo. Las demás columnas (id, teléfono, fecha de registro, etc.) no aparecen en el resultado.
Tomarlo todo: SELECT *
Si quieres todas las columnas, hay un atajo — el asterisco:
SELECT * FROM users;
Práctico durante el desarrollo, cuando estás explorando qué hay en una tabla. En código real (sobre todo APIs y analítica), es mejor enumerar las columnas explícitamente. El asterisco es frágil: si alguien añade una columna nueva a la tabla, la consulta empieza de pronto a devolver datos de más y tu aplicación puede romperse.
Regla práctica: explorando una tabla — SELECT *. Escribiendo código de producción — enumera las columnas a mano.
Ejemplo: una tabla de publicaciones de una red social
Supongamos que hay una tabla de publicaciones:
| 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 |
Las columnas id, author y created_at siguen en la tabla — simplemente no las pedimos.
Alias: SELECT … AS …
A veces el nombre de la columna es feo — demasiado largo, en otro idioma o, sin más, incómodo en el resultado. Para eso está 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 |
Los mismos datos — solo cambiaron los encabezados de columna en la salida. AS se puede omitir: title heading funciona igual.
Campos calculados
En SELECT puedes poner no solo nombres de columna, sino expresiones — la base de datos las calcula sobre la marcha. 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 y LENGTH(title) no son columnas reales de la tabla — son valores calculados. Viene de perlas siempre que necesitas una métrica o una transformación: precios con impuestos, longitud de texto, nombres concatenados, etc.
Otro ejemplo: productos de comercio electrónico
Tabla de productos:
| id | name | price | weight_kg |
|---|
| 1 | iPhone 15 | 999 | 0.17 |
| 2 | Bosch kettle | 49 | 1.20 |
| 3 | Book "Clean Code" | 22 | 0.65 |
Mostremos el nombre, el precio en dólares y el precio en euros (tipo 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 |
La base de datos multiplicó y redondeó por nosotros. La columna price_eur es calculada; no existe tal columna en la tabla.
DISTINCT — eliminar duplicados
A veces solo quieres valores únicos en el resultado. Por ejemplo, de qué países proceden los usuarios:
SELECT DISTINCT country
FROM users;
Si la tabla tiene 10 000 usuarios de 5 países, recuperas exactamente 5 filas, sin repeticiones.
DISTINCT también funciona sobre varias columnas — la unicidad es entonces por combinación:
SELECT DISTINCT country, city
FROM users;
DISTINCT es un tema grande por sí mismo y merece su propio artículo, pero por ahora basta con saber: «elimina las filas duplicadas del resultado».
Ejemplo más grande: antes y después
Tabla 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: «nombre completo, departamento y salario mensual con un 20 % de bonificación».
SELECT
first_name || ' ' || last_name AS full_name,
department,
salary,
ROUND(salary * 1.2, 0) AS salary_with_bonus
FROM employees;
(|| es el operador de concatenación de cadenas en PostgreSQL. En MySQL, usa CONCAT(first_name, ' ', last_name) en su 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 en la tabla cambió. SELECT solo calculó y mostró. Ejecútalo de nuevo — el mismo resultado.
Errores habituales de principiante
1. Erratas en los nombres de columna. SQL es estricto con los identificadores. SELECT nme FROM users falla con column "nme" does not exist. Revisa la ortografía dos veces.
2. SELECT * en producción. Funciona, pero es impredecible. Mañana alguien añade una columna con blobs binarios — y tu consulta es de pronto 10 veces más lenta. Enumera las columnas explícitamente.
3. Confundir el orden de SELECT y FROM. Los principiantes a veces escriben FROM users SELECT name. El orden es fijo: primero SELECT, luego FROM.
4. Olvidar una coma entre columnas.
SELECT name email FROM users;
La base de datos cree que email es un alias de name. Obtienes una sola columna con el encabezado «email». En silencio, sin error. Horas de depuración después te das cuenta.
5. Comillas alrededor de los nombres de columna. Si el nombre de la columna es una palabra normal sin espacios — no hacen falta comillas: SELECT name. Para nombres con espacios o caracteres especiales (mala idea, pero ocurre), PostgreSQL usa comillas dobles: SELECT "first name". MySQL usa comillas invertidas: SELECT `first name`.
6. Esperar un orden fijo. SELECT * FROM users sin ORDER BY puede devolver las filas en cualquier orden — incluso órdenes distintos para dos consultas idénticas. Si necesitas una ordenación, añade ORDER BY.
Resumen rápido
SELECT … FROM es la base de cualquier consulta de lectura.
- En
SELECT puedes poner columnas, expresiones, funciones y constantes.
* significa «todas las columnas». Cómodo para explorar, dudoso en producción.
AS renombra una columna en la salida. Palabra clave opcional.
DISTINCT elimina filas duplicadas del resultado.
SELECT no cambia la base de datos — pura lectura.
Pruébalo tú
Sobre la misma tabla employees:
- Muestra solo los nombres y salarios de todos los empleados.
- Añade una columna con el salario anual (mensual × 12) llamada
annual_salary.
- Obtén la lista de departamentos únicos mediante
DISTINCT.
Escribe primero las consultas por tu cuenta y luego compruébate. SQL se lee de izquierda a derecha — SELECT qué FROM dónde, como una frase normal. Cada ejercicio lo vuelve más automático.
SELECT … FROMes el primerísimo comando que aprendes en SQL. Toda consulta de lectura empieza aquí. En lenguaje llano:SELECT— qué quieresFROM— de dónde sacarloAsí que
SELECT name FROM usersse lee como «dame la columnanamede la tablausers». Suena como una petición normal — y el 90 % del trabajo con una base de datos se construye sobre esto.Por qué importa SELECT
Una base de datos es un conjunto de tablas. Para hacer cualquier cosa con ellas —mostrarlas en pantalla, devolverlas desde una API, calcular estadísticas— primero necesitas leer los datos. Para eso está
SELECT.Otros comandos (
INSERT,UPDATE,DELETE) escriben o modifican datos.SELECTes pura lectura — seguro y reversible: ejecutas una consulta, miras el resultado y nada en la base de datos ha cambiado.Sintaxis básica
SELECT column1, column2, ... FROM table_name;Ejemplo:
SELECT name, email FROM users;Se lee como: «toma las columnas
nameeemailde la tablausers».El resultado es una lista de todos los usuarios, pero solo con dos columnas: nombre y correo. Las demás columnas (id, teléfono, fecha de registro, etc.) no aparecen en el resultado.
Tomarlo todo: SELECT *
Si quieres todas las columnas, hay un atajo — el asterisco:
SELECT * FROM users;Práctico durante el desarrollo, cuando estás explorando qué hay en una tabla. En código real (sobre todo APIs y analítica), es mejor enumerar las columnas explícitamente. El asterisco es frágil: si alguien añade una columna nueva a la tabla, la consulta empieza de pronto a devolver datos de más y tu aplicación puede romperse.
Regla práctica: explorando una tabla —
SELECT *. Escribiendo código de producción — enumera las columnas a mano.Ejemplo: una tabla de publicaciones de una red social
Supongamos que hay una tabla de publicaciones:
Consulta:
SELECT title, likes FROM posts;Resultado:
Las columnas
id,authorycreated_atsiguen en la tabla — simplemente no las pedimos.Alias: SELECT … AS …
A veces el nombre de la columna es feo — demasiado largo, en otro idioma o, sin más, incómodo en el resultado. Para eso está
AS:SELECT title AS heading, likes AS hearts, created_at AS posted_on FROM posts;Resultado:
Los mismos datos — solo cambiaron los encabezados de columna en la salida.
ASse puede omitir:title headingfunciona igual.Campos calculados
En
SELECTpuedes poner no solo nombres de columna, sino expresiones — la base de datos las calcula sobre la marcha. Superútil:SELECT title, likes, likes * 2 AS doubled_likes, LENGTH(title) AS title_length FROM posts;Resultado:
likes * 2yLENGTH(title)no son columnas reales de la tabla — son valores calculados. Viene de perlas siempre que necesitas una métrica o una transformación: precios con impuestos, longitud de texto, nombres concatenados, etc.Otro ejemplo: productos de comercio electrónico
Tabla de productos:
Mostremos el nombre, el precio en dólares y el precio en euros (tipo 0,92):
SELECT name, price AS price_usd, ROUND(price * 0.92, 2) AS price_eur FROM products;Resultado:
La base de datos multiplicó y redondeó por nosotros. La columna
price_eures calculada; no existe tal columna en la tabla.DISTINCT — eliminar duplicados
A veces solo quieres valores únicos en el resultado. Por ejemplo, de qué países proceden los usuarios:
SELECT DISTINCT country FROM users;Si la tabla tiene 10 000 usuarios de 5 países, recuperas exactamente 5 filas, sin repeticiones.
DISTINCTtambién funciona sobre varias columnas — la unicidad es entonces por combinación:SELECT DISTINCT country, city FROM users;DISTINCT es un tema grande por sí mismo y merece su propio artículo, pero por ahora basta con saber: «elimina las filas duplicadas del resultado».
Ejemplo más grande: antes y después
Tabla
employees:Consulta: «nombre completo, departamento y salario mensual con un 20 % de bonificación».
SELECT first_name || ' ' || last_name AS full_name, department, salary, ROUND(salary * 1.2, 0) AS salary_with_bonus FROM employees;(
||es el operador de concatenación de cadenas en PostgreSQL. En MySQL, usaCONCAT(first_name, ' ', last_name)en su lugar.)Resultado:
Nada en la tabla cambió.
SELECTsolo calculó y mostró. Ejecútalo de nuevo — el mismo resultado.Errores habituales de principiante
1. Erratas en los nombres de columna. SQL es estricto con los identificadores.
SELECT nme FROM usersfalla concolumn "nme" does not exist. Revisa la ortografía dos veces.2. SELECT * en producción. Funciona, pero es impredecible. Mañana alguien añade una columna con blobs binarios — y tu consulta es de pronto 10 veces más lenta. Enumera las columnas explícitamente.
3. Confundir el orden de SELECT y FROM. Los principiantes a veces escriben
FROM users SELECT name. El orden es fijo: primeroSELECT, luegoFROM.4. Olvidar una coma entre columnas.
-- Error: falta la coma entre name y email SELECT name email FROM users;La base de datos cree que
emailes un alias dename. Obtienes una sola columna con el encabezado «email». En silencio, sin error. Horas de depuración después te das cuenta.5. Comillas alrededor de los nombres de columna. Si el nombre de la columna es una palabra normal sin espacios — no hacen falta comillas:
SELECT name. Para nombres con espacios o caracteres especiales (mala idea, pero ocurre), PostgreSQL usa comillas dobles:SELECT "first name". MySQL usa comillas invertidas:SELECT `first name`.6. Esperar un orden fijo.
SELECT * FROM userssinORDER BYpuede devolver las filas en cualquier orden — incluso órdenes distintos para dos consultas idénticas. Si necesitas una ordenación, añadeORDER BY.Resumen rápido
SELECT … FROMes la base de cualquier consulta de lectura.SELECTpuedes poner columnas, expresiones, funciones y constantes.*significa «todas las columnas». Cómodo para explorar, dudoso en producción.ASrenombra una columna en la salida. Palabra clave opcional.DISTINCTelimina filas duplicadas del resultado.SELECTno cambia la base de datos — pura lectura.Pruébalo tú
Sobre la misma tabla
employees:annual_salary.DISTINCT.Escribe primero las consultas por tu cuenta y luego compruébate. SQL se lee de izquierda a derecha —
SELECT qué FROM dónde, como una frase normal. Cada ejercicio lo vuelve más automático.