La mayoría de las preguntas de entrevista de SQL para roles de QA se reducen a cuatro patrones: SELECT con WHERE para verificar que se guardó un registro, LEFT JOIN para encontrar registros huérfanos, COUNT con GROUP BY para encontrar duplicados, y DELETE para limpiar datos de prueba. Los entrevistadores quieren respuestas prácticas vinculadas a escenarios de testing, no definiciones de libro de texto. Este artículo cubre las diez preguntas que realmente aparecen en entrevistas de QA de nivel junior, medio y senior, con respuestas enmarcadas en casos de uso comunes de testing.

Qué nivel de SQL evalúan las entrevistas de QA

Para la mayoría de los roles de QA automation, en el nivel Junior se espera SELECT, WHERE, filtrado básico y entender qué hace un JOIN conceptualmente. En nivel medio se añaden JOINs (INNER, LEFT), GROUP BY, funciones de agregación (COUNT, SUM, AVG) y subconsultas. En Senior se evalúan funciones de ventana, conceptos de optimización de consultas y explicar planes de ejecución.

Si la descripción del trabajo menciona "testing de base de datos" o "validación de datos", espera preguntas de SQL más profundas. De lo contrario, el nivel junior a medio es típico.

Preguntas centrales y respuestas

1. "¿Qué consultas SQL usas más frecuentemente en testing?"

Qué quieren escuchar: Casos de uso prácticos, no consultas teóricas. Respuesta sólida: "Las consultas que más uso son SELECT con WHERE para verificar que un registro se guardó con los valores correctos, COUNT para comprobar cuántos registros existen, y LEFT JOIN para verificar relaciones entre tablas. Por ejemplo, verificar que al crear un pedido también se crearon las filas de order_items esperadas. También uso DELETE e INSERT para configurar y limpiar datos de prueba en entornos inferiores."

2. "¿Cómo verificarías que un usuario se creó correctamente después de un registro?"

-- Encontrar el usuario y verificar los campos clave
SELECT id, email, role, is_active, created_at
FROM users
WHERE email = 'test_user@example.com';

Luego verificar:

  • La fila existe (si hay 0 filas, el registro no escribió en la DB)
  • email coincide con lo que se envió
  • role es 'member' (no 'admin' por defecto)
  • is_active es false (si se requiere confirmación por email antes de la activación)
  • created_at es reciente (no es una fila preexistente)

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

WHERE filtra filas antes de la agregación. HAVING filtra grupos después de la agregación.

-- WHERE: filtrar filas individuales
SELECT user_id, amount FROM orders WHERE status = 'completed';

-- HAVING: filtrar grupos (después de GROUP BY)
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 5;
-- Devuelve usuarios que tienen más de 5 pedidos

Relevancia en testing: Usarías HAVING para encontrar usuarios con entradas duplicadas, pedidos por encima de un umbral, o cualquier condición agregada.

4. "Explica la diferencia entre INNER JOIN y LEFT JOIN."

INNER JOIN devuelve filas que existen en AMBAS tablas, solo coincidencias. LEFT JOIN devuelve TODAS las filas de la tabla izquierda, más las filas coincidentes de la derecha. Las filas de la tabla derecha sin coincidencia tienen valores NULL.

-- ¿Qué usuarios realizaron al menos un pedido?
SELECT u.email
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
-- Solo usuarios que tienen pedidos

-- ¿Qué usuarios NUNCA realizaron un pedido?
SELECT u.email
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
-- Usuarios sin pedido coincidente (la verificación de NULL)

Relevancia en testing: LEFT JOIN con WHERE right.id IS NULL es un patrón clásico para encontrar registros "huérfanos" o verificar que algo NO se creó.

5. "¿Cómo encontrarías registros duplicados en una tabla?"

SELECT email, COUNT(*) as count
FROM users
GROUP BY email
HAVING COUNT(*) > 1;

Esto encuentra emails que aparecen más de una vez. Reemplaza email con el campo que debería ser único.

Caso de uso en testing: Después de una migración o importación de datos, verificar que no se crearon registros duplicados.

6. "¿Cuál es la diferencia entre DELETE y TRUNCATE?"

| | DELETE | TRUNCATE |

|-|--------|---------|

| Elimina | Filas específicas (con WHERE) o todas las filas | Todas las filas (no es posible usar WHERE) |

| Rollback | Se puede revertir (en una transacción) | Generalmente no (operación DDL) |

| Triggers | Activa triggers DELETE a nivel de fila | No activa triggers |

| Velocidad | Más lento en tablas grandes | Mucho más rápido |

| Uso en testing | Configurar/limpiar datos de prueba específicos | Resetear tablas enteras entre ejecuciones |

