fundamentos · temario
1.3tema 3 de 4

SQL y Datos

SELECT, JOIN, GROUP BY, índices, pandas básico y limpieza de datos.

SQL (Structured Query Language) es el lenguaje universal para consultar bases de datos relacionales. En el ciclo de vida de un proyecto de IA, la mayoría de los datos de entrenamiento viven en bases de datos SQL antes de convertirse en DataFrames o tensores. No saber SQL te deja dependiente de otros para obtener tus propios datos.

La operación fundamental es SELECT ... FROM ... WHERE. A partir de ahí, JOIN permite combinar tablas relacionadas, GROUP BY permite agregar (contar, sumar, promediar) por categorías, y ORDER BY / LIMIT permiten paginar resultados. Con estas cuatro construcciones se resuelven el 80% de las consultas del día a día.

Los índices son la diferencia entre una consulta que tarda milisegundos y una que tarda minutos. Un índice es una estructura de datos auxiliar (B-tree o hash) que permite al motor de base de datos encontrar filas sin escanear la tabla completa. La regla de oro: crea índices en las columnas que aparecen en WHERE, JOIN ON y ORDER BY.

pandas es la librería de análisis de datos de Python. Un DataFrame es una tabla en memoria con columnas tipadas, operaciones vectorizadas y métodos para filtrar, agrupar, mergear y transformar datos. La transición mental de SQL a pandas es directa: SELECT → df[cols], WHERE → df[df.col > val], GROUP BY → df.groupby().

La limpieza de datos (data cleaning) consume entre el 60% y el 80% del tiempo en un proyecto real. Los problemas más comunes son: valores nulos (NaN), duplicados, tipos incorrectos (número guardado como string), outliers y formatos inconsistentes (fechas en distintos formatos). Detectar estos problemas antes de entrenar un modelo es crítico.

Un pipeline de datos bien construido es reproducible: dado el mismo archivo fuente, produce exactamente el mismo dataset limpio. Esto significa que cada paso de transformación es una función pura, los parámetros son configurables, y el proceso se puede re-ejecutar desde cero sin efectos secundarios en la base de datos de producción.

structure.txt
-- SELECT básico
SELECT id, name, score
FROM users
WHERE score > 0.8
ORDER BY score DESC
LIMIT 10;

-- INNER JOIN
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = 'completed';

-- GROUP BY + HAVING
SELECT category, COUNT(*) AS count, AVG(price) AS avg_price
FROM products
GROUP BY category
HAVING COUNT(*) > 5
ORDER BY avg_price DESC;

-- Crear índice
CREATE INDEX idx_users_score ON users(score);

# pandas — operaciones equivalentes
import pandas as pd

df = pd.read_csv('data.csv')
df.info()                              # tipos y nulos
df.describe()                          # estadísticas básicas
df.isnull().sum()                      # conteo de NaN por columna
df.dropna(subset=['score'])            # eliminar filas con NaN en score
df.fillna({'category': 'unknown'})     # rellenar NaN con valor fijo
df[df['score'] > 0.8]                  # filtro (WHERE)
df.groupby('category')['price'].mean() # GROUP BY + AVG
df.sort_values('score', ascending=False).head(10)  # ORDER BY + LIMIT

Debugging lab

Detecta y corrige el error en el código.

0/5 tests passing0%
  1. 1.3.5.1

    SELECT name, COUNT(orders) FROM users JOIN orders ON users.id = orders.id GROUP BY name;

  2. 1.3.5.2

    SELECT category, AVG(price) FROM products GROUP BY category WHERE AVG(price) > 100;

  3. 1.3.5.3

    df_clean = df.dropna() df_clean = df_clean.drop_duplicates print(df_clean.shape)

  4. 1.3.5.4

    counts = df.groupby('category').count('id')

  5. 1.3.5.5

    df['date'] = pd.to_datetime(df['date']) df['year'] = df['date'].dt.year df_filtered = df[df.year == 2024]