Aprende leyendo en orden

Cadenas, números, booleanos y conversión implícita de tipos

Con la tabla typed_demo, observa cómo los tipos declarados difieren de las clases de almacenamiento, mira cómo '10' y 123 se convierten de ida y vuelta con typeof(), descubre cómo los booleanos se representan con 0 / 1 y compara todo esto con los tipos estrictos CHAR / VARCHAR / INT / DECIMAL de MySQL ejecutando consultas reales.

Los datos que usaremos — la tabla typed_demo

Cuando creas una columna declaras un tipo como INTEGER / TEXT / REAL, y eso decide cómo la columna trata los valores que contiene.

En este artículo recorrerás cómo se almacenan y comparan cadenas, números y booleanos en SQL, y en qué se diferencia la forma en que la consola de este curso maneja los tipos (también conocido como type affinity (afinidad de tipos) en la documentación de SQLite) de los tipos estrictos de MySQL.

Antes de pasar a los ejercicios, echa un vistazo rápido a las definiciones de columnas y a las filas de muestra de la tabla typed_demo. (Ejecútalo correctamente y aparecerá la explicación.)

① Usa PRAGMA table_info(typed_demo); para revisar los nombres de columna, los tipos declarados y la clave primaria.

② Usa SELECT * FROM typed_demo; para previsualizar cada fila.

Editor SQL

Ejecutar una consulta para ver el resultado

Tipo declarado frente a clase de almacenamiento — cada valor lleva su propio tipo

El tipo que un valor realmente tiene en tiempo de ejecución se llama su clase de almacenamiento, y hay cinco: NULL / INTEGER (números enteros) / REAL (decimales) / TEXT (cadenas) / BLOB (binario).

Puedes comprobar qué clase de almacenamiento tiene un valor en este momento con la función typeof(value).

Si pones una cadena con apariencia numérica en una columna declarada TEXT, la política de la columna es "trata esto como texto", así que se queda como cadena.

Pero si pones una cadena con apariencia numérica como '123' en una columna declarada INTEGER, entra en acción la política de la columna y la convierte en el entero 123 antes de almacenarla.

Tipo declarado frente a clase de almacenamiento
Valor insertadoTipo de columna declaradoTipo almacenado'123'Columna INTEGERentero 123(typeof=integer)'10'Columna TEXTcadena '10'(typeof=text)
El tipo que declaras en una columna es la política de "cómo debe tratarse este valor". '123' entrando en una columna INTEGER se convierte en entero, mientras que '10' entrando en una columna TEXT se queda como cadena. El tipo real por valor siempre se puede comprobar con typeof().
-- Ejemplo rápido e independiente que muestra que "el tipo declarado de la columna decide el tipo almacenado"
-- Una cadena con apariencia numérica en una columna INTEGER se convierte en un entero
CREATE TABLE IF NOT EXISTS aff_probe(num INTEGER, txt TEXT);
INSERT OR IGNORE INTO aff_probe VALUES ('123','123'), ('hello','hello');

-- Usa typeof para inspeccionar la clase de almacenamiento real
SELECT num, typeof(num) AS num_class,
       txt, typeof(txt) AS txt_class
FROM aff_probe;
-- columna num: '123' se convierte en entero, 'hello' no se puede convertir y se queda como texto
-- columna txt: ambos se quedan como texto

Imagina que quieres comprobar "con qué tipo (entero / real / cadena) está realmente almacenado cada valor de typed_demo".

① Extrae las columnas a, b, c y flag de typed_demo.

② Añade también un typeof() para cada columna, con alias a_class / b_class / c_class / flag_class.

③ No filtres las filas — las dos filas deben aparecer en el resultado.

Editor SQL

Ejecutar una consulta para ver el resultado

Las cadenas y los números se convierten de ida y vuelta — '123' y 123

Cuando se necesita un número, una cadena se convierte automáticamente en número; cuando se necesita una cadena, un número se convierte en cadena.

Por ejemplo, '123' + 0 convierte la cadena '123' en el número 123 y devuelve 123, por lo que las cadenas con apariencia numérica se pueden incluir directamente en operaciones aritméticas.

En el sentido contrario, 123 || '' (|| es concatenación de cadenas) convierte el número en cadena.