-- Eliminar solo el usuario de prueba
DELETE FROM users WHERE email LIKE 'test_%@example.com';

-- Limpiar la tabla test_runs completa entre suites
TRUNCATE TABLE test_runs;

7. "¿Cómo usas SQL para configurar datos de prueba?"

Respuesta sólida: "Uso INSERT para crear usuarios de prueba, pedidos o cualquier dato prerrequisito en entornos inferiores. También uso SELECT para confirmar las precondiciones antes de que corra un test: por ejemplo, verificar que el usuario con el que voy a probar no tenga ya una cuenta. Después de los tests, limpio con DELETE usando los mismos identificadores que usé para crear los datos, para dejar el entorno limpio para la próxima ejecución." Ejemplo:

-- Configuración: crear un usuario de prueba
INSERT INTO users (email, password_hash, role, is_active)
VALUES ('playwright_test@example.com', '$2b$10$hashedpassword', 'member', true);

-- Verificación: comprobar que existe con los valores correctos
SELECT id, email, role FROM users WHERE email = 'playwright_test@example.com';

-- Limpieza: eliminarlo
DELETE FROM users WHERE email = 'playwright_test@example.com';

8. "¿Cómo encontrarías todos los pedidos realizados en los últimos 7 días?"

SELECT id, user_id, total, status, created_at
FROM orders
WHERE created_at >= NOW() - INTERVAL '7 days'
ORDER BY created_at DESC;

(La sintaxis varía ligeramente según la base de datos: PostgreSQL usa INTERVAL '7 days', MySQL usa INTERVAL 7 DAY, SQL Server usa DATEADD(day, -7, GETDATE()))

9. "¿Qué es una subconsulta y cuándo la usarías?"

Una subconsulta es una consulta dentro de otra consulta:

-- Encontrar usuarios que realizaron pedidos de más de $100
SELECT email FROM users
WHERE id IN (
    SELECT user_id FROM orders WHERE total > 100
);

Relevancia en testing: Útil cuando necesitas filtrar por una condición que involucra otra tabla sin hacer un JOIN.

10. "¿Cómo verificas la integridad referencial después de un delete?"

Si eliminas un usuario, puede que quieras verificar que sus registros relacionados también se eliminaron (borrado en cascada) o que las restricciones de clave foránea evitaron registros huérfanos.

-- Confirmar que el usuario fue eliminado
SELECT COUNT(*) FROM users WHERE id = 123;
-- Esperado: 0

-- Confirmar que los pedidos relacionados también fueron eliminados (cascada)
SELECT COUNT(*) FROM orders WHERE user_id = 123;
-- Esperado: 0 (si está configurado el borrado en cascada)

-- O confirmar que los pedidos siguen existiendo (si se usa borrado lógico)
SELECT id, user_id, deleted_at FROM orders WHERE user_id = 123;
-- Esperado: filas con deleted_at asignado

Consejos prácticos para la entrevista

Si te piden escribir una consulta en una pizarra o en un editor de texto

Empieza diciendo qué debería hacer la consulta antes de escribirla, escribe la estructura básica primero (SELECT ... FROM ... WHERE ...) y luego añade complejidad, y menciona que querrías probar la consulta con datos reales antes de finalizarla.

Si no recuerdas la sintaxis exacta

Di "Verificaría la documentación para la sintaxis exacta, pero el enfoque sería..." y explica la lógica. Esto es mucho mejor que adivinar la sintaxis incorrecta y defenderla.

Si te preguntan sobre una base de datos que no conoces

Algo como "Mi experiencia es principalmente con PostgreSQL, pero el concepto es el mismo en MySQL: la sintaxis para la aritmética de fechas es ligeramente diferente" funciona bien. Mostrar conciencia de las diferencias entre bases de datos es un plus.

Referencia rápida: consultas que más usan los QA engineers

-- Verificar que se creó un registro
SELECT * FROM table WHERE id = 123;

-- Verificar conteo (registro creado o eliminado)
SELECT COUNT(*) FROM orders WHERE user_id = 456;

-- Encontrar duplicados
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;

-- Encontrar registros huérfanos (no deberían existir)
SELECT o.* FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL;

-- Registros recientes
SELECT * FROM logs WHERE created_at > NOW() - INTERVAL '1 hour';

-- Limpiar datos de prueba
DELETE FROM users WHERE email LIKE 'test_%';

→ See also: SQL para QA: Las Consultas que Realmente Necesitas | Pruebas de Base de Datos para Ingenieros QA: Consultas SQL que Todo Tester Debe Conocer | Cómo Prepararse para una Entrevista Técnica QA: Guía Paso a Paso