Hola! Empecemos por la confusión más común
Vas a buscar "cómo aprender SQL" y en dos minutos aparecen cuatro nombres: MySQL, SQL Server, PostgreSQL y SQLite. Y la pregunta obvia: ¿cuál aprendo? 😅
Te doy la respuesta de una y después la explico: aprendes SQL, no un motor. El 80% de lo que vas a escribir en tu vida es idéntico en los cuatro. Lo que cambia es un 20% que se puede tener en una tabla al lado, y en este libro lo vas a tener en cada capítulo 💜
Qué es SQL, sin rodeos
SQL es el lenguaje para pedirle datos a una base de datos. Se lee casi como una frase en inglés:
SELECT nombre, ciudad FROM clientes WHERE ciudad = 'Lima';
"Selecciona el nombre y la ciudad, de la tabla clientes, donde la ciudad sea Lima". Ya está, eso es SQL.
Y aquí está lo que lo hace especial: tú dices QUÉ quieres, no CÓMO buscarlo. No le explicas que recorra las filas ni por dónde empezar. El motor decide eso solo, y suele decidirlo mejor que tú.
Por eso SQL lleva cincuenta años en pie mientras aparecen y desaparecen lenguajes: lo que se pide no cambia aunque cambie la forma de guardarlo.
Motor, base de datos y SQL, que no son lo mismo
Esta confusión la tiene todo el mundo al empezar, así que la aclaro con una imagen que a mí me sirvió.
- 📖 SQL es el idioma.
- ⚙️ El motor (PostgreSQL, MySQL, SQL Server, SQLite) es el programa que lo entiende y guarda los datos. Se le dice también gestor o DBMS.
- 🗃️ La base de datos es tu conjunto de tablas concreto: la de ventas de tu empresa.
Es como decir que el español es el idioma, la persona que lo habla es el motor, y lo que te está contando es la base. Cuatro personas pueden hablar español con acentos distintos y entenderse perfecto 🌸
Los cuatro, y dónde te los vas a encontrar
| Motor | Dónde aparece | Qué conviene saber |
|---|---|---|
| PostgreSQL | Startups, fintech, analítica, casi todo lo nuevo | El más completo y el más estricto. Si aprendes aquí, el resto te resulta fácil |
| MySQL | Web, ecommerce, WordPress, sistemas heredados | El más extendido del mundo. MariaDB es su gemelo y va casi igual |
| SQL Server | Empresas grandes, banca, retail, todo lo Microsoft | Su dialecto se llama T-SQL y es el que más se aparta. Muy común en Perú |
| SQLite | Celulares, apps de escritorio, un archivo suelto | No tiene servidor: la base es un archivo. Es con el que vamos a practicar |
Si trabajas en una empresa grande peruana, lo más probable es SQL Server. Si es una startup o algo montado en los últimos años, PostgreSQL. Si es una tienda online o algo con WordPress detrás, MySQL 📊
Y hay un quinto grupo que conviene nombrar: los de la nube, como BigQuery de Google, Snowflake o Redshift de Amazon. Son otra cosa por dentro, pero el SQL que escribes ahí se parece muchísimo al de PostgreSQL, así que lo de este libro te sirve igual.
Qué es igual en los cuatro
Esto es lo que quiero que te lleves del capítulo, porque quita el miedo: casi todo.
Existe un estándar, el ANSI SQL, que los cuatro respetan en lo fundamental. Lo que se escribe igual en todos:
- ✅
SELECT,FROM,WHERE - ✅
GROUP BYyHAVING - ✅ Los cuatro
JOIN - ✅
ORDER BY - ✅
COUNT,SUM,AVG,MIN,MAX - ✅
INSERT,UPDATE,DELETE - ✅ Las subconsultas, los
CTEconWITHy las funciones de ventana
O sea: los capítulos 3 al 9 de este libro, que son el corazón, valen tal cual en los cuatro motores 🌟
Y qué cambia
El 20% restante. Te lo adelanto entero aquí para que lo veas junto una vez, y después cada capítulo lo retoma en su momento.
Traer solo las primeras 10 filas
| PostgreSQL | SELECT * FROM clientes LIMIT 10; |
| MySQL | SELECT * FROM clientes LIMIT 10; |
| SQL Server | SELECT TOP 10 * FROM clientes; |
| SQLite | SELECT * FROM clientes LIMIT 10; |
Tres usan LIMIT y SQL Server usa TOP, que además va antes de las columnas. Es la primera diferencia con la que se choca todo el mundo.
Juntar dos textos
| PostgreSQL | SELECT nombre || ' - ' || ciudad FROM clientes; |
| MySQL | SELECT CONCAT(nombre, ' - ', ciudad) FROM clientes; |
| SQL Server | SELECT nombre + ' - ' + ciudad FROM clientes; |
| SQLite | SELECT nombre || ' - ' || ciudad FROM clientes; |
Tres formas distintas para lo mismo. El CONCAT de MySQL también funciona en PostgreSQL y en SQL Server, así que si quieres escribir algo que corra en los tres, usa CONCAT.
La fecha y hora de ahora
| PostgreSQL | SELECT NOW(); |
| MySQL | SELECT NOW(); |
| SQL Server | SELECT GETDATE(); |
| SQLite | SELECT datetime('now'); |
Y ojo: CURRENT_TIMESTAMP funciona en los cuatro. Cuando exista una forma estándar, esa es la que conviene usar.
Si viene nulo, ponme otro valor
| PostgreSQL | SELECT COALESCE(monto, 0) FROM pedidos; |
| MySQL | SELECT IFNULL(monto, 0) FROM pedidos; |
| SQL Server | SELECT ISNULL(monto, 0) FROM pedidos; |
| SQLite | SELECT IFNULL(monto, 0) FROM pedidos; |
COALESCE funciona en los cuatro y además acepta varios valores de repuesto. Es la que yo uso siempre.
¿Ves el patrón? Casi siempre hay una forma que funciona en los cuatro, y las diferencias están en los atajos que cada motor inventó por su cuenta. Si te acostumbras a la forma estándar, tu SQL viaja 💜
Las otras diferencias que vas a encontrar, y que veremos cada una en su capítulo:
- 🔤 Las comillas. El texto va entre comillas simples en los cuatro. Los nombres de tabla y columna con espacios van entre comillas dobles en PostgreSQL y SQLite, entre acentos graves en MySQL y entre corchetes en SQL Server.
- 🔢 Los tipos de dato. Capítulo 5.
- 🆔 El id que se autoincrementa. Capítulo 11, y ahí los cuatro se escriben distinto.
- 📅 Las funciones de fecha. Capítulo 6, y es donde más se pelean.
- 🔠 Las mayúsculas. En MySQL sobre Windows,
'lima'y'Lima'suelen ser lo mismo. En PostgreSQL no. Esa te puede cambiar un conteo sin que te enteres.
Con cuál practicamos, y por qué
Con SQLite, y no porque sea el más fácil sino por tres cosas muy concretas:
- 💾 No hay que instalar un servidor. La base entera es un archivo. Lo descargas y ya.
- 🐍 Python lo trae de fábrica. Cero configuración.
- 📱 Lo usas todos los días sin saberlo. Tu celular tiene decenas de bases SQLite dentro: WhatsApp, el navegador, la galería.
Y lo importante: lo que aprendas aquí se escribe igual en los otros tres, salvo lo que este libro te va marcando en su tabla.
Cuando quieras probar los demás, sin instalar nada:
- 🐘 DB Fiddle para PostgreSQL y MySQL en el navegador.
- 🪟 dbfiddle.uk, que además tiene SQL Server.
La base de este libro
Todo corre sobre tienda.db, una distribuidora con cinco tablas y
relaciones de verdad. Vamos a mirarla:
SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name;
name ----------- clientes detalle direcciones pedidos productos
Esa consulta es de SQLite y no funciona igual en los otros. Es un buen ejemplo de algo que parece SQL normal y es específico del motor:
Listar las tablas que hay
| PostgreSQL | \dt (o consultar information_schema.tables) |
| MySQL | SHOW TABLES; |
| SQL Server | SELECT name FROM sys.tables; |
| SQLite | SELECT name FROM sqlite_master WHERE type = 'table'; |
Los cuatro guardan su catálogo en un sitio distinto. PostgreSQL, MySQL y SQL Server sí tienen information_schema.tables, que es lo estándar y lo que conviene usar si quieres una sola consulta para los tres.
Y cuántas filas tiene cada una:
SELECT 'clientes' AS tabla, COUNT(*) AS filas FROM clientes UNION ALL SELECT 'direcciones', COUNT(*) FROM direcciones UNION ALL SELECT 'productos', COUNT(*) FROM productos UNION ALL SELECT 'pedidos', COUNT(*) FROM pedidos UNION ALL SELECT 'detalle', COUNT(*) FROM detalle;
tabla filas ----------- ----- clientes 120 direcciones 164 productos 40 pedidos 900 detalle 2682
Esa sí es SQL estándar y corre igual en los cuatro motores 🌟
Fíjate en la forma de las tablas, que dice mucho: 120 clientes hicieron 900 pedidos, y esos 900 pedidos tienen 2.682 líneas de detalle. O sea que cada cliente compró varias veces y cada compra tenía varios productos. Eso es una base relacional de verdad y por eso los JOIN del capítulo 7 van a tener sentido.
Tu primera consulta
SELECT nombre, ciudad, segmento FROM clientes WHERE ciudad = 'Lima' ORDER BY nombre LIMIT 5;
nombre ciudad segmento ---------------------- ------ ---------- Almacenes Vega 010 Lima Minimarket Almacenes Vega 039 Lima Mayorista Almacenes Vega 072 Lima Horeca Autoservicio Norte 091 Lima Bodega Bodega La Esquina 005 Lima Mayorista
Eso ya es una consulta completa: qué columnas quieres, de dónde, con qué filtro, en qué orden y cuántas 💜
Y salvo el LIMIT, esa consulta corre tal cual en los cuatro
motores. En SQL Server sería SELECT TOP 5 nombre, ciudad, segmento
y el resto igual.
Ejercicios
1. Cuántos clientes hay
Cuenta cuántos clientes tiene la tabla.
SELECT COUNT(*) AS clientes FROM clientes;
clientes -------- 120
COUNT(*) es estándar y funciona igual en los cuatro motores.
2. Las ciudades sin repetir
Lista las ciudades distintas que hay, ordenadas.
SELECT DISTINCT ciudad FROM clientes ORDER BY ciudad;
ciudad -------- Arequipa Chiclayo Cusco Lima Piura Trujillo
3. Los cinco productos más caros
Trae nombre y precio de los cinco productos con el precio más alto.
SELECT nombre, precio FROM productos ORDER BY precio DESC LIMIT 5;
nombre precio ----------- ------ Producto 27 89.35 Producto 37 86.1 Producto 16 83.42 Producto 36 82.97 Producto 12 81.85
En SQL Server esto sería SELECT TOP 5 nombre, precio FROM productos
ORDER BY precio DESC;. Todo lo demás igual.
4. Escríbelo para los cuatro motores
Sin ejecutar nada: escribe "los 3 pedidos más caros" en los cuatro dialectos.
-- PostgreSQL, MySQL y SQLite SELECT id, monto FROM pedidos ORDER BY monto DESC LIMIT 3; -- SQL Server SELECT TOP 3 id, monto FROM pedidos ORDER BY monto DESC; -- Y el estándar ANSI, que funciona en PostgreSQL y en SQL Server modernos SELECT id, monto FROM pedidos ORDER BY monto DESC FETCH FIRST 3 ROWS ONLY;
Esa tercera forma, FETCH FIRST, es la del estándar. Es más larga
y casi nadie la usa, pero saber que existe te salva el día que veas una consulta
escrita así y no entiendas de dónde salió 🙂
5. El filtro con texto
Trae los clientes del segmento Mayorista que sean de Arequipa.
SELECT nombre, ciudad, segmento FROM clientes WHERE segmento = 'Mayorista' AND ciudad = 'Arequipa';
nombre ciudad segmento --------------------- -------- --------- Cafe del Puerto 060 Arequipa Mayorista Bodega San Martin 103 Arequipa Mayorista Minimarket El Sol 109 Arequipa Mayorista
Las comillas simples para el texto son estándar. Si usas comillas dobles, PostgreSQL va a creer que le hablas de una columna llamada Mayorista y te va a dar un error raro.
6. La consulta que falla
Pide una columna que no existe y lee el error.
SELECT nombre, telefono FROM clientes LIMIT 3;
OperationalError: no such column: telefono
Los cuatro motores dicen lo mismo con otras palabras: PostgreSQL dice
column "telefono" does not exist, MySQL Unknown column
'telefono' y SQL Server Invalid column name 'telefono'.
Distinto texto, mismo problema 🙃
Lo que te llevas
- 🗣️ SQL es el idioma; el motor es quien lo habla. Aprendes el idioma.
- 🤝 El 80% se escribe igual en PostgreSQL, MySQL, SQL Server y SQLite.
- ⚠️ El 20% que cambia aparece el primer día: limitar filas, juntar textos, fechas y nulos.
- 🧭 Cuando exista una forma estándar (
COALESCE,CONCAT,CURRENT_TIMESTAMP), esa es la que conviene. - 💾 Practicamos con SQLite porque es un archivo, y lo aprendido viaja.
En el capítulo 2 instalamos lo que haga falta y conectamos con la base, que es donde se atasca la gente antes de escribir su primer SELECT.
Que tengas un hermoso día! 🌟