Pregunta 1¿Cuál de las siguientes es una ventaja correcta de almacenar fechas como cadenas ISO del tipo '2024-03-15'?
Tipos de fecha/hora y tablas STRICT
Con la tabla perf_sales de 50 000 filas, aprende los tres formatos de almacenamiento de fechas (cadenas ISO, julianday, unixepoch), la agregación por año y por rango con date() / strftime() y cómo la tabla typed_strict rechaza desajustes de tipo — todo ejecutado en vivo en el navegador.
Los datos que usaremos — perf_sales
Las fechas se almacenan como cadenas o como números, y las lees o calculas con funciones como date() / strftime().
En la primera mitad, usarás la columna sale_date de la tabla de ventas perf_sales para revisar los tres formatos de almacenamiento y cómo extraer valores; en la segunda mitad, crearás tú mismo una tabla STRICT para ver qué pasa cuando insertas un valor que no coincide con el tipo declarado.
Los tres formatos de almacenamiento de fechas — cadena ISO / julianday / unixepoch
Las fechas y horas se pueden almacenar en tres formatos principales.
| Formato | Valor de ejemplo | Uso principal |
|---|---|---|
| Cadena ISO | '2024-03-15' (con hora: '2024-03-15 12:30:00') | Legible por humanos; la ordenación y la comparación por rango funcionan correctamente como comparación de cadenas (la opción más común) |
| julianday | julianday('2024-03-15') → 2460384.5 (un decimal que cuenta los días desde la antigüedad) | Calcular la diferencia entre dos fechas en días |
| unixepoch | strftime('%s', ...) → 1710460800 (segundos enteros desde 1970-01-01) | Aritmética de tiempo a nivel de segundos / interoperación entre sistemas |
Sea cual sea el formato que almacenes, puedes leerlo de vuelta como 'YYYY-MM-DD' con date() o como 'YYYY-MM-DD HH:MM:SS' con datetime().
Este curso usa la cadena ISO por defecto porque es legible por humanos y fácil de comparar, y solo convierte a julianday / unixepoch cuando hace falta.
-- La misma fecha en 3 formatos (ejemplo de solo lectura)
SELECT '2024-03-15' AS iso_text,
julianday('2024-03-15') AS as_julianday,
strftime('%s','2024-03-15 00:00:00') AS as_unixepoch;
-- Convierte cada uno de los 3 formatos de vuelta a una fecha legible
SELECT date(julianday('2024-03-15')) AS from_jd,
datetime(1710460800,'unixepoch') AS from_unix,
date('2024-03-15') AS from_iso;
-- Con cadenas ISO, la comparación por rango funciona correctamente como comparación de cadenas
SELECT '2024-03-15' BETWEEN '2024-01-01' AND '2024-12-31' AS in_2024; -- 1
Manipula y agrega fechas con date() y strftime()
date(value, modifier...): devuelve la parte de fecha como'YYYY-MM-DD'y te permite hacer aritmética de fechas con modificadores como'+1 month'/'-7 days'/'start of month'strftime(format, value): extrae una parte de la fecha como cadena usando especificadores de formato como%Y(año),%m(mes),%d(día),%w(día de la semana)- Combina
strftime('%Y', sale_date)conGROUP BYpara agregar por año - Como
sale_datese almacena como cadena ISO, las condiciones de rango como `WHERE sale_date >= '2024-01-01'` funcionan correctamente como comparaciones de cadenas
-- Manipulación de fechas (ejemplo de solo lectura)
SELECT date('2024-03-15','+1 month') AS plus_1_month, -- 2024-04-15
date('2024-03-15','start of month') AS month_start, -- 2024-03-01
strftime('%Y', '2024-03-15') AS year_part, -- 2024
strftime('%Y-%m','2024-03-15') AS year_month; -- 2024-03
-- Conteo por año (cadena ISO: extrae el año con strftime y GROUP BY)
SELECT strftime('%Y', sale_date) AS yr, COUNT(*) AS cnt
FROM perf_sales
GROUP BY yr
ORDER BY yr;
Tablas STRICT — imponer tipado estricto
La afinidad de tipos que hemos visto hasta ahora convierte flexiblemente las cadenas con apariencia numérica.
Por el contrario, cuando añades STRICT al final de una definición de tabla, esa tabla rechaza almacenar valores cuyo tipo no coincida con el declarado.
Si intentas insertar una cadena no numérica en una columna numérica, el valor no se convierte implícitamente — obtienes un error.
Úsalo para tablas en las que quieras detectar pronto las confusiones de tipos.
En una tabla STRICT, los tipos de columna permitidos se limitan a INTEGER / REAL / TEXT / BLOB / ANY — INT y los nombres de tipo personalizados no están permitidos.
En el próximo ejercicio crearás tú mismo una tabla typed_strict con STRICT, y en los ejercicios siguientes insertarás valores coincidentes y no coincidentes para ver la diferencia.
-- Declarar y usar una tabla STRICT (ejemplo de solo lectura)
CREATE TABLE IF NOT EXISTS typed_strict(a INTEGER, b TEXT, c REAL) STRICT;
-- Las filas con tipos coincidentes se insertan sin problemas
INSERT INTO typed_strict VALUES (1, '2024-03-15', 1.5);
-- Insertar una cadena no numérica en la columna a INTEGER
-- no se convierte implícitamente -- el INSERT da error:
-- cannot store TEXT value in INTEGER column typed_strict.a
INSERT INTO typed_strict VALUES ('not-a-number', 'x', 1.0);
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Cuál de las siguientes describe correctamente el papel de strftime('%Y', sale_date)?
Pregunta 3¿Cuál de las siguientes describe correctamente qué pasa cuando intentas hacer INSERT de una cadena no numérica en una columna INTEGER de una tabla STRICT?