SQL incluye un conjunto de funciones de cadena y numéricas que permiten transformar y formatear datos directamente en la consulta, sin necesidad de procesar los resultados en el código de la aplicación. Usarlas bien reduce el volumen de datos transferidos y simplifica la lógica del servidor.
Este capítulo cubre las funciones de texto y numéricas más usadas en MySQL y sus equivalentes en PostgreSQL, con ejemplos prácticos sobre el esquema de la tienda.
Funciones de cadena
-- Convertir a mayúsculas / minúsculas
SELECT UPPER('hola mundo'); -- 'HOLA MUNDO'
SELECT LOWER('AURICULARES'); -- 'auriculares'
-- Longitud en bytes vs longitud en caracteres
SELECT LENGTH('café'); -- 5 (en UTF-8, 'é' ocupa 2 bytes)
SELECT CHAR_LENGTH('café'); -- 4 (número de caracteres)
-- Eliminar espacios
SELECT TRIM(' hola '); -- 'hola'
SELECT LTRIM(' hola '); -- 'hola '
SELECT RTRIM(' hola '); -- ' hola'
SELECT TRIM(BOTH '_' FROM '__test__'); -- 'test'
-- Extraer parte de una cadena
SELECT SUBSTRING('Auriculares Bluetooth', 1, 11); -- 'Auriculares'
SELECT SUBSTRING('Auriculares Bluetooth', -9); -- 'Bluetooth'
SELECT LEFT('Auriculares', 5); -- 'Auric'
SELECT RIGHT('Bluetooth', 4); -- 'ooth'
-- Concatenar
SELECT CONCAT('Hola', ' ', 'mundo'); -- 'Hola mundo'
SELECT CONCAT_WS(' — ', nombre, ciudad) -- 'Ana García — Madrid'
FROM clientes WHERE id = 1;
-- Reemplazar
SELECT REPLACE('Camiseta algodón M', 'M', 'L'); -- 'Camiseta algodón L'
-- Buscar posición
SELECT LOCATE('USB', 'Cable USB-C 2m'); -- 7 (posición 1-based; 0 = no encontrado)
SELECT INSTR('Cable USB-C 2m', 'USB'); -- 7 (equivalente en MySQL)
-- Rellenar con caracteres
SELECT LPAD('42', 5, '0'); -- '00042'
SELECT RPAD('hola', 8, '.'); -- 'hola....'
-- Invertir
SELECT REVERSE('SQL'); -- 'LQS'
Ejemplo práctico: normalizar datos
-- Normalizar email a minúsculas y eliminar espacios al insertar
INSERT INTO clientes (nombre, email, ciudad, fecha_alta)
VALUES ('Pedro Sanz', LOWER(TRIM(' [email protected] ')), 'Granada', CURDATE());
-- Buscar clientes cuyo nombre contiene espacios extra
SELECT id, nombre FROM clientes
WHERE nombre != TRIM(nombre);
-- Extraer el dominio del email
SELECT
email,
SUBSTRING(email, LOCATE('@', email) + 1) AS dominio
FROM clientes;
Funciones numéricas
-- Redondear SELECT ROUND(59.999, 2); -- 60.00 SELECT ROUND(59.994, 2); -- 59.99 SELECT ROUND(59.995, 2); -- 60.00 (redondea hacia arriba en .5) -- Techo y suelo SELECT CEIL(4.1); -- 5 (redondea hacia arriba al entero más cercano) SELECT FLOOR(4.9); -- 4 (redondea hacia abajo) -- Valor absoluto y módulo SELECT ABS(-42); -- 42 SELECT MOD(17, 5); -- 2 (equivalente al operador %) SELECT 17 % 5; -- 2 -- Potencias y raíces SELECT POW(2, 10); -- 1024 SELECT SQRT(144); -- 12 -- Truncar (cortar decimales sin redondear) SELECT TRUNCATE(59.999, 2); -- 59.99 (no redondea, corta) -- Número aleatorio entre 0 y 1 SELECT RAND(); -- Número aleatorio entero entre 1 y 100 SELECT FLOOR(RAND() * 100) + 1;
CAST y CONVERT: cambiar tipo de dato
-- CAST: estándar SQL
SELECT CAST('42' AS UNSIGNED); -- 42 (string a entero)
SELECT CAST(42 AS CHAR); -- '42' (entero a string)
SELECT CAST('2024-05-09' AS DATE); -- fecha
SELECT CAST(59.99 AS DECIMAL(10,0)); -- 60
-- CONVERT: equivalente en MySQL con sintaxis alternativa
SELECT CONVERT('42', UNSIGNED);
SELECT CONVERT(42, CHAR);
Las funciones de cadena son útiles en el SELECT pero pueden inhibir el uso de índices cuando se aplican en el WHERE. Por ejemplo, WHERE LOWER(email) = '[email protected]' no puede usar un índice sobre email. La solución es guardar el email ya en minúsculas o usar una collation case-insensitive.
