Aprende SQL · lección gratuita
En SQLite no existe un tipo DATE nativo: las fechas se guardan como TEXT en formato ISO 'YYYY-MM-DD'. Este formato es clave porque ordena alfabéticamente igual que cronológicamente y es compatible con todas las funciones de fecha. Con strftime, date, julianday y aritmética de intervalos puedes extraer partes, sumar meses, calcular antigüedad y agrupar por periodo.
strftime(formato, fecha): extrae o formatea partes. %Y (año), %m (mes), %d (día), %Y-%m (año-mes), %w (día de semana 0=domingo).date(fecha, modificador): aplica desplazamientos. date(fecha, '+1 month'), date(fecha, '-7 days'), date(fecha, 'start of month').julianday(fecha): convierte la fecha a un número de día continuo. La resta de dos julianday da la diferencia en días: julianday(a) - julianday(b).CAST((julianday(ref) - julianday(fecha_contratacion)) / 365.25 AS INTEGER) da los años completos.GROUP BY strftime('%Y-%m', fecha) agrupa por mes; strftime('%Y', fecha) por año.Como el formato es 'YYYY-MM-DD', una comparación de texto fecha >= '2024-01-01' funciona perfectamente como filtro cronológico, y ORDER BY fecha ordena en el tiempo. No necesitas convertir nada para filtrar rangos: WHERE fecha BETWEEN '2023-01-01' AND '2023-12-31'.
strftime siempre devuelve TEXT, incluso para el año o el mes. Por eso strftime('%Y', fecha) devuelve '2023' (cadena). Si necesitas operar aritméticamente (restar años, comparar como número) envuélvelo en CAST(strftime('%Y', fecha) AS INTEGER) o súmale 0. Esto enlaza con la lección 12 sobre conversión de tipos.
La forma robusta de la antigüedad en años completos es con julianday: cuentas los días entre la contratación y una fecha de referencia, y divides entre 365.25 (promedio que compensa años bisiestos). El CAST(... AS INTEGER) trunca a años enteros. Usamos una fecha de referencia fija ('2024-06-01') en los ejemplos para que el resultado sea reproducible; en producción usarías date('now').
date(fecha, '+1 month') te da el mismo día del mes siguiente; encadenas modificadores: date(fecha, '+1 year', 'start of month'). Cuidado con fines de mes: date('2024-01-31', '+1 month') produce '2024-03-02', porque febrero no tiene día 31 y SQLite normaliza el desbordamiento.
SELECT nombre, fecha_contratacion, strftime('%Y', fecha_contratacion) AS anio FROM empleados ORDER BY fecha_contratacion LIMIT 6
-- Antigüedad de cada empleado en años completos a una fecha de referencia fija.
-- julianday cuenta días; dividir entre 365.25 y truncar da años enteros.
SELECT
nombre,
fecha_contratacion,
CAST((julianday('2024-06-01') - julianday(fecha_contratacion)) / 365.25 AS INTEGER) AS antiguedad_anios
FROM empleados
ORDER BY antiguedad_anios DESC, id
LIMIT 8;
-- Extraer partes de la fecha y construir el año-mes del pedido.
SELECT
id,
fecha,
strftime('%Y', fecha) AS anio,
strftime('%m', fecha) AS mes,
strftime('%Y-%m', fecha) AS periodo
FROM pedidos
ORDER BY fecha
LIMIT 6;
-- Pedidos agrupados por mes (volumen mensual).
SELECT
strftime('%Y-%m', fecha) AS periodo,
COUNT(*) AS total_pedidos
FROM pedidos
GROUP BY periodo
ORDER BY periodo;
-- Aritmética de fechas: fecha de renovación = un año después del alta del cliente.
SELECT
empresa,
fecha_alta,
date(fecha_alta, '+1 year') AS proxima_renovacion,
CAST(julianday('2024-06-01') - julianday(fecha_alta) AS INTEGER) AS dias_como_cliente
FROM clientes
ORDER BY fecha_alta
LIMIT 6;
💡strftimedevuelve siempre texto. Si comparasstrftime('%m', fecha) = 5fallará silenciosamente porque comparas'05'(texto) con5(número). Usastrftime('%m', fecha) = '05'oCAST(strftime('%m', fecha) AS INTEGER) = 5.
| Función | Qué hace |
|---|---|
strftime('%Y', f) | Año como texto ('2023') |
strftime('%m', f) / '%d' | Mes / día como texto ('05', '14') |
strftime('%Y-%m', f) | Año-mes, ideal para agrupar |
date(f, '+1 month') | Suma/resta intervalos ('+N days/months/years') |
date(f, 'start of month') | Primer día del mes |
julianday(f) | Día juliano (número); resta = diferencia en días |
(jd_a - jd_b) / 365.25 | Diferencia aproximada en años |
---
← Funciones de textoConversión de tipos: CAST, COALESCE y NULLIF →