Los operadores de comparación funcionan de la misma manera: si un lado es una columna INTEGER, el otro lado se alinea como número; si un lado es una columna TEXT, el otro lado se alinea como cadena.

Pero con dos literales en bruto como '1' = 1 no hay columna que fije la política, así que los valores permanecen con tipos distintos y el resultado es 0 (sin coincidencia).

Las cadenas y los números se convierten según el contexto
ExpresiónConversiónResultado'123' + 0'123' pasa anúmero 123123'abc' + 0no convertible,tratado como 00
Cuando se necesita aritmética, las cadenas con apariencia numérica se convierten en números; cuando se necesita concatenación, los números se convierten en cadenas. Una cadena como 'abc' que no se puede convertir en número se trata como 0 en aritmética.
-- Observa la conversión cadena <-> número (ejemplo de solo lectura)
SELECT '123' + 0     AS str_to_num,   -- la cadena pasa a número 123
       'abc' + 0     AS not_a_num,    -- no se puede convertir, pasa a 0
       123 || ''     AS num_to_str,   -- el número pasa a cadena '123'
       typeof('123' + 0) AS class_after_add,
       '1' = 1       AS literal_cmp,  -- literales en bruto: 0 (sin coincidencia)
       7 / 2         AS int_div,      -- entero / entero = entero 3
       7.0 / 2       AS real_div;     -- un decimal en la mezcla da 3.5

Imagina que quieres "tratar las cadenas con apariencia numérica de la columna b (TEXT) de typed_demo como números para aritmética y comparación".

① Extrae la columna b de typed_demo.

② Añade b + 0 con alias b_plus0. Las filas con apariencia numérica pasan a números y las filas no numéricas pasan a 0.

③ Después añade una comprobación de si b como número es mayor que 5, con alias gt5 (como estás comparando un valor de la columna b con un literal numérico, la comparación ocurre entre números).

Editor SQL

Ejecutar una consulta para ver el resultado

Booleanos — TRUE / FALSE se almacenan como 1 / 0

SQL no tiene un tipo booleano independiente — los valores de verdad se representan con los enteros 1 (verdadero) y 0 (falso).

Las expresiones de comparación como 1 = 1 o 3 > 2 devuelven 1 para verdadero y 0 para falso.

En cualquier lugar donde puedas escribir una condición, como CASE WHEN column THEN ..., cualquier cosa distinta de 0 (normalmente 1) se trata como verdadero y 0 se trata como falso.

NULL es un tercer estado que no es ni verdadero ni falso ("desconocido"), y en condiciones WHERE o CASE se comporta como falso en el sentido de que la fila "no se selecciona".

Booleanos como entero 1 / 0
Expresión / valorInterpretación booleana1 / TRUE / 3>2verdadero0 / FALSE / 1>2falsoNULLdesconocido — no se selecciona
Las expresiones de comparación devuelven 1 para verdadero y 0 para falso. Una columna flag que contenga 1 / 0 puede usarse directamente como condición y NULL se trata como un tercer estado que no es ni verdadero ni falso.
-- Las expresiones de comparación devuelven 1 / 0 (ejemplo de solo lectura)
SELECT (1 = 1)  AS is_true,    -- 1
       (1 = 2)  AS is_false,   -- 0
       (3 > 2)  AS gt,         -- 1
       TRUE     AS true_kw,    -- equivalente a 1
       FALSE    AS false_kw;   -- equivalente a 0

-- Usa una columna flag directamente como condición
SELECT a, flag,
  CASE WHEN flag THEN 'enabled' ELSE 'disabled' END AS state
FROM typed_demo;

Imagina que quieres "convertir la columna flag (entero 1 / 0) de typed_demo en una etiqueta legible para humanos".

① Extrae a y flag de typed_demo.

② Usa flag directamente como condición en un CASE WHEN ... y añade una tercera columna con alias state que devuelva 'enabled' para las filas verdaderas (1) y 'disabled' para las falsas (0).

③ Para ver también qué devuelve una expresión de comparación para verdadero / falso, añade una cuarta columna con el resultado de flag = 1 con alias is_on.

Editor SQL

Ejecutar una consulta para ver el resultado

Comparado con los tipos estrictos de MySQL

Lo que has visto hasta ahora es conversión implícita de tipos — los valores se reformulan flexiblemente según el contexto.

Por el contrario, MySQL y Oracle tienen tipos estrictos: cuando declaras CHAR(10) / VARCHAR(255) / TEXT para cadenas o INT / DECIMAL(10,2) para números, solo entran valores de ese tipo y la longitud y la precisión se imponen exactamente como están declaradas.

Un número normalmente no se cuela en una columna de cadena por conversión implícita y los valores que superan la longitud declarada o bien dan error o se truncan.

El código de abajo es la forma de MySQL de declarar tipos.

La consola de este curso no impone comprobaciones de longitud por diseño, así que cuando estudies restricciones de longitud como VARCHAR(10), simplemente recuerda que "así es como lo escribe MySQL" — esa sintaxis se traslada cuando pases a otras bases de datos.

Conversión implícita de tipos frente a los tipos estrictos de MySQL
Consola de este curso(conversión implícita)MySQL(tipos estrictos)'123' en columna INTEGER ->almacenado como entero 123Columna INT = solo números /VARCHAR(10) = hasta 10 caract.Longitud / precisiónno se imponenExceso de longitud:error / truncamiento
La consola de este curso usa conversión implícita de tipos — '123' insertado en una columna INTEGER pasa a entero y la sentencia se ejecuta. MySQL usa tipos estrictos — el tipo y la longitud declarados se imponen, y los valores no coincidentes dan error o se truncan.
-- Declaraciones de tipos estrictos en MySQL (solo lectura — no lo ejecutes en esta consola)
CREATE TABLE product (
  id        INT            PRIMARY KEY,   -- solo enteros
  code      CHAR(8),                      -- longitud fija, 8 caracteres
  name      VARCHAR(100)   NOT NULL,      -- hasta 100 caracteres
  note      TEXT,                         -- cadena larga
  price     DECIMAL(10,2)  NOT NULL,      -- 8 dígitos + 2 decimales
  in_stock  TINYINT(1)     DEFAULT 0      -- bandera 0/1 para booleanos
);

-- En MySQL, poner 101 caracteres en VARCHAR(100)
-- dará error o se truncará según la configuración.
-- Poner 'abc' en una columna INT dará error.
-- La consola de este curso ejecuta todo gracias a la conversión implícita de tipos.

Tips — CHAR frente a VARCHAR y cuándo usar cada uno

`CHAR(n)` es de longitud fija: si el valor es más corto que n caracteres, se rellena con espacios al final hasta completar los n caracteres.

`VARCHAR(n)` es de longitud variable: mantiene el valor con su longitud real (n es la cota superior).

Usa `CHAR` cuando: el valor siempre tiene una longitud fija, como un código de país ('JP' / 'US'), un código de género o una sección de longitud fija de un hash. La disposición fija puede ser marginalmente más rápida para comparaciones y cálculos de posición de registro.

Usa `VARCHAR` cuando: las longitudes varían — nombres, direcciones de correo, títulos, descripciones, etc. Solo ocupa el espacio que realmente necesita, por lo que el almacenamiento queda más pequeño.

En caso de duda, `VARCHAR` es la opción más segura por defecto. Usar CHAR para datos de longitud variable puede provocar desajustes sutiles en las comparaciones por el relleno de espacios finales (por ejemplo, 'JP' frente a 'JP ' manejados de forma inconsistente).

Imagina que quieres "sumar y promediar los valores de la columna b (TEXT) de typed_demo como números, y contar cuántas filas son verdaderas en la columna flag". Esto demuestra que la conversión implícita de tipos permite agregar columnas de texto numéricamente.

① Obtén la suma de la columna b de typed_demo con alias sum_b, y el promedio con alias avg_b. Solo las filas con apariencia numérica se suman como números.

② En la misma consulta, obtén la suma de la columna flag con alias enabled_count (como flag es 1 / 0, la suma equivale al conteo de filas verdaderas).

③ No agrupes por nada — devuelve una sola fila de resumen para toda la tabla.

Editor SQL

Ejecutar una consulta para ver el resultado
QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1En la consola de este curso, haces INSERT de la cadena '123' en una columna declarada INTEGER. ¿Qué afirmación es correcta?

Pregunta 2¿Qué afirmación describe correctamente cómo se representan los booleanos en SQL?

Pregunta 3¿Qué afirmación describe correctamente la diferencia entre la consola de este curso (conversión implícita de tipos) y los tipos estrictos de MySQL?