SELECT en SQL
En esta lección
SELECT es la instrucción que más vas a escribir. Sirve para leer datos de una o varias tablas y devolverlos en forma de tabla de resultados. No cambia nada en la base de datos: puedes ejecutarla tantas veces como quieras sin miedo. En esta lección verás cómo elegir columnas, renombrarlas, calcular valores nuevos, unir textos y quitar repetidos.
Todos los ejemplos usan las tablas clientes y pedidos de la introducción.
La consulta más sencilla
SELECT nombre, ciudad
FROM clientes;
- Después de
SELECTvan las columnas que quieres ver, separadas por comas. - Después de
FROMva la tabla de la que salen. - La consulta termina en punto y coma
;.
Resultado:
| nombre | ciudad |
|---|---|
| Ana García | Santander |
| Luis Pérez | Bilbao |
| Marta Ruiz | Santander |
| Pablo Díaz | Madrid |
| Eva Martín | Madrid |
Las columnas salen en el orden en que las escribes, no en el de la tabla. SELECT ciudad, nombre mostraría primero la ciudad. Y puedes repetir una columna o dejar fuera las que no te interesan: la tabla original no cambia, solo lo que ves.
Cuidado: entre columnas va una coma, pero no después de la última.
SELECT nombre, ciudad, FROM clientesda un error de sintaxis, y es uno de los más frecuentes al empezar.
Todas las columnas: *
SELECT * FROM clientes;
| id | nombre | ciudad | edad |
|---|---|---|---|
| 1 | Ana García | Santander | 34 |
| 2 | Luis Pérez | Bilbao | 22 |
| 3 | Marta Ruiz | Santander | 45 |
| 4 | Pablo Díaz | Madrid | 17 |
| 5 | Eva Martín | Madrid | 29 |
El asterisco significa “todas las columnas, en el orden de la tabla”. Es perfecto para echar un vistazo rápido a una tabla que no conoces.
Por qué evitar * en una aplicación
En el código de una aplicación real es mejor escribir las columnas una a una:
- Rendimiento: si la tabla tiene 30 columnas y necesitas 3, traes diez veces más datos de los necesarios por la red. Si alguna columna guarda textos largos o imágenes, se nota mucho.
- Claridad: quien lee
SELECT nombre, emailsabe qué usa el programa. Con*tiene que ir a mirar la tabla. - Cambios en la tabla: si alguien añade o reordena columnas, un
SELECT *devuelve algo distinto de lo que esperaba el programa y puede romperlo. Si una columna nueva guarda datos sensibles, los enviarías sin darte cuenta.
Regla práctica: * para explorar a mano; columnas explícitas en todo lo que se guarda en un programa, una vista o un informe.
Alias: AS
Un alias renombra una columna en el resultado. Es útil para dar nombres más claros o para ponérselo a una columna calculada, que si no tendría un nombre feo:
SELECT nombre AS cliente, edad AS anios
FROM clientes;
| cliente | anios |
|---|---|
| Ana García | 34 |
| Luis Pérez | 22 |
| Marta Ruiz | 45 |
| Pablo Díaz | 17 |
| Eva Martín | 29 |
La palabra AS es opcional (SELECT nombre cliente también funciona), pero escríbela: deja claro que es un alias y no una coma olvidada.
Alias con espacios
Si el alias lleva espacios, tildes o palabras reservadas, ponlo entre comillas dobles:
SELECT nombre AS "Nombre completo", ciudad AS "Ciudad"
FROM clientes;
| Nombre completo | Ciudad |
|---|---|
| Ana García | Santander |
| Luis Pérez | Bilbao |
| Marta Ruiz | Santander |
| Pablo Díaz | Madrid |
| Eva Martín | Madrid |
Nota: las comillas dobles son el estándar y funcionan en MySQL, PostgreSQL y SQLite. MySQL también acepta acentos graves:
`Nombre completo`. No uses comillas simples para alias: en SQL las comillas simples son para textos.
El alias solo existe en el resultado: no cambia el nombre de la columna en la tabla.
Columnas calculadas
SELECT también puede calcular valores nuevos con operadores aritméticos (+, -, *, /). Por ejemplo, el importe de cada pedido con un 21 % de IVA:
SELECT id, importe, ROUND(importe * 1.21, 2) AS importe_con_iva
FROM pedidos;
| id | importe | importe_con_iva |
|---|---|---|
| 1 | 45.00 | 54.45 |
| 2 | 120.50 | 145.81 |
| 3 | 12.99 | 15.72 |
| 4 | 60.00 | 72.60 |
| 5 | 33.25 | 40.23 |
ROUND(valor, 2) redondea a dos decimales; sin él, MySQL mostraría 54.4500, 145.8050… La verás con más detalle en funciones.
Otro ejemplo: el año aproximado de nacimiento de cada cliente.
SELECT nombre, edad, 2026 - edad AS anio_nacimiento
FROM clientes;
| nombre | edad | anio_nacimiento |
|---|---|---|
| Ana García | 34 | 1992 |
| Luis Pérez | 22 | 2004 |
| Marta Ruiz | 45 | 1981 |
| Pablo Díaz | 17 | 2009 |
| Eva Martín | 29 | 1997 |
El cálculo se hace fila a fila y no se guarda en ningún sitio: la tabla sigue teniendo solo la edad. También puedes escribir valores fijos, que se repiten en todas las filas:
SELECT nombre, 'cliente' AS tipo
FROM clientes;
| nombre | tipo |
|---|---|
| Ana García | cliente |
| Luis Pérez | cliente |
| Marta Ruiz | cliente |
| Pablo Díaz | cliente |
| Eva Martín | cliente |
Esto es útil, por ejemplo, al juntar resultados de varias tablas con UNION. Y en MySQL, PostgreSQL y SQLite puedes incluso escribir un SELECT sin FROM para usar la base de datos como calculadora: SELECT 2 + 3; devuelve 5.
Unir textos
Para concatenar (juntar) varios textos en una columna hay dos formas, según el sistema.
En MySQL y MariaDB, la función CONCAT:
SELECT CONCAT(nombre, ' (', ciudad, ')') AS ficha
FROM clientes;
En PostgreSQL, SQLite y Oracle, el operador estándar ||:
SELECT nombre || ' (' || ciudad || ')' AS ficha
FROM clientes;
Las dos dan el mismo resultado:
| ficha |
|---|
| Ana García (Santander) |
| Luis Pérez (Bilbao) |
| Marta Ruiz (Santander) |
| Pablo Díaz (Madrid) |
| Eva Martín (Madrid) |
Cuidado: en MySQL,
||no concatena: por defecto significaORlógico y devuelve0o1. Si escribes código para MySQL, usaCONCAT. PostgreSQL y SQLite también tienenCONCAT(SQLite desde la versión 3.44), así queCONCATes la opción más portable.
Recuerda que los textos fijos, como ' (', van entre comillas simples.
Quitar repetidos: DISTINCT
SELECT DISTINCT ciudad
FROM clientes;
| ciudad |
|---|
| Santander |
| Bilbao |
| Madrid |
Sin DISTINCT saldrían cinco filas, con Santander y Madrid repetidas. Otro uso típico: ¿qué clientes han hecho algún pedido?
SELECT DISTINCT cliente_id
FROM pedidos;
| cliente_id |
|---|
| 1 |
| 3 |
| 2 |
| 5 |
Ana (cliente 1) tiene dos pedidos, pero aparece una sola vez.
DISTINCT con varias columnas
DISTINCT va justo detrás de SELECT y afecta a toda la fila, no a la primera columna. Quita las filas en las que todas las columnas coinciden:
SELECT DISTINCT ciudad, edad >= 18 AS adulto
FROM clientes;
| ciudad | adulto |
|---|---|
| Santander | 1 |
| Bilbao | 1 |
| Madrid | 0 |
| Madrid | 1 |
Madrid sale dos veces porque la combinación es distinta: Pablo (17) da 0 y Eva (29) da 1. Las dos filas de Santander, en cambio, eran iguales y se han fusionado. (La condición edad >= 18 devuelve 1 si es verdadera y 0 si es falsa).
Nota: sin
ORDER BY, el orden de las filas no está garantizado y puede variar entre sistemas. Lo verás en ORDER BY.
El orden en que se escribe y el orden en que se ejecuta
Una consulta completa puede tener muchas partes, y siempre se escriben en este orden. Las irás viendo en las próximas lecciones:
SELECT columnas
FROM tabla
WHERE condición sobre las filas
GROUP BY columnas para agrupar
HAVING condición sobre los grupos
ORDER BY columnas para ordenar
LIMIT número de filas;
Pero la base de datos no las ejecuta en ese orden. El orden lógico es:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
Primero elige la tabla, luego filtra, agrupa, filtra grupos, y solo entonces calcula las columnas del SELECT. Esto explica un error típico: no puedes usar en el WHERE un alias creado en el SELECT, porque cuando se ejecuta el WHERE ese alias todavía no existe. (MySQL y PostgreSQL dan error; SQLite lo permite, pero no es estándar). En cambio, ORDER BY sí puede usarlo, porque va después. Lo retomarás en GROUP BY.
Errores frecuentes
- Coma después de la última columna:
SELECT nombre, edad, FROM clientes. - Comillas simples en un alias:
AS 'Nombre completo'funciona en MySQL, pero no en PostgreSQL. Usa comillas dobles. - Usar
||para concatenar en MySQL: devuelve0o1en lugar del texto. UsaCONCAT. - Creer que
DISTINCTafecta solo a una columna: siempre mira la fila completa. - Escribir mal un nombre:
SELECT nombres FROM clientesda un error del tipo Unknown column ‘nombres’. Lee el mensaje: suele decirte exactamente qué falla.
Resumen
| Quieres… | Escribe |
|---|---|
| Unas columnas concretas | SELECT nombre, ciudad FROM clientes |
| Todas las columnas | SELECT * FROM clientes |
| Renombrar una columna | SELECT edad AS anios |
| Un alias con espacios | SELECT nombre AS "Nombre completo" |
| Calcular un valor | SELECT importe * 1.21 AS con_iva |
| Unir textos (MySQL) | CONCAT(nombre, ' - ', ciudad) |
| Unir textos (estándar) | nombre || ' - ' || ciudad |
| Quitar filas repetidas | SELECT DISTINCT ciudad |
En la siguiente lección aprenderás a quedarte solo con las filas que te interesan usando WHERE.
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.