SQL para Devs Frontend: Lo que Necesitas Saber de PostgreSQL
SQL esencial para desarrolladores frontend y fullstack. SELECT, JOINs, filtros, agregaciones y como pensar en datos relacionales sin ser DBA.
SQL para Devs Frontend: Lo que Necesitas Saber de PostgreSQL
SQL es el tercer lenguaje mas usado en el mundo con 58.6% de adopcion segun el Stack Overflow Survey 2025. Y si eres dev frontend que esta pasando a fullstack, es el skill que mas te va a servir despues de TypeScript.
No necesitas ser DBA. Necesitas entender como leer, filtrar y combinar datos. Esto es lo esencial.
Pensar en tablas
Si vienes de frontend, piensa en tablas como arrays de objetos con estructura fija. Cada fila es un objeto, cada columna es una propiedad.
-- Esto en tu frontend seria:
-- const users = [{ id: 1, name: "Rod", email: "rod@ejemplo.com" }]
SELECT * FROM users;La diferencia clave: en una base de datos relacional, las tablas se conectan entre si con llaves foraneas. Un post tiene un author_id que apunta al id de users.
SELECT: traer datos
-- Todo de una tabla
SELECT * FROM users;
-- Solo las columnas que necesitas (siempre preferible)
SELECT name, email FROM users;
-- Con alias para claridad
SELECT name AS nombre, email AS correo FROM users;Regla de oro: nunca uses SELECT * en produccion. Trae solo lo que necesitas. Es mas rapido y consume menos memoria.
WHERE: filtrar
-- Igualdad
SELECT * FROM users WHERE email = 'rod@ejemplo.com';
-- Comparacion
SELECT * FROM posts WHERE created_at > '2026-01-01';
-- Multiples condiciones
SELECT * FROM posts
WHERE published = true
AND author_id = 1;
-- Busqueda parcial (LIKE)
SELECT * FROM posts WHERE title ILIKE '%nextjs%';ILIKE es la version case-insensitive de LIKE. En PostgreSQL lo vas a usar mucho mas que LIKE.
JOIN: combinar tablas
Aqui es donde SQL se pone interesante. Tienes datos en tablas separadas y necesitas combinarlos.
-- Traer posts con el nombre del autor
SELECT posts.title, users.name AS author
FROM posts
INNER JOIN users ON posts.author_id = users.id
WHERE posts.published = true;Los dos JOINs que vas a usar siempre:
-- INNER JOIN: solo trae filas que tienen match en ambas tablas
-- Si un post no tiene autor, no aparece
SELECT posts.title, users.name
FROM posts
INNER JOIN users ON posts.author_id = users.id;
-- LEFT JOIN: trae TODOS los de la izquierda, con o sin match
-- Si un usuario no tiene posts, aparece con NULL en las columnas de posts
SELECT users.name, posts.title
FROM users
LEFT JOIN posts ON users.id = posts.author_id;Agregaciones: contar y resumir
-- Cuantos posts tiene cada autor
SELECT users.name, COUNT(posts.id) AS total_posts
FROM users
LEFT JOIN posts ON users.id = posts.author_id
GROUP BY users.name;
-- Filtrar grupos (HAVING, no WHERE)
SELECT users.name, COUNT(posts.id) AS total_posts
FROM users
LEFT JOIN posts ON users.id = posts.author_id
GROUP BY users.name
HAVING COUNT(posts.id) > 5;Las funciones de agregacion mas comunes:
COUNT()-- contar filasSUM()-- sumar valoresAVG()-- promedioMAX()/MIN()-- maximo y minimo
ORDER BY y LIMIT
-- Los 10 posts mas recientes
SELECT title, created_at
FROM posts
WHERE published = true
ORDER BY created_at DESC
LIMIT 10;
-- Paginacion (pagina 2, 10 por pagina)
SELECT title, created_at
FROM posts
ORDER BY created_at DESC
LIMIT 10 OFFSET 10;INSERT, UPDATE, DELETE
-- Crear
INSERT INTO users (name, email)
VALUES ('Rod', 'rod@ejemplo.com');
-- Actualizar (SIEMPRE con WHERE)
UPDATE users
SET name = 'Rod Alexanderson'
WHERE id = 1;
-- Eliminar (SIEMPRE con WHERE)
DELETE FROM posts WHERE id = 5;Regla critica: nunca corras UPDATE o DELETE sin WHERE. Sin el WHERE, afectas TODAS las filas de la tabla. En produccion esto es irrecuperable.
Como se traduce al ORM
Si usas Prisma o Drizzle, todo esto se traduce directamente. Entender el SQL te ayuda a entender que hace tu ORM:
| SQL | Prisma |
|---|---|
SELECT * FROM users WHERE id = 1 | prisma.user.findUnique({ where: { id: 1 } }) |
INNER JOIN | include: { posts: true } |
WHERE title ILIKE '%next%' | where: { title: { contains: "next", mode: "insensitive" } } |
ORDER BY created_at DESC LIMIT 10 | orderBy: { createdAt: "desc" }, take: 10 |
COUNT(*) | prisma.post.count() |
Si quieres profundizar en el setup completo con TypeScript, revisa la guia de PostgreSQL para devs TypeScript. Y si estas decidiendo entre ORMs, la comparativa Prisma vs Drizzle te ayuda a elegir.
Preguntas frecuentes
Necesito aprender SQL si uso un ORM como Prisma?
Si, lo basico. El ORM genera SQL por ti, pero cuando una query es lenta o un resultado no tiene sentido, necesitas entender que esta pasando por debajo. No necesitas ser DBA, pero si leer un query plan basico.
Cual es la diferencia entre WHERE y HAVING?
WHERE filtra filas antes de agrupar. HAVING filtra despues de agrupar (con GROUP BY). Si quieres filtrar datos crudos, usa WHERE. Si quieres filtrar resultados de COUNT, SUM o AVG, usa HAVING.
Que tipo de JOIN debo usar?
INNER JOIN para traer solo registros que existen en ambas tablas. LEFT JOIN para traer todos los de la tabla izquierda aunque no tengan match en la derecha. En el 90% de los casos usaras estos dos.
SQL es igual en todas las bases de datos?
La base es la misma (SELECT, INSERT, JOIN, WHERE), pero cada base de datos tiene extensiones propias. PostgreSQL tiene JSONB, arrays y funciones avanzadas que MySQL no tiene. Lo basico que aprendes aqui aplica en todas.
Articulos relacionados
Next.js 16: Guia de Migracion y Novedades
Migra tu proyecto de Next.js 15 a 16. Novedades principales, breaking changes, y pasos para actualizar sin romper tu app.
Testing en Next.js con Vitest y Playwright
Configura testing en tu proyecto Next.js. Unit tests con Vitest, E2E con Playwright, y como integrarlos en tu pipeline de CI/CD.
Tailwind CSS 4: Migracion desde v3
Migra tu proyecto de Tailwind CSS 3 a 4. Cambios principales, nuevo sistema de configuracion, CSS-first config y como actualizar sin romper tu app.