guias·8 min de lectura

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 más usado en el mundo con 58.6% de adopción según el Stack Overflow Survey 2025. Y si eres dev frontend que esta pasando a fullstack, es el skill que más te va a servir después 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.

sql
-- Esto en tu frontend sería:
-- 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

sql
-- 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 producción. Trae solo lo que necesitas. Es más rápido y consume menos memoria.

WHERE: filtrar

sql
-- Igualdad
SELECT * FROM users WHERE email = 'rod@ejemplo.com';
 
-- Comparación
SELECT * FROM posts WHERE created_at > '2026-01-01';
 
-- múltiples condiciones
SELECT * FROM posts
WHERE published = true
  AND author_id = 1;
 
-- búsqueda parcial (LIKE)
SELECT * FROM posts WHERE title ILIKE '%nextjs%';

ILIKE es la versión case-insensitive de LIKE. En PostgreSQL lo vas a usar mucho más que LIKE.

JOIN: combinar tablas

aquí es donde SQL se pone interesante. Tienes datos en tablas separadas y necesitas combinarlos.

sql
-- 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:

sql
-- 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

sql
-- cuántos 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 agregación más comunes:

  • COUNT() -- contar filas
  • SUM() -- sumar valores
  • AVG() -- promedio
  • MAX() / MIN() -- máximo y mínimo

ORDER BY y LIMIT

sql
-- Los 10 posts más recientes
SELECT title, created_at
FROM posts
WHERE published = true
ORDER BY created_at DESC
LIMIT 10;
 
-- Paginación (página 2, 10 por página)
SELECT title, created_at
FROM posts
ORDER BY created_at DESC
LIMIT 10 OFFSET 10;

INSERT, UPDATE, DELETE

sql
-- 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 crítica: nunca corras UPDATE o DELETE sin WHERE. Sin el WHERE, afectas TODAS las filas de la tabla. En producción esto es irrecuperable.

cómo se traduce al ORM

Si usas Prisma o Drizzle, todo esto se traduce directamente. Entender el SQL te ayuda a entender qué hace tu ORM:

SQLPrisma
SELECT * FROM users WHERE id = 1prisma.user.findUnique({ where: { id: 1 } })
INNER JOINinclude: { posts: true }
WHERE title ILIKE '%next%'where: { title: { contains: "next", mode: "insensitive" } }
ORDER BY created_at DESC LIMIT 10orderBy: { createdAt: "desc" }, take: 10
COUNT(*)prisma.post.count()

Si quieres profundizar en el setup completo con TypeScript, revisa la guía de PostgreSQL para devs TypeScript. Y si estas decidiendo entre ORMs, la comparativa Prisma vs Drizzle te ayuda a elegir.

#sql#postgresql#frontend#base-de-datos#fullstack

Preguntas frecuentes

¿Necesito aprender SQL si uso un ORM como Prisma?

Si, lo básico. 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 básico.

¿Cuál es la diferencia entre WHERE y HAVING?

WHERE filtra filas antes de agrupar. HAVING filtra después de agrupar (con GROUP BY). Si quieres filtrar datos crudos, usa WHERE. Si quieres filtrar resultados de COUNT, SUM o AVG, usa HAVING.

¿Qué 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 básico que aprendes aquí aplica en todas.