Columnas calculadas en SQL: funciones y CASE

Aprende a calcular nuevas columnas en consultas SQL. Realiza operaciones aritméticas con alias de columna claros, convierte valores entre tipos de datos, limpia y recorta textos como nombres y direcciones de correo electrónico, y calcula fechas, meses, edades y plazos. Gestiona los valores ausentes con la lógica de NULL, COALESCE y NULLIF, y clasifica filas en categorías con expresiones CASE. Los ejemplos se ejecutan en SQLite y PostgreSQL, y se señalan las diferencias que encontrarás en MySQL, SQL Server y Oracle.

PrincipianteUnidad 3 de 6 del curso Curso de Fundamentos de SQL

Lo que aprenderás

  1. Calcula nuevos valores para cada fila con operaciones aritméticas y funciones, asigna nombres claros a los resultados y evita que los tipos de datos cambien la respuesta.
    • Calcula nuevas columnas y asígnales nombres mediante alias
      Escribe expresiones en la lista SELECT, etiqueta los resultados con AS y comprende en qué partes de una consulta se pueden utilizar esas etiquetas.
    • Realiza cálculos con operadores aritméticos y funciones numéricas
      Utiliza +, -, *, / y % en el orden correcto, evita sorpresas con la división entera y redondea los resultados con ROUND y funciones relacionadas.
    • Convierte valores entre tipos de datos
      Reconoce el tipo de cada valor, conviértelo explícitamente con CAST e identifica las conversiones automáticas que cambian la ordenación, las comparaciones y los resultados.
  2. Predice cómo afecta NULL a los cálculos, las comparaciones y los filtros, y sustituye o genera valores ausentes de forma deliberada.
    • Predice cómo se comporta NULL en cálculos y condiciones
      Explica qué significa NULL, cómo se propaga por las expresiones y por qué una condición que encuentra NULL no es ni verdadera ni falsa.
    • Sustituye y genera valores ausentes con COALESCE y NULLIF
      Rellena los valores ausentes con COALESCE, convierte ceros y valores marcadores en NULL con NULLIF y elige valores de sustitución que conserven el significado de los datos.
  3. Concatena, limpia, mide y recorta valores de texto para que los nombres, las direcciones de correo electrónico y los códigos sean uniformes y utilizables.
    • Concatena y limpia valores de texto
      Concatena texto, cambia entre mayúsculas y minúsculas, elimina espacios de los extremos y sustituye caracteres; anida estas funciones para limpiar entradas desordenadas.
    • Mide y extrae partes del texto
      Cuenta caracteres, encuentra la posición en la que aparece un carácter y extrae fragmentos de texto utilizando posiciones que empiezan en 1.
  4. Escribe y lee correctamente los valores de fecha, extrae sus componentes y dales formato, y realiza cálculos con días, meses y períodos de tiempo.
    • Escribe, almacena y lee valores de fecha y hora
      Conoce los tipos de fecha y hora, escribe fechas en el formato ISO inequívoco, convierte texto en fechas y obtén la fecha y la hora actuales.
    • Extrae partes de las fechas y dales formato
      Extrae el año, el mes o el día de la semana, agrupa fechas por períodos y convierte fechas en texto legible.
    • Realiza cálculos con fechas y filtra por intervalos de fechas
      Añade días y meses, mide el tiempo entre dos fechas y escribe filtros de fecha que incluyan todas las filas de un período.
  5. Convierte condiciones en etiquetas, categorías y órdenes personalizados con CASE, y combínalo con las demás funciones en consultas completas para informes.
    • Clasifica filas en categorías con CASE de búsqueda
      Escribe CASE WHEN … THEN … ELSE … END, ordena las condiciones para que cada fila quede en el grupo correcto y gestiona los valores límite y los NULL.
    • Utiliza CASE simple y aplica CASE en distintas partes de una consulta
      Convierte códigos en etiquetas con CASE simple, crea indicadores y órdenes personalizados, y reconoce las formas abreviadas que ofrecen otras bases de datos.
    • Combina funciones en una consulta completa para informes
      Construye paso a paso un informe con varias columnas calculadas, anida correctamente las funciones y comprueba cada columna con filas calculadas a mano.

Guía de estudio de Columnas calculadas en SQL

5 capítulos

1

Crea columnas calculadas con expresiones y alias

Las columnas calculadas transforman los valores que ya hay en una fila en respuestas útiles: un importe de línea, un descuento o una variación porcentual. Los alias claros hacen legibles esos resultados, mientras que los paréntesis y los tipos de datos determinan lo que SQL calcula realmente. Construirás expresiones en pequeños pasos, verás por qué la división entera puede eliminar una parte fraccionaria y elegirás conversiones explícitas cuando la forma de almacenamiento no sea adecuada para la operación.

1.1 Calcula nuevas columnas y asígnales nombres mediante alias

Una columna del resultado puede mostrar un valor que no está almacenado en ningún lugar de la tabla. SQL lo calcula a partir de la fila actual. Una expresión combina columnas, valores fijos, operadores y llamadas a funciones.

Calcula un valor para cada fila
SELECT order_id,
       quantity * unit_price AS line_total
FROM orders;

Para una cantidad de 3 y un precio unitario de 12,50, la nueva columna muestra 37.5. Cada fila aporta su propia cantidad y precio. La consulta deja intactas las columnas almacenadas. Una función de una sola fila, como ROUND(unit_price, 0), también devuelve un valor por cada fila de entrada. Añadirla a la lista SELECT no combina filas. En cambio, una función de agregación como SUM o AVG calcula un valor para un grupo.

El nombre que sigue a AS es un alias de columna: un encabezado para el resultado. Sin él, SQLite utiliza como encabezado el texto de la expresión; PostgreSQL utiliza ?column? para esta expresión aritmética. AS es opcional, pero facilita distinguir un nombre de una coma ausente.

Elige nombres y comillas

Utiliza un nombre sencillo como line_total: letras, dígitos y guiones bajos, empezando por una letra. Un nombre que contenga un espacio o una palabra reservada necesita comillas dobles: AS "Line Total" o AS "order". Las comillas simples delimitan valores de texto, como 'Boston'. MySQL también acepta comillas invertidas para los nombres y SQL Server acepta corchetes.

PostgreSQL convierte los nombres sin comillas a minúsculas: AS LineTotal produce linetotal. Las comillas dobles conservan la escritura en AS "LineTotal". SQLite conserva el alias tal como se escribió. Los nombres en minúsculas con guiones bajos funcionan bien en ambos.

Utiliza un alias en la etapa adecuada

El orden lógico es FROM, WHERE, SELECT y, después, ORDER BY. Se elige la tabla y se filtran las filas antes de que las expresiones de salida reciban sus alias. La ordenación se realiza después.

SELECT order_id,
       quantity * unit_price AS line_total
FROM orders
WHERE quantity * unit_price > 100
ORDER BY line_total DESC;

ORDER BY puede utilizar line_total. SQL estándar, PostgreSQL y MySQL no pueden utilizar ese nuevo alias en WHERE; repite allí la expresión. SQLite acepta un alias en WHERE como una extensión, pero esa forma fallará al trasladarla a PostgreSQL.

Un alias nuevo tampoco está disponible para otra expresión de la misma lista SELECT. Después de unit_price * 1.08 AS with_tax, escribir with_tax - unit_price AS tax falla si la tabla no tiene una columna with_tax. Escribe en su lugar unit_price * 1.08 - unit_price AS tax.

Diagnostica un resultado inesperado

SELECT first_name last_name FROM customers; es SQL válido. Muestra una columna de nombres con el alias last_name. Para recuperar ambas columnas, escribe SELECT first_name, last_name FROM customers;. Por tanto, una coma ausente puede producir un resultado engañoso sin generar un error.

Para comprobar rápidamente una expresión, no hace falta una tabla: SELECT 19.99 * 3 AS total; devuelve 59.97 en SQLite y PostgreSQL. Oracle anterior a la versión 23 exige FROM DUAL para esta consulta; la versión 23 y las posteriores también permiten SELECT sin FROM.

Puntos clave

  • Una columna calculada obtiene un valor para cada fila sin cambiar los datos almacenados.
  • Una función de una sola fila conserva las filas; una función de agregación combina valores de un grupo.
  • Utiliza comillas dobles para los nombres que las necesiten y comillas simples para los valores de texto.
  • ORDER BY puede utilizar un alias de salida; repite la expresión en WHERE para que funcione en distintas bases de datos.
  • Un alias nuevo no está disponible en otras expresiones de la misma lista SELECT.
  • Una coma ausente puede convertir el siguiente nombre de columna en un alias.

1.2 Realiza cálculos con operadores aritméticos y funciones numéricas

Las expresiones aritméticas transforman cantidades originales en importes, tasas y diferencias. Los operadores son +, -, *, / y %; el módulo da el resto de la división.

Controla el orden del cálculo

La multiplicación, la división y el módulo se realizan antes que la suma y la resta. Los operadores de igual prioridad se evalúan de izquierda a derecha. Así, 10 + 3 * 2 da 16, mientras que (10 + 3) * 2 da 26.

Para una cantidad de 3, un precio unitario de 12,50 y un porcentaje de descuento de 10:

quantity * unit_price * (1 - discount_pct / 100.0)

Primero, 10 / 100.0 da 0.1. Los paréntesis dan la fracción que se paga, 0.9. El importe bruto es 37.5, por lo que el importe neto es 33.75. Sin paréntesis, quantity * unit_price * 1 - discount_pct / 100.0 resta 0.1 de 37.5 y da 37.4.

Conserva la parte fraccionaria al dividir

En SQLite, PostgreSQL y SQL Server, dividir un entero por otro elimina la parte fraccionaria hacia cero: 7 / 2 da 3 y -7 / 2 da -3. MySQL y Oracle dan un resultado decimal para /. En SQLite y PostgreSQL, convierte un operando en decimal antes de dividir: 7 / 2.0, 7 * 1.0 / 2 o CAST(7 AS REAL) / 2 da 3.5. CAST(7 / 2 AS REAL) llega demasiado tarde y da 3.0.

Para una subida de 80 a 92, (92 - 80) * 100.0 / 80 da 15.0 por ciento. Dividir primero la diferencia entera por 80 elimina la parte fraccionaria. El módulo conserva lo que sobra: 135 / 60 da 2 horas y 135 % 60 da 15 minutos. En SQLite y PostgreSQL, -7 % 3 da -1; el resto sigue el signo del operando izquierdo. Oracle escribe MOD(17, 5) en lugar de %.

Un divisor cero genera un error en PostgreSQL y SQL Server; SQLite y MySQL devuelven NULL. amount / NULLIF(divisor, 0) hace que el caso de cero devuelva NULL en todos estos sistemas.

Redondea o elige un número entero

ROUND(x, n) redondea a n decimales. Una lámpara con un precio de 24,00 y un coste de 15,50 tiene un beneficio de 8.5. ROUND((price - cost) / price * 100, 1) da un margen de 35.4 por ciento. PostgreSQL admite un número de decimales negativo: ROUND(1234.5678, -2) da 1200; SQLite lo trata como cero y da 1235.0.

FunciónSignificadoEjemplo
ABSDistancia a ceroABS(-4.2) da 4.2
CEILMenor entero mayor o igual al valorCEIL(4.1) da 5
FLOORMayor entero menor o igual al valorFLOOR(-4.1) da -5
TRUNCElimina la parte fraccionaria hacia ceroTRUNC(42.8) da 42

PostgreSQL proporciona estas funciones. SQLite proporciona ABS; CEIL, FLOOR y TRUNC requieren una versión compilada con funciones matemáticas, disponibles desde la 3.35.

Ajusta la precisión a los datos

ROUND de SQLite y ROUND con numeric de PostgreSQL redondean los valores exactamente a mitad alejándose de cero: ROUND(-2.5) da -3. El redondeo de coma flotante de PostgreSQL suele resolver los empates con el entero par más cercano; su ROUND de dos argumentos requiere numeric, por lo que debes utilizar ROUND(CAST(x AS numeric), 2) para una columna de doble precisión.

Los números de coma flotante aproximan muchas fracciones decimales. SQLite puede hacer que 0.1 + 0.2 = 0.3 sea falso y que ROUND(2.675, 2) devuelva 2.67. Los literales decimales de PostgreSQL utilizan numeric exacto. Para importes monetarios exactos, utiliza NUMERIC/DECIMAL en PostgreSQL o céntimos expresados como enteros en SQLite. Declarar DECIMAL en SQLite no crea un almacenamiento decimal exacto. Conserva la precisión durante los cálculos y redondea para mostrar los resultados.

Puntos clave

  • Los paréntesis controlan qué cantidades se combinan antes de multiplicar o dividir.
  • Convierte un operando antes de la división entera; convertir el resultado no recupera los dígitos perdidos.
  • El módulo devuelve un resto, como los minutos que sobran después de contar las horas completas.
  • ROUND, FLOOR, CEIL y TRUNC toman decisiones distintas sobre un valor con parte fraccionaria.
  • El redondeo de coma flotante y las funciones numéricas disponibles dependen del tipo y de la base de datos.
  • Utiliza almacenamiento numérico exacto en PostgreSQL o céntimos expresados como enteros en SQLite para obtener importes exactos.
  • NULLIF puede hacer que un divisor cero produzca NULL en lugar de un error.

1.3 Convierte valores entre tipos de datos

El tipo de datos de un valor afecta a las operaciones aritméticas, las comparaciones y la ordenación. El número 42 es distinto del texto '42', aunque una cuadrícula de resultados los muestre de la misma manera.

Convierte un valor explícitamente

Los tipos habituales incluyen INTEGER para números enteros, NUMERIC o DECIMAL para decimales exactos en PostgreSQL, REAL o double precision para números aproximados, TEXT o VARCHAR para texto, y DATE, TIME, TIMESTAMP y BOOLEAN donde estén disponibles.

SELECT CAST('42' AS INTEGER) AS number_value,
       CAST(42 AS TEXT) AS text_value;

CAST(expression AS type) forma parte de SQL estándar. El primer resultado es un número; el segundo es texto. PostgreSQL también acepta '42'::integer. Convertir NULL sigue dando NULL.

Para la división decimal en SQLite, escribe CAST(quantity AS REAL) / 4; en PostgreSQL, escribe CAST(quantity AS NUMERIC) / 4. Una cantidad de 7 da 1.75. CAST(7 AS NUMERIC) / 2 de SQLite sigue dando 3: NUMERIC deja ese valor entero almacenado como un entero. REAL es el tipo adecuado para esta conversión en SQLite.

Comprende qué hace una conversión a entero
Entrada y conversiónSQLitePostgreSQL
CAST(3.9 AS INTEGER)34
CAST(-3.9 AS INTEGER)-3-4
CAST('abc' AS INTEGER)0Error

SQLite elimina la parte fraccionaria hacia cero. PostgreSQL redondea un valor numérico al entero más cercano. Utiliza primero ROUND, TRUNC, FLOOR o CEIL cuando importe la regla que se deba aplicar. PostgreSQL rechaza el texto que no sea un número válido. SQLite lee una parte numérica inicial: '12abc' se convierte en 12 y '12.5' se convierte en 12 al convertirlos a INTEGER. Por tanto, obtener cero tras una conversión en SQLite no demuestra que el texto original fuera un cero válido. TRY_CAST de SQL Server devuelve NULL si la conversión falla.

Distingue las cantidades de los identificadores

El texto se ordena carácter por carácter. Las cadenas '9', '10' y '100' se ordenan como '10', '100', '9'. Para ordenar cantidades realmente numéricas almacenadas como texto, utiliza ORDER BY CAST(code AS INTEGER) después de asegurarte de que sean números válidos.

Un código postal estadounidense ZIP como '02134' es un identificador. Convertirlo da 2134 y pierde el primer cero. Los números de teléfono también deben ser texto: sus dígitos identifican algo, en lugar de describir una cantidad que se pueda sumar o promediar.

Reconoce las conversiones automáticas

Tanto SQLite como PostgreSQL convierten el número en texto en 'Order #' || 42, produciendo 'Order #42'. Ambos también evalúan como número el literal entre comillas de '5' + 3. En PostgreSQL, ese literal tiene inicialmente un tipo sin determinar; una columna TEXT no tiene la misma flexibilidad. Sumar 3 a una columna TEXT falla, por lo que debes convertir la columna explícitamente.

SQLite asigna a las columnas una preferencia de tipo, llamada afinidad de tipo, y puede conservar valores de distintos tipos en una misma columna ordinaria. typeof(42), typeof(4.2), typeof('42') y typeof(NULL) devuelven 'integer', 'real', 'text' y 'null'. SQLite no tiene un tipo DATE específico: CAST('2026-03-14' AS DATE) da 2026. Utiliza date('2026-03-14') para sus funciones de fecha.

Oracle proporciona TO_NUMBER, TO_CHAR y TO_DATE. TO_CHAR y TO_DATE de PostgreSQL reciben patrones de formato como 'MM/DD/YYYY'. CONVERT de SQL Server utiliza un código numérico de estilo: CONVERT(date, '03/14/2026', 101) interpreta el formato de fecha estadounidense.

Puntos clave

  • CAST cambia explícitamente un valor al tipo solicitado; NULL sigue siendo NULL.
  • SQLite trunca las conversiones de números a enteros, mientras que PostgreSQL las redondea.
  • SQLite puede convertir texto numérico no válido en un número parcial o en cero.
  • Conserva los códigos postales estadounidenses ZIP y los números de teléfono como texto para preservar su identidad.
  • La ordenación de texto y la ordenación numérica pueden producir órdenes distintos.
2

Gestiona los valores ausentes con la lógica de NULL y COALESCE

Un valor ausente puede cambiar un cálculo y también las filas que conserva un filtro. Comprender NULL requiere seguir tanto el dato como la condición que lo utiliza. Distinguirás la ausencia de datos del cero y de la cadena vacía, seguirás TRUE, FALSE y UNKNOWN a través de una consulta y elegirás valores de sustitución que conserven el significado de un informe. COALESCE y NULLIF te permitirán rellenar valores ausentes o generarlos deliberadamente.

2.1 Predice cómo se comporta NULL en cálculos y condiciones

NULL indica un valor ausente o desconocido. Una celda vacía del resultado podría representar NULL, pero NULL no es un valor ordinario que puedas comparar con =.

Sigue una entrada ausente a través de una expresión

Cero es un número conocido. La cadena vacía, '', es una cadena conocida sin caracteres. El texto 'N/A' es una etiqueta registrada. NULL indica que no hay ningún valor disponible. Oracle trata la cadena vacía como NULL; SQLite y PostgreSQL los distinguen.

La mayoría de las operaciones aritméticas y funciones propagan una entrada ausente como NULL. Con un salario de 50 000 y una bonificación NULL, salary + bonus da NULL. El total es desconocido porque la bonificación es desconocida. UPPER(NULL), ROUND(NULL, 2) y 'Ana ' || NULL también devuelven NULL en SQLite y PostgreSQL.

Comprueba NULL directamente

bonus = NULL, bonus <> NULL e incluso NULL = NULL producen UNKNOWN. No se sabe si dos valores ausentes son iguales. Utiliza bonus IS NULL o bonus IS NOT NULL. Estas comprobaciones siempre devuelven TRUE o FALSE.

SQL tiene tres resultados posibles: TRUE, FALSE y UNKNOWN. SQLite muestra TRUE como 1, FALSE como 0 y UNKNOWN como NULL.

CondiciónResultadoMotivo
FALSE AND UNKNOWNFALSEUn requisito falso descarta AND
TRUE AND UNKNOWNUNKNOWNEl segundo requisito sigue sin resolverse
TRUE OR UNKNOWNTRUEUna alternativa verdadera determina OR
FALSE OR UNKNOWNUNKNOWNLa alternativa restante sigue sin resolverse
NOT UNKNOWNUNKNOWNNegar un valor desconocido no lo resuelve
Comprende qué filas conserva WHERE

WHERE solo conserva TRUE. Tanto FALSE como UNKNOWN excluyen la fila. Para bonificaciones de 1000, 0, NULL, 2500 y NULL, WHERE bonus < 1000 solo conserva el cero. WHERE bonus >= 1000 conserva 1000 y 2500. Estos filtros abarcan tres filas, no cinco. WHERE NOT (bonus < 1000) también conserva únicamente las dos bonificaciones conocidas de al menos 1000.

El mismo problema afecta a <>. Con las ciudades Boston, Denver, NULL, Boston y Austin, WHERE city <> 'Boston' conserva Denver y Austin. Incluye explícitamente la ciudad desconocida:

WHERE city <> 'Boston' OR city IS NULL

Esto conserva tres filas. NOT no recupera automáticamente los valores ausentes.

Presta atención a las listas y las comparaciones

3 IN (1, 2, NULL) es UNKNOWN: el elemento ausente podría ser 3. Para x NOT IN (1, 2, NULL), un valor coincidente no cumple NOT IN y cualquier valor sin coincidencia da UNKNOWN. En una cláusula WHERE, esta lista fija no conserva ninguna fila. Elimina los NULL no deseados de una lista de exclusión antes de utilizarla.

Para una igualdad que trate dos NULL como iguales, utiliza a IS NOT DISTINCT FROM b. Su opuesto, a IS DISTINCT FROM b, es TRUE cuando un valor es NULL y el otro no; dos NULL no son distintos. PostgreSQL y SQLite desde la versión 3.39 admiten estas formas. SQLite también tiene IS e IS NOT; MySQL escribe la igualdad segura frente a NULL como <=>.

La ordenación predeterminada de NULL varía: SQLite coloca NULL al principio en orden ascendente; PostgreSQL lo coloca al final. Indica su posición cuando importe: ORDER BY bonus DESC NULLS LAST coloca las bonificaciones conocidas en orden descendente y las ausentes al final.

Puntos clave

  • NULL significa ausente o desconocido, no cero ni cadena vacía.
  • Las comparaciones con NULL producen UNKNOWN; comprueba la ausencia de datos con IS NULL.
  • WHERE solo conserva TRUE, por lo que NOT y <> no recuperan las filas con resultados desconocidos.
  • AND y OR solo pueden resolver un resultado desconocido cuando la otra condición determina el resultado.
  • Un NULL en una lista NOT IN impide que esa condición sea TRUE.
  • IS NOT DISTINCT FROM trata dos NULL como iguales.
  • NULLS FIRST o NULLS LAST hace explícita la posición de NULL en la ordenación.

2.2 Sustituye y genera valores ausentes con COALESCE y NULLIF

Los valores ausentes a veces necesitan un valor de sustitución y otras veces deben seguir ausentes. La elección forma parte del significado del informe. COALESCE rellena una ausencia; NULLIF convierte un valor marcador coincidente en una ausencia.

Elige el primer valor disponible

COALESCE(a, b, ...) comprueba de izquierda a derecha y devuelve el primer argumento que no sea NULL. Devuelve NULL si todos los argumentos son NULL.

SELECT COALESCE(mobile_phone, home_phone, 'no phone') AS contact
FROM customers;

Sin número de móvil y con el teléfono fijo '555-0100', el contacto es '555-0100'. Si no se ha registrado ninguno de los dos números, es 'no phone'. Un cero conocido o una cadena vacía cuentan como disponibles: COALESCE omite NULL, no los valores que parecen vacíos o falsos.

Para la remuneración, salary + COALESCE(bonus, 0) da 50 000 cuando el salario es 50 000 y la bonificación es NULL. Esto es adecuado cuando una bonificación ausente significa que no se pagó ninguna. La ausencia de una valoración de producto no significa una valoración de cero; sustituirla inventaría una mala valoración. Deja ese número ausente o crea una etiqueta de texto para mostrarlo.

Mantén compatibles los tipos de los valores de sustitución

PostgreSQL no puede combinar un rating entero con el texto 'not rated' en un resultado numérico. Convierte primero las valoraciones conocidas en texto:

COALESCE(CAST(rating AS TEXT), 'not rated')

Una valoración de 4 se muestra como el texto '4'; un NULL se muestra como 'not rated'. SQLite acepta argumentos numéricos y de texto mezclados, pero entonces la salida puede contener distintos tipos. Deja claro el tipo de resultado deseado al trasladar una consulta entre bases de datos.

COALESCE forma parte de SQL estándar y acepta dos o más argumentos. Las alternativas habituales con dos argumentos son IFNULL en SQLite y MySQL, ISNULL en SQL Server y NVL en Oracle.

Convierte un valor marcador en NULL

NULLIF(a, b) devuelve NULL si los argumentos son iguales; en caso contrario, devuelve el primer argumento. NULLIF(0, 0) es NULL, mientras que NULLIF(5, 0) es 5.

Una expresión útil para una tasa es:

orders * 100.0 / NULLIF(visits, 0) AS conversion_pct

Con 12 pedidos y 300 visitas, el divisor sigue siendo 300 y la tasa es 4.0. Con cero visitas, el divisor se convierte en NULL y la tasa pasa a ser NULL. PostgreSQL evita un error de división por cero y el resultado indica correctamente una tasa no definida. Sustituir esa tasa por cero afirmaría algo distinto.

Limpia las ausencias antes de proporcionar una etiqueta
COALESCE(NULLIF(phone, ''), 'unknown')

El NULLIF interno convierte una cadena vacía en NULL. El COALESCE externo etiqueta después tanto un NULL original como una cadena vacía con 'unknown'. Un número de teléfono registrado pasa sin cambios.

Para un segundo nombre opcional, incluye su espacio final dentro de la expresión de sustitución:

first_name || ' ' || COALESCE(middle_name || ' ', '') || last_name

Un segundo nombre NULL no aporta nada, y produce 'Ana Lopez'. Un segundo nombre 'Maria' aporta 'Maria ', y produce 'Ana Maria Lopez'.

Estas expresiones solo cambian el resultado de la consulta. Dejan los valores originales almacenados en la tabla. Un filtro como WHERE COALESCE(bonus, 0) = 0 reúne las bonificaciones conocidas de cero y las ausentes, así que utilízalo cuando esos sean los dos grupos que quieras.

Puntos clave

  • COALESCE devuelve el primer argumento que no sea NULL, incluidos un cero conocido o una cadena vacía.
  • Un valor de sustitución debe expresar el significado de los datos ausentes y tener un tipo compatible.
  • NULLIF devuelve NULL si hay igualdad y, en caso contrario, devuelve su primer argumento.
  • Utiliza NULLIF alrededor de un divisor para que un denominador cero produzca NULL.
  • Limpia un valor marcador con NULLIF antes de aplicar un valor de sustitución para mostrarlo con COALESCE.
3

Limpia, combina y descompón texto con funciones de cadenas

El texto de una tabla a menudo necesita una forma utilizable: un nombre completo, una dirección de correo electrónico uniforme o una parte de un código. SQL puede concatenar y limpiar cadenas, contar sus caracteres y extraer la parte anterior o posterior a un separador. Seguirás las posiciones de los caracteres en cada paso y comprobarás cómo afectan al resultado los espacios, las mayúsculas y minúsculas y NULL. SQLite y PostgreSQL comparten muchas funciones, pero difieren en varios nombres y comportamientos.

3.1 Concatena y limpia valores de texto

SQL trata un valor de texto como una cadena de caracteres. Las funciones de texto pueden construir un nombre completo o limpiar una dirección de correo electrónico para compararla. Sus resultados aparecen en la consulta; el texto almacenado permanece intacto.

Escribe y concatena texto

Los literales de texto utilizan comillas simples. Para incluir un apóstrofo, duplícalo: 'O''Brien' representa «O'Brien». Un par de comillas simples, '', es una cadena vacía.

SELECT first_name || ' ' || last_name AS full_name
FROM customers;

El operador de concatenación || une los fragmentos exactamente como están escritos. Con 'Ana' y 'Lopez', el resultado es 'Ana Lopez'. El literal del medio aporta el espacio; la concatenación no lo inserta automáticamente.

SQLite, PostgreSQL y Oracle utilizan ||. En el modo predeterminado de MySQL, || significa OR, así que utiliza CONCAT allí. SQL Server utiliza + y también admite || desde 2025. Para concatenar un identificador numérico de pedido, SQLite y PostgreSQL lo convierten en texto en 'Order #' || order_id. Con + de SQL Server, convierte primero el número: 'Order #' + CAST(order_id AS VARCHAR(10)).

Elige cómo concatenar una parte ausente

En SQLite y PostgreSQL, un operando NULL hace que el resultado de || sea NULL. Oracle trata esa parte ausente como una cadena vacía. CONCAT también varía según la base de datos:

Base de datosCONCAT('Ana', NULL, 'Lopez')
PostgreSQL, SQL Server, SQLite desde la versión 3.44'AnaLopez'
MySQLNULL

CONCAT de Oracle recibe exactamente dos argumentos. CONCAT_WS(' ', first_name, middle_name, last_name) coloca espacios entre las partes que no son NULL, por lo que un segundo nombre ausente da 'Ana Lopez'. SQLite añadió CONCAT y CONCAT_WS en la versión 3.44. Omitir NULL sigue sin eliminar una cadena vacía.

Cambia entre mayúsculas y minúsculas y recorta los extremos

UPPER('boston') da 'BOSTON'; LOWER produce minúsculas. INITCAP('ana LOPEZ') de PostgreSQL da 'Ana Lopez'. SQLite no tiene INITCAP, y su conversión incorporada entre mayúsculas y minúsculas solo cambia A–Z: UPPER('é') sigue siendo 'é' sin la extensión ICU. La conversión de PostgreSQL sigue su configuración regional.

TRIM elimina espacios de ambos extremos; LTRIM los elimina solo al principio y RTRIM solo al final. TRIM(' New York ') da 'New York', conservando los dos espacios interiores. Para eliminar x de ambos extremos, SQLite escribe TRIM('xxBostonxx', 'x'); PostgreSQL escribe TRIM(BOTH 'x' FROM 'xxBostonxx').

Sustituye caracteres y anida los pasos de limpieza

REPLACE('555-0100', '-', '') da '5550100'. Sustituye cada aparición exacta. Las mayúsculas y minúsculas importan: sustituir 'st' en 'Main St' no cambia nada porque 'St' tiene una S mayúscula.

SELECT LOWER(TRIM(email)) AS email_clean
FROM customers;

Para ' Ana@Example.COM ', TRIM produce primero 'Ana@Example.COM' y después LOWER produce 'ana@example.com'. Anidar significa que la función más interna proporciona la entrada de la siguiente.

La igualdad ordinaria de texto distingue mayúsculas y minúsculas de forma predeterminada en SQLite y PostgreSQL. WHERE LOWER(TRIM(email)) = 'ana@example.com' puede encontrar coincidencias con entradas que tengan distintas mayúsculas y espacios en los extremos. La intercalación predeterminada de MySQL ignora las mayúsculas y minúsculas, y LIKE de SQLite ignora esa distinción en A–Z aunque su comparación predeterminada con = no lo haga.

Puntos clave

  • Utiliza comillas simples para el texto y duplica un apóstrofo dentro de un literal.
  • La concatenación une fragmentos exactos; incluye los separadores explícitamente.
  • El comportamiento de NULL varía entre ||, CONCAT y los dialectos de las bases de datos.
  • TRIM elimina espacios de los extremos, mientras que REPLACE cambia los caracteres coincidentes en todo el texto.
  • Las funciones anidadas se ejecutan de dentro hacia fuera.
  • La conversión entre mayúsculas y minúsculas y la búsqueda que las distingue dependen de la base de datos y de la configuración regional.

3.2 Mide y extrae partes del texto

Las funciones de texto localizan y extraen fragmentos según la posición de sus caracteres. SQL empieza a contar las posiciones en 1, por lo que el primer carácter ocupa la posición 1. Una posición encontrada y un número de caracteres son entradas distintas.

Mide y recorta una cadena

LENGTH('Boston') da 6. Los espacios cuentan: LENGTH(' Bo ') da 4. Una cadena vacía tiene longitud 0; LENGTH(NULL) da NULL. LENGTH de MySQL cuenta bytes, así que utiliza CHAR_LENGTH para contar caracteres en ese sistema. SQL Server utiliza LEN, que ignora los espacios finales.

SELECT SUBSTR('Boston', 1, 3) AS beginning,
       SUBSTR('Boston', 4) AS ending;

Los resultados son 'Bos' y 'ton'. La primera llamada toma tres caracteres a partir de la posición 1. La segunda omite el número de caracteres y toma todo desde la posición 4 en adelante. PostgreSQL también escribe SUBSTRING('Boston' FROM 4 FOR 3). SQLite acepta el nombre SUBSTRING desde la versión 3.34. SQL Server utiliza SUBSTRING(text, start, count); el número de caracteres es obligatorio hasta 2022 y opcional desde 2025.

SQLite puede contar desde la derecha: SUBSTR('Boston', -3) da 'ton'. Las posiciones iniciales negativas de PostgreSQL no cuentan hacia atrás desde el final. Utiliza allí RIGHT('Boston', 3); LEFT toma caracteres del principio. SQLite no tiene LEFT ni RIGHT.

Encuentra el punto de separación

INSTR(text, search) de SQLite devuelve la posición de la primera coincidencia. PostgreSQL utiliza STRPOS o POSITION(search IN text). Estas funciones devuelven 0 cuando no encuentran ninguna coincidencia. La búsqueda distingue mayúsculas y minúsculas: INSTR('Ana', 'a') da 3.

En 'ana@example.com', el @ está en la posición 4. El nombre de usuario termina justo antes; el dominio empieza justo después:

SUBSTR(email, 1, INSTR(email, '@') - 1) AS user_name,
SUBSTR(email, INSTR(email, '@') + 1) AS domain

La primera expresión se convierte en SUBSTR(email, 1, 3) y produce 'ana'. La segunda empieza en 5 y produce 'example.com'. Omitir - 1 incluye @ en el nombre de usuario. Omitir + 1 lo incluye al principio del dominio. En PostgreSQL, sustituye INSTR por STRPOS o utiliza SPLIT_PART(email, '@', 2) para el dominio.

Gestiona la ausencia de un separador

Para 'anaexample.com', INSTR devuelve 0. La fórmula del dominio empieza en 1 y devuelve toda la cadena de forma engañosa. La fórmula del nombre de usuario en SQLite da una cadena vacía; PostgreSQL rechaza su longitud de subcadena negativa. Protege la extracción:

CASE
  WHEN INSTR(email, '@') > 0
  THEN SUBSTR(email, INSTR(email, '@') + 1)
END

Esto devuelve NULL cuando falta el separador. La comprobación busca un separador; no verifica todas las reglas de una dirección de correo electrónico válida.

Crea etiquetas breves y códigos de anchura fija

SUBSTR(first_name, 1, 1) || '. ' || last_name da 'A. Lopez' para Ana Lopez. WHERE LENGTH(zip_code) <> 5 encuentra cadenas de códigos postales estadounidenses ZIP registradas con una longitud incorrecta; las longitudes NULL producen UNKNOWN y se excluyen.

LPAD('42', 5, '0') de PostgreSQL da '00042'; RPAD rellena por la derecha. SQLite puede construir ese código con SUBSTR('00000' || 42, -5). Conservar solo cinco caracteres también recorta un valor más largo, por lo que esta expresión de anchura fija necesita un código que quepa.

Puntos clave

  • Las posiciones de las cadenas SQL empiezan en 1; LENGTH incluye los espacios.
  • SUBSTR recibe una posición inicial y un número opcional de caracteres.
  • INSTR, STRPOS y POSITION devuelven 0 cuando no hay coincidencia.
  • Utiliza la posición menos 1 antes de un separador y la posición más 1 después de él.
  • Comprueba si falta el separador antes de extraer un fragmento.
  • La extracción desde el final y el relleno tienen nombres distintos en SQLite y PostgreSQL.
4

Trabaja con fechas y horas

El trabajo con fechas empieza por distinguir claramente entre un día del calendario, una hora y una marca de fecha y hora. A partir de ahí, SQL puede crear etiquetas de año y mes, calcular plazos, medir el tiempo transcurrido y filtrar un período completo. Mantendrás separados los valores de fecha del texto para mostrarlos, tendrás en cuenta los finales de mes y los cumpleaños, y compararás las expresiones de SQLite y PostgreSQL que realizan la misma tarea. Los casos límite hacen fiables estos cálculos.

4.1 Escribe, almacena y lee valores de fecha y hora

Es más fácil calcular con una fecha cuando su almacenamiento y su escritura son claros. El texto '03/04/2026' podría significar 4 de marzo o 3 de abril. Una fecha ISO, '2026-03-14', coloca el año, el mes y el día en un orden inequívoco.

Relaciona el valor con su tipo

PostgreSQL tiene DATE para un día del calendario, TIME para una hora del día y TIMESTAMP para una fecha y hora. Su TIMESTAMP WITH TIME ZONE, también llamado timestamptz, almacena un instante en UTC y lo muestra en la zona horaria de la sesión. Un TIMESTAMP simple no incorpora ese significado de zona horaria.

SQLite almacena las fechas y horas como texto ISO o como números, no en tipos específicos de fecha y hora. Las formas numéricas incluyen números de día juliano y tiempo Unix. Las funciones de fecha interpretan estos valores y devuelven una fecha, una hora o una medida numérica.

Utiliza texto ISO de anchura fija como '2026-03-14', incluidos los ceros iniciales. Añade una hora con el formato de 24 horas: '2026-03-14 09:30:00'. El literal con tipo de PostgreSQL DATE '2026-03-14' crea explícitamente una fecha.

Conserva el orden cronológico

El texto ISO de anchura fija se compara en orden cronológico porque empieza por el componente mayor. '2026-03-14' va antes de '2026-11-02'. El texto de presentación estadounidense no tiene esta propiedad: como cadenas, '11/02/2025' se ordena después de '03/14/2026' aunque su fecha sea anterior.

El analizador de SQLite necesita un formato compatible. date('2026-3-14') devuelve NULL porque el mes no tiene dos dígitos. También puede normalizar una fecha imposible: date('2026-02-30') devuelve '2026-03-02'. Un resultado que no sea NULL no demuestra por sí solo que la entrada fuera un día válido del calendario. PostgreSQL rechaza DATE '2026-02-30'.

Lee texto en otro formato

PostgreSQL y Oracle utilizan TO_DATE('03/14/2026', 'MM/DD/YYYY') para leer un formato estadounidense. PostgreSQL también lee texto ISO con CAST('2026-03-14' AS DATE) o '2026-03-14'::date.

SQLite no tiene un analizador TO_DATE. Para texto de formato fijo MM/DD/YYYY en d, reconstruye el texto ISO:

SUBSTR(d, 7, 4) || '-' ||
SUBSTR(d, 1, 2) || '-' || SUBSTR(d, 4, 2)

Los fragmentos son el año '2026', el mes '03' y el día '14'. El resultado es '2026-03-14', que las funciones de fecha de SQLite pueden leer. Las posiciones dependen de que la entrada utilice realmente ese formato fijo.

Obtén la fecha y la hora actuales

CURRENT_DATE y CURRENT_TIMESTAMP funcionan en SQLite y PostgreSQL. SQLite devuelve texto UTC; date('now', 'localtime') da la fecha local. Cerca de medianoche, la fecha UTC y la fecha local del calendario pueden diferir.

PostgreSQL utiliza la zona horaria de la sesión. CURRENT_TIMESTAMP y NOW() reflejan el inicio de la transacción actual, por lo que esperar dentro de esa transacción no hace avanzar su valor. MySQL ofrece NOW() y CURDATE(); SQL Server tiene GETDATE() y SYSDATETIME(); Oracle tiene SYSDATE, que incluye una hora, y CURRENT_DATE.

Para comprobar un cálculo de vencimiento, utiliza primero una referencia fija como DATE '2026-10-21' en PostgreSQL o '2026-10-21' en SQLite. Así podrás comparar el resultado con un calendario sin que la respuesta cambie al día siguiente.

Puntos clave

  • DATE es un día del calendario; TIMESTAMP añade una hora del día.
  • Utiliza YYYY-MM-DD de anchura fija para que el texto de fecha sea inequívoco y funcione en distintas bases de datos.
  • El texto ISO se ordena cronológicamente cuando su formato y su referencia horaria son uniformes.
  • Un resultado de fecha de SQLite puede normalizar una entrada imposible en lugar de rechazarla.
  • Las funciones de fecha actual utilizan distintas reglas de zona horaria y transacción.

4.2 Extrae partes de las fechas y dales formato

Extrae un componente de una fecha cuando necesites un año o un día de la semana para calcular. Da formato a una fecha cuando necesites texto para el lector. Estas operaciones pueden producir tipos distintos aunque los caracteres mostrados parezcan iguales.

Extrae un año, un mes o un día de la semana

PostgreSQL utiliza la forma estándar EXTRACT(part FROM value). Para DATE '2026-03-14', extraer YEAR da 2026 y MONTH da 3, ambos como números. MySQL y Oracle también admiten EXTRACT.

SQLite utiliza strftime(format, value), que devuelve texto:

Patrón de SQLiteResultado para '2026-03-14'
'%Y''2026'
'%m''03'
'%d''14'
'%w''6'

%w de SQLite y DOW de PostgreSQL numeran desde el domingo como 0 hasta el sábado como 6. El 14 de marzo de 2026 es sábado. En cambio, ISODOW de PostgreSQL numera desde el lunes como 1 hasta el domingo como 7. Un filtro de fin de semana en SQLite es WHERE strftime('%w', order_date) IN ('0', '6').

Compara los tipos adecuados

strftime('%m', order_date) = 3 es falso para una fecha de marzo en SQLite: la función devuelve el texto '03', no el número 3. Compáralo con = '03' o conviértelo primero:

CAST(strftime('%m', order_date) AS INTEGER) = 3

Esto también resulta útil en la expresión del trimestre (CAST(strftime('%m', d) AS INTEGER) + 2) / 3. La división entera da el trimestre 1 para marzo y el trimestre 4 para noviembre. PostgreSQL dispone directamente de EXTRACT(QUARTER FROM d).

Identifica un mes como un período completo

strftime('%Y-%m', order_date) crea una etiqueta de SQLite como '2026-03'. date(order_date, 'start of month') crea '2026-03-01'. PostgreSQL puede utilizar TO_CHAR(order_date, 'YYYY-MM') para una etiqueta o DATE_TRUNC('month', order_date) para el primer instante de ese mes.

Conserva el año en una etiqueta de período. Un valor de mes de 3 por sí solo combinaría marzo de distintos años. El valor del primer día del mes puede seguir utilizándose para calcular y ordenar, mientras otra expresión proporciona el texto que se muestra.

Da formato en la etapa de salida

En PostgreSQL, TO_CHAR(DATE '2026-03-14', 'MM/DD/YYYY') da '03/14/2026', y el patrón 'Mon DD, YYYY' da 'Mar 14, 2026'. Oracle también utiliza estos patrones. El formato estadounidense de SQLite es strftime('%m/%d/%Y', '2026-03-14').

Las letras de los patrones son propias de cada base de datos. En PostgreSQL, MM significa mes y MI significa minuto. En SQLite, %m significa mes y %M significa minuto; cambiar esa mayúscula cambia la información solicitada.

SELECT TO_CHAR(order_date, 'MM/DD/YYYY') AS order_day
FROM orders
ORDER BY order_date;

Aquí PostgreSQL muestra texto legible, pero ordena las fechas reales. Ordenar por order_day ordenaría las cadenas mostradas empezando por el mes y podría colocar fuera de orden fechas de distintos años.

Puntos clave

  • EXTRACT de PostgreSQL devuelve componentes numéricos; strftime de SQLite devuelve texto.
  • Compara un mes de SQLite con cero inicial con texto, o conviértelo en un número.
  • La numeración de los días de la semana depende de la convención solicitada.
  • Conserva el año en las etiquetas de año y mes y da formato solo para mostrar los resultados.

4.3 Realiza cálculos con fechas y filtra por intervalos de fechas

Los cálculos de calendario deben tener en cuenta la duración de los meses, los componentes horarios y el tipo de respuesta necesario. Un número de días, un mes del calendario y un año cumplido de edad son medidas distintas.

Añade días y meses del calendario

PostgreSQL escribe DATE '2026-03-14' + 30; SQLite escribe date('2026-03-14', '+30 days'). Ambos llegan al 13 de abril: 17 días completan marzo y otros 13 llegan al 13 de abril. En cambio, la expresión directa de SQLite '2026-03-14' + 30 da 2056, porque la operación aritmética interpreta el año inicial como un número.

Los finales de mes necesitan una regla explícita. DATE '2026-01-31' + INTERVAL '1 month' de PostgreSQL da el 28 de febrero a medianoche, utilizando el último día disponible. date('2026-01-31', '+1 month') de SQLite desplaza los días sobrantes a marzo y da '2026-03-03'. Desde SQLite 3.46, añade 'floor' después del desplazamiento para elegir '2026-02-28'. ADD_MONTHS de Oracle también se desplaza al último día del mes más corto.

Mide el tiempo transcurrido

La resta de DATE en PostgreSQL devuelve días enteros: DATE '2026-04-13' - DATE '2026-03-14' da 30. SQLite resta valores numéricos de día: julianday('2026-04-13') - julianday('2026-03-14') da 30.0. SQL Server utiliza DATEDIFF(day, start, end); MySQL utiliza DATEDIFF(end, start).

Para marcas de fecha y hora del 14 de marzo desde las 09:30 hasta las 18:00, la resta de PostgreSQL da un intervalo de 08:30:00; EXTRACT(EPOCH FROM interval) / 3600 lo expresa como 8,5 horas. Desde SQLite 3.38 se puede escribir:

(unixepoch('2026-03-14 18:00') -
 unixepoch('2026-03-14 09:30')) / 3600.0

Esto da 8.5. Una diferencia de días julianos multiplicada por 24 puede dar 8.49999999627471 por la aproximación de coma flotante; redondea para mostrarla. Una duración con parte fraccionaria entre marcas de fecha y hora no debe convertirse a INTEGER antes de calcular la unidad deseada.

Cuenta los cumpleaños cumplidos

Una persona nacida el 2 de noviembre de 1990 tiene 35 años el 21 de octubre de 2026. Los números de año difieren en 36, pero el cumpleaños aún no ha llegado. PostgreSQL utiliza EXTRACT(YEAR FROM AGE(DATE '2026-10-21', DATE '1990-11-02')), que da 35.

SQLite resta uno si el cumpleaños de este año aún está por llegar:

strftime('%Y', '2026-10-21') - strftime('%Y', birth_date)
- (strftime('%m-%d', '2026-10-21') < strftime('%m-%d', birth_date))

La comparación produce 1 cuando el cumpleaños aún no ha llegado y 0 en caso contrario. Dividir los días transcurridos por 365 no es fiable: el 1 de noviembre de 2026, esta persona ha vivido 13 148 días, que divididos por 365 dan 36,02, aunque cumple 36 años mañana. DATEDIFF de SQL Server cuenta límites: pasar del 31 de diciembre al 1 de enero cuenta como un cambio de año, no como un año cumplido de edad.

Incluye todas las marcas de fecha y hora de un período

BETWEEN incluye ambos extremos. Para columnas DATE, del 1 al 31 de marzo abarca marzo. Para marcas de fecha y hora, un límite superior de '2026-03-31' significa medianoche al inicio del último día y deja fuera el resto de ese día.

WHERE ordered_at >= '2026-03-01'
  AND ordered_at < '2026-04-01'

Este intervalo semiabierto incluye el inicio y excluye el inicio del período siguiente, abarcando todas las horas de marzo sin elegir una última fracción de segundo.

Las fechas vencidas cumplen due_date < CURRENT_DATE. El límite inferior para los últimos 30 días en PostgreSQL es CURRENT_DATE - 30; en SQLite es date('now', '-30 days'). Los días hasta un vencimiento son due_date - CURRENT_DATE para valores DATE de PostgreSQL y julianday(due_date) - julianday(date('now')) en SQLite.

Puntos clave

  • Utiliza funciones de cálculo con fechas o fechas con tipo, en lugar de operaciones aritméticas sobre texto de fecha en SQLite.
  • Decide cómo debe tratar la suma de un mes un día que no exista en el mes siguiente.
  • Las diferencias de DATE cuentan días; las diferencias entre marcas de fecha y hora pueden incluir fracciones.
  • La edad cuenta cumpleaños cumplidos, no días transcurridos divididos por 365.
  • Un intervalo semiabierto de marcas de fecha y hora incluye el inicio del período y excluye el siguiente inicio.
  • Utiliza un valor actual que solo contenga la fecha para calcular plazos en días enteros.
5

Clasifica filas con expresiones CASE

Un informe suele necesitar una regla que convierta datos en una etiqueta o un cargo: un pedido pequeño, un envío pendiente o una posición de prioridad. CASE expresa esa elección dentro de una consulta. Seguirás qué condición se aplica, situarás los valores límite exactos y los ausentes en la categoría adecuada y convertirás códigos en etiquetas con CASE simple. El informe final combina la clasificación con operaciones aritméticas, texto, fechas y valores de sustitución, comprobando cada salida con filas conocidas.

5.1 Clasifica filas en categorías con CASE de búsqueda

Una expresión CASE elige un resultado para cada fila. Puedes utilizarla para etiquetar un intervalo de precios, calcular un cargo o marcar un registro que requiera atención.

Lee la forma de búsqueda
CASE
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END AS size_band

Cada WHEN proporciona una condición y THEN proporciona el valor que se devuelve si esa condición es TRUE. La base de datos comprueba de arriba abajo y toma la primera condición verdadera. END cierra la expresión; después puede aparecer un alias. Si ninguna condición es TRUE y no hay ELSE, el resultado es NULL.

Un total de 35 cumple la primera condición y pasa a ser 'small'. Un total de 50 no cumple la primera, pero sí la segunda, y pasa a ser 'medium'. Lo mismo ocurre con 199,99. Un total de 200 llega a ELSE y pasa a ser 'large'.

Ajusta el orden y los límites a la regla

La segunda rama no necesita total >= 50: un valor inferior a 50 ya ha obtenido su resultado en la primera rama. Los umbrales < en orden ascendente funcionan porque las ramas anteriores descartan los valores menores. Los umbrales >= en orden descendente pueden funcionar por la misma razón.

Colocar WHEN total < 200 primero hace que nunca se alcance una rama posterior < 50. Un total de 35 ya cumple < 200, por lo que se detiene ahí. CASE no elige la condición más específica ni comprueba qué etiqueta parece mejor.

Compara la regla de negocio con cada extremo. < 50 coloca exactamente 50 en la categoría mediana; <= 50 lo coloca en la pequeña. Comprueba 49,99, 50, 199,99 y 200 para ver ambos lados y los límites. Si las condiciones se escriben como intervalos explícitos, ajusta sus extremos para que no haya huecos ni solapamientos no deseados.

Gestiona NULL antes de los intervalos ordinarios

Un total NULL hace que ambas comparaciones sean UNKNOWN. Por tanto, en la primera expresión llega a ELSE y pasa a ser 'large', lo que resulta engañoso. Detecta primero la ausencia:

CASE
  WHEN total IS NULL THEN 'unknown'
  WHEN total < 50 THEN 'small'
  WHEN total < 200 THEN 'medium'
  ELSE 'large'
END

ELSE significa «ninguna condición fue verdadera», por lo que puede recoger entradas ausentes además de valores conocidos fuera de los intervalos comprobados.

Devuelve valores de un tipo uniforme

PostgreSQL necesita tipos THEN y ELSE compatibles. CASE WHEN quantity > 0 THEN unit_price ELSE 'n/a' END falla si unit_price es numérico, porque 'n/a' no se puede convertir en un número. Utiliza NULL para un resultado numérico no disponible o convierte el precio en texto si toda la salida es una etiqueta para mostrar. SQLite permite tipos de resultado mezclados, lo que puede complicar los cálculos posteriores.

Una condición puede combinar columnas:

CASE
  WHEN country = 'US' AND subtotal >= 100 THEN 0
  ELSE 7.99
END AS shipping_fee

El cargo devuelto puede aparecer dentro de subtotal + CASE ... END AS amount_due. Un CASE es una expresión de valor, no una orden que modifica varias columnas; cada columna del resultado necesita su propia expresión.

CASE también puede proteger una división por fila: CASE WHEN visits = 0 THEN NULL ELSE orders * 100.0 / visits END. Una fila con cero selecciona la rama NULL. orders * 100.0 / NULLIF(visits, 0) expresa de forma más breve la misma regla para una tasa ausente.

Puntos clave

  • CASE devuelve el valor de la primera condición que sea TRUE.
  • Ordena las condiciones de intervalos solapados para que una comprobación amplia no oculte otra más restringida.
  • Elige < o <= para colocar un límite exacto en la categoría prevista.
  • Comprueba NULL explícitamente antes de un intervalo cuando ELSE no deba asignarle una etiqueta.
  • Mantén compatibles los tipos de resultado y utiliza CASE donde pueda aparecer una expresión de valor.

5.2 Utiliza CASE simple y aplica CASE en distintas partes de una consulta

La forma CASE simple convierte un valor en otro. CASE de búsqueda comprueba condiciones; CASE simple compara la misma expresión con una serie de valores.

Convierte códigos en etiquetas con CASE simple
CASE status
  WHEN 'S' THEN 'Shipped'
  WHEN 'P' THEN 'Pending'
  WHEN 'C' THEN 'Canceled'
  ELSE 'Other'
END AS status_label

Las comprobaciones implícitas son status = 'S', después status = 'P' y después status = 'C'. Un estado fuera de estos códigos recibe 'Other'. La forma de búsqueda puede escribir explícitamente las mismas comprobaciones de igualdad. Elige CASE de búsqueda para intervalos, patrones LIKE, comprobaciones de NULL o condiciones que abarquen varias columnas.

CASE region WHEN NULL THEN 'missing' ELSE region END no puede detectar una región NULL. Su comparación implícita region = NULL es UNKNOWN, por lo que la fila llega a ELSE y sigue siendo NULL. Escribe CASE WHEN region IS NULL THEN 'missing' ELSE region END.

Asigna una posición de ordenación personalizada

El orden alfabético de las prioridades es high, low, medium. Para ordenar por urgencia, convierte las etiquetas en números:

SELECT ticket_id, priority
FROM tickets
ORDER BY CASE priority
           WHEN 'high' THEN 1
           WHEN 'medium' THEN 2
           WHEN 'low' THEN 3
           ELSE 4
         END;

Ahora el orden ascendente coloca high antes de medium y después low, con los demás valores o los ausentes al final. CASE es una expresión de ordenación; no tiene que ser una columna mostrada. Utilizar DESC invertiría la clasificación numérica.

Crea un indicador numérico
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END AS is_discounted

Un porcentaje positivo recibe 1; un cero conocido recibe 0. Un porcentaje NULL también recibe 0 porque > 0 es UNKNOWN y ELSE lo recoge. Por tanto, este indicador significa «hay un descuento positivo registrado». No conserva la distinción entre ausencia de descuento y descuento desconocido. Si necesitas esa distinción, añade una rama IS NULL con su propio resultado.

Los indicadores se pueden seleccionar, ordenar, filtrar o incluir en operaciones aritméticas. En una cláusula WHERE que deba funcionar en distintas bases de datos, repite la expresión o utiliza su condición original en lugar de referirte a un alias de salida recién definido.

Reconoce las funciones condicionales relacionadas

COALESCE(bonus, 0) es una forma abreviada de CASE WHEN bonus IS NOT NULL THEN bonus ELSE 0 END. NULLIF(a, b) corresponde a CASE WHEN a = b THEN NULL ELSE a END. Sus nombres comunican directamente estos usos habituales.

SQLite desde la versión 3.32 y SQL Server tienen IIF(condition, true_value, false_value); MySQL tiene IF. DECODE de Oracle convierte coincidencias de igualdad, por ejemplo, DECODE(status, 'S', 'Shipped', 'P', 'Pending', 'Other'). DECODE trata dos NULL como iguales, a diferencia de las comparaciones de igualdad de CASE simple. CASE estándar funciona en todos estos sistemas.

Un CASE puede contener otro CASE, pero las condiciones combinadas suelen hacer más clara una expresión sin anidar. Una regla de envío puede indicar directamente WHEN country = 'US' AND subtotal >= 100 THEN 0, manteniendo juntas las comprobaciones de país y subtotal.

Puntos clave

  • CASE simple compara una expresión mediante igualdad con una serie de valores.
  • Utiliza CASE de búsqueda para comprobaciones de NULL, intervalos y condiciones combinadas.
  • Un CASE numérico en ORDER BY crea una clasificación personalizada.
  • Un indicador con ELSE 0 también asigna cero cuando su condición es UNKNOWN.
  • COALESCE y NULLIF expresan casos particulares habituales de CASE.
  • DECODE de Oracle trata dos NULL como iguales; CASE simple no lo hace.

5.3 Combina funciones en una consulta completa para informes

Un informe puede limpiar nombres, calcular totales netos, identificar meses y etiquetar la rapidez del envío en un solo SELECT. Construye cada expresión a partir de sus entradas y comprueba el resultado antes de combinarla con las demás.

Trabaja a partir de filas conocidas

Una tabla de pedidos contiene estos registros. Las fechas son texto ISO para la consulta SQLite que aparece a continuación; quantity es entero y unit_price es numérico.

PedidoClienteCantidadPrecioDescuento %Fecha del pedidoFecha de envío
1001Ana Lopez312,50102026-03-142026-03-17
1002Ben Okafor1240,0002026-03-30NULL
1003Chen Wu124,25NULL2026-04-022026-04-03

Aquí, un descuento ausente significa que no hay descuento. Empieza recuperando los campos originales. Añade una columna calculada cada vez y utiliza LIMIT 5 mientras compruebas una muestra pequeña.

Sigue un cálculo anidado
ROUND(quantity * unit_price *
      (1 - COALESCE(discount_pct, 0) / 100.0), 2)

COALESCE proporciona primero un descuento conocido. Dividir por 100.0 conserva su parte fraccionaria. Restarlo de 1 da la fracción que se paga, la multiplicación da el importe neto y ROUND establece la precisión final. El importe de Ana es 33,75, el de Ben es 240,0 y el de Chen es 51,0. El descuento NULL de Chen se convierte en cero; en cambio, una fecha de envío ausente debe seguir ausente en el recuento de días.

Construye el informe de SQLite
SELECT order_id,
       first_name || ' ' || last_name AS customer,
       ROUND(quantity * unit_price *
         (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net_total,
       strftime('%Y-%m', order_date) AS order_month,
       CAST(julianday(shipped_date) - julianday(order_date)
         AS INTEGER) AS days_to_ship,
       CASE
         WHEN shipped_date IS NULL THEN 'not shipped'
         -- fast = shipped within 2 days
         WHEN julianday(shipped_date) - julianday(order_date) <= 2
           THEN 'fast'
         ELSE 'standard'
       END AS shipping
FROM orders
ORDER BY order_id;

Cada expresión tiene un alias de salida claro. La diferencia numérica de días se convierte a INTEGER porque estos valores solo contienen fechas. La rama IS NULL aparece antes de la comparación de rapidez, por lo que un pedido sin enviar recibe una etiqueta útil.

La salida es:

PedidoClienteTotal netoMesDíasEnvío
1001Ana Lopez33,752026-033estándar
1002Ben Okafor240,02026-03NULLsin enviar
1003Chen Wu51,02026-041rápido
Adapta los tipos y las cláusulas de la consulta

Para columnas DATE de PostgreSQL, utiliza TO_CHAR(order_date, 'YYYY-MM') para el mes y shipped_date - order_date para el recuento de días y la comparación CASE. Mantén unit_price como numeric exacto para ROUND de dos argumentos. La concatenación, la sustitución del descuento y la regla de clasificación conservan el mismo significado.

Para filtrar los totales redondeados superiores a 50 en ambas bases de datos, repite la expresión neta completa en WHERE. Permanecen los pedidos 1002 y 1003. SQLite también permite WHERE net_total > 50, pero PostgreSQL no puede ver ese nuevo alias en la etapa de filtrado. ORDER BY net_total DESC funciona en ambos.

Al trasladar un informe, comprueba los tipos y los nombres de funciones de cada expresión. Una función de texto debe recibir texto, un cálculo de fechas debe recibir un valor de fecha compatible y una sustitución numérica debe expresar la regla prevista. Coloca cada salida en su propia línea; un comentario breve puede definir un umbral de negocio sin dificultar la lectura del SQL.

Puntos clave

  • Construye y comprueba una columna calculada cada vez con una muestra pequeña.
  • Las funciones anidadas pasan sus resultados hacia fuera; mantén adecuado el tipo de cada entrada.
  • Un descuento ausente y una fecha de envío ausente pueden necesitar tratamientos distintos.
  • Utiliza expresiones de fecha adecuadas al dialecto y conserva las reglas del informe.
  • Filtra con la expresión completa y ordena con su alias de salida cuando corresponda.

Ejemplos de Columnas calculadas en SQL

5 Lecciones Interactivas

1

Construye y comprueba un importe de línea con descuento

16 pasos
Calcula un importe, dale nombre, conserva su parte fraccionaria y comprueba los tipos que determinan el resultado.
  1. 1
    IntroducciónConvierte una fila en un importe útil

    Una línea de pedido registra ocho artículos a 7,50 cada uno con un descuento del 20 por ciento. El informe necesita un importe neto, pero la tabla solo almacena las entradas. Construirás la expresión por etapas, darás nombre a su salida y comprobarás qué hace la división entera con el descuento.

    Los ejemplos utilizan SQLite y PostgreSQL. Cuando sus reglas de tipos difieren, el nombre de la base de datos identifica el resultado.

  2. 2
    ExplicaciónEmpieza con una expresión

    Una expresión combina valores para producir otro valor. Aquí, quantity * unit_price utiliza dos columnas de la fila actual.

    SELECT quantity * unit_price AS gross_total
    FROM order_lines;
    

    gross_total es el alias de salida. Para la fila de ejemplo, el nuevo valor es 60.0 en SQLite. Cada una de las demás filas aporta sus propias entradas; la consulta no guarda estos totales en la tabla.

  3. 3
    ConexiónCada fila sigue teniendo su propio valor

    Una función de una sola fila devuelve un valor por cada fila de entrada. ROUND(unit_price, 0) cambia el precio mostrado de una fila, mientras que UPPER(item_name) cambia su texto mostrado.

    Estas funciones no combinan las líneas de pedido. Una función de agregación como SUM sí combina valores de un grupo, por lo que responde a otro tipo de pregunta. Un cálculo en SELECT puede conservar el detalle de los pedidos individuales.

  4. 4
    ConsejoDa un nombre claro al resultado

    AS net_total es un alias sencillo y legible. Utiliza comillas dobles cuando un nombre tenga un espacio, como en AS "Net Total". Las comillas simples identifican valores de texto.

    Mantén una coma entre las expresiones de salida. SELECT quantity unit_price devuelve una columna de cantidades con el encabezado unit_price: sin coma, el segundo nombre se convierte en un alias. Esa consulta puede ejecutarse correctamente y mostrar menos columnas de las previstas.

  5. 5
    DesafíoColoca el alias en la consulta

    La tabla solo tiene quantity y unit_price. Una consulta define quantity * unit_price AS gross_total. ¿Puede un filtro WHERE de PostgreSQL utilizar gross_total > 50 y puede ORDER BY utilizar gross_total DESC?

    ---reveal---

    WHERE no puede ver ese nuevo alias porque precede lógicamente a SELECT. Repite quantity * unit_price > 50. ORDER BY va después de SELECT y puede utilizar gross_total DESC. SQLite permite el alias en WHERE como una extensión, pero PostgreSQL no.

  6. 6
    EjemploConvierte un descuento en la fracción que se paga

    El importe bruto es 8 * 7.50, es decir, 60. Un descuento del 20 por ciento deja un 80 por ciento por pagar. Exprésalo como 1 - discount_pct / 100.0.

    quantity * unit_price * (1 - discount_pct / 100.0)
    

    La división da 0.2; los paréntesis dan 0.8; la multiplicación da un importe neto de 48.0. Los paréntesis mantienen la resta como un único factor.

  7. 7
    Idea claveUn decimal posterior no puede reparar una división anterior

    Supón que discount_pct es un entero y que el divisor se escribe como 100. SQLite y PostgreSQL calculan 20 / 100 mediante división entera y obtienen 0. El factor pasa a ser 1, por lo que el neto se mantiene incorrectamente en 60.

    El precio decimal de otra parte de la expresión no corrige esa división interna. Utiliza 100.0 en la propia división. Convertir después el cociente ya calculado cambia su tipo, pero no puede recuperar la parte fraccionaria perdida.

  8. 8
    DesafíoEncuentra el cálculo que perdió su parte fraccionaria

    Una fila de SQLite tiene el entero completed = 9 y el entero assigned = 12. ¿Qué devuelve completed / assigned * 100.0 y cómo debería calcular el porcentaje la expresión?

    ---reveal---

    Devuelve 0.0: la división entera 9 / 12 se convierte primero en 0. Escribe completed * 100.0 / assigned, que da 75.0. La conversión debe producirse antes de dividir, no solo antes de mostrar el resultado final.

  9. 9
    ExplicaciónElige la regla para obtener un entero

    ROUND elige un valor redondeado cercano. FLOOR baja hasta un entero, CEIL sube y TRUNC elimina la parte fraccionaria hacia cero.

    Para -6.4, FLOOR da -7, mientras que CEIL y TRUNC dan -6. La dirección importa con las entradas negativas. PostgreSQL proporciona estas funciones; CEIL, FLOOR y TRUNC de SQLite requieren una versión compilada con funciones matemáticas. ABS, que da la distancia a cero, está incorporada en SQLite.

  10. 10
    ConsejoComprueba el tipo numérico antes de redondear

    En PostgreSQL, ROUND de dos argumentos recibe numeric, no double precision. Para una columna de coma flotante, escribe ROUND(CAST(amount AS numeric), 2). SQLite acepta su propia forma numérica de ROUND.

    Los valores aproximados de coma flotante pueden producir empates inesperados. Para importes exactos, NUMERIC/DECIMAL de PostgreSQL almacena decimales exactos; SQLite puede conservar los céntimos enteros como números enteros. Redondea el resultado mostrado después del cálculo.

  11. 11
    ExplicaciónHaz explícito un cambio de tipo

    CAST(expression AS type) solicita una conversión. El texto '28' puede convertirse en el entero 28 con CAST('28' AS INTEGER). El número puede convertirse en texto con CAST(28 AS TEXT).

    Para una división con parte fraccionaria, SQLite necesita REAL para obtener de forma fiable un operando no entero. CAST(7 AS NUMERIC) puede seguir siendo el entero 7 en ese sistema. NUMERIC de PostgreSQL proporciona un tipo decimal exacto. Convertir NULL con CAST sigue dando NULL.

  12. 12
    EjemploMantén separados los identificadores y las cantidades

    Supón que una etiqueta almacena el código postal estadounidense ZIP '00421'. Convertirlo en un entero da 421, y se pierden los ceros iniciales. Es un identificador, por lo que no se trata de hacer operaciones aritméticas.

    Una columna de texto que realmente contenga cantidades puede necesitar una conversión para la ordenación numérica. Los textos '12', '3' y '80' se ordenan en ese orden; la ordenación numérica da 3, 12, 80. Elige la conversión según el significado de la columna.

  13. 13
    DesafíoInterpreta una conversión sin tomarla como validación

    SQLite ejecuta correctamente CAST('31units' AS INTEGER). ¿Qué valor devuelve y demuestra ese éxito que el texto original era un entero válido?

    ---reveal---

    Devuelve 31 leyendo la parte numérica inicial. Ejecutarse correctamente no valida toda la cadena. PostgreSQL rechaza ese mismo texto como entero. SQLite también puede convertir en cero texto sin un prefijo numérico, ocultando una entrada incorrecta.

  14. 14
    Idea claveLa conversión a entero no funciona igual en todos los sistemas

    Para el valor numérico 4.7, CAST(... AS INTEGER) de SQLite trunca a 4, mientras que PostgreSQL redondea a 5. Si un informe quiere «unidades enteras que no superen este valor», exprésalo con FLOOR antes de la conversión.

    Una conversión implícita también depende de la base de datos. PostgreSQL puede inferir un número a partir de un literal entre comillas en una operación aritmética, pero una columna TEXT necesita una conversión explícita. Los caracteres visibles por sí solos no determinan el tipo del operando.

  15. 15
    DesafíoComprueba la expresión neta completa

    Para ocho artículos a 7,50 con el entero discount_pct = 20, un informe escribe ROUND(quantity * unit_price * (1 - discount_pct / 100.0), 2) AS net_total. ¿Cuál es el resultado y puede ese alias ordenar la salida?

    ---reveal---

    El bruto es 60, la fracción que se paga es 0,8 y el neto es 48.0 en SQLite. ORDER BY net_total es válido tanto en SQLite como en PostgreSQL porque la ordenación puede ver el alias de SELECT.

  16. 16
    RepasoLee las entradas, el cálculo y el nombre de salida

    Un importe calculado sigue un recorrido: la fila aporta valores, las operaciones aritméticas y las funciones producen el resultado y un alias le da nombre. Comprueba el orden de las operaciones y los tipos de los operandos antes de aceptar un número mostrado.

    Cuando un resultado sea inesperado, revisa primero una división o conversión interna. Para filtrar un valor calculado en distintas bases de datos, repite su expresión en WHERE; para ordenarlo, utiliza el alias de salida en ORDER BY.

2

Sigue los datos ausentes a través de una consulta

12 pasos
Sigue las condiciones UNKNOWN y después elige y combina COALESCE y NULLIF.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónUn importe ausente cambia algo más que una celda
  2. 2
    ExplicaciónNULL es una entrada desconocida
  3. 3
    EjemploUtiliza una comprobación que detecte la ausencia
  4. 4
    Idea claveWHERE solo acepta TRUE
  5. 5
    DesafíoCombina una condición conocida con otra desconocida
  6. 6
    ConsejoNo dejes NULL en una lista de exclusión
  7. 7
    ExplicaciónElige un valor de sustitución según el significado
  8. 8
    EjemploMantén uniforme el tipo de presentación
  9. 9
    EjemploConvierte un denominador cero en un valor ausente
  10. 10
    DesafíoLimpia la cadena vacía antes de aplicar la etiqueta
  11. 11
    DesafíoDistingue la decisión de presentación de la decisión de filtrado
  12. 12
    RepasoMantén visible el significado de una ausencia
3

Limpia un nombre y extrae el dominio de un correo electrónico

14 pasos
Concatena texto, anida funciones de limpieza y sigue las posiciones de los caracteres alrededor de un separador.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónHaz utilizable el texto sin perder sus partes
  2. 2
    EjemploAporta el espacio entre el nombre y el apellido
  3. 3
    ExplicaciónDecide qué efecto tiene una parte ausente del nombre
  4. 4
    EjemploLimpia el correo de dentro hacia fuera
  5. 5
    DesafíoElige entre recortar y sustituir
  6. 6
    ConsejoComprueba las reglas de caracteres y dialectos
  7. 7
    ExplicaciónCuenta desde uno
  8. 8
    EjemploLocaliza el separador
  9. 9
    EjemploExtrae los caracteres anteriores y posteriores a @
  10. 10
    DesafíoEncuentra el resultado desplazado una posición
  11. 11
    Idea claveUn resultado de búsqueda cero necesita su propio tratamiento
  12. 12
    ConsejoExtrae finales y rellena códigos en el dialecto adecuado
  13. 13
    DesafíoCombina la limpieza con la extracción
  14. 14
    RepasoSigue los caracteres exactos
4

Crea etiquetas de fecha y filtros de período fiables

18 pasos
Lee valores de fecha, dales formato para mostrarlos y calcula plazos, duraciones y períodos completos.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónSepara el valor de calendario de su etiqueta
  2. 2
    ExplicaciónElige una representación de fecha clara
  3. 3
    EjemploLee un formato local fijo
  4. 4
    DesafíoExplica qué texto se ordena por fecha
  5. 5
    ConsejoComprueba la interpretación y la referencia horaria actual
  6. 6
    EjemploExtrae el mes con el tipo de retorno correcto
  7. 7
    ExplicaciónConserva el año en la etiqueta de año y mes
  8. 8
    EjemploCrea una presentación sin cambiar la ordenación
  9. 9
    DesafíoEncuentra el trimestre correcto
  10. 10
    ConexiónElige la convención de numeración de los días de la semana
  11. 11
    EjemploAñade diez días a la reserva
  12. 12
    Idea claveUn mes no es un número fijo de días
  13. 13
    EjemploMide días y horas en unidades adecuadas
  14. 14
    DesafíoIncluye la última tarde del mes
  15. 15
    ExplicaciónCuenta los cumpleaños que ya han llegado
  16. 16
    ConsejoInterpreta las fechas relativas como límites móviles
  17. 17
    DesafíoCombina un vencimiento con la selección de un mes
  18. 18
    RepasoComprueba el tipo, la regla de calendario y los extremos
5

Etiqueta pedidos y construye el informe final

17 pasos
Elige ramas CASE, convierte prioridades y combina varias salidas calculadas.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónAsigna una etiqueta útil a cada pedido
  2. 2
    ExplicaciónElige la primera condición verdadera
  3. 3
    EjemploSigue el límite exacto
  4. 4
    Idea claveELSE también puede recoger un importe desconocido
  5. 5
    DesafíoRecupera una categoría pequeña oculta
  6. 6
    ConsejoDevuelve resultados compatibles
  7. 7
    EjemploConvierte un valor de estado en una etiqueta
  8. 8
    Desafío¿Por qué WHEN NULL no detecta la fila?
  9. 9
    EjemploOrdena las prioridades por posición
  10. 10
    Idea claveUn indicador puede reunir casos conocidos y desconocidos
  11. 11
    EjemploEmpieza el informe con entradas conocidas
  12. 12
    EjemploCalcula primero el importe neto
  13. 13
    EjemploAñade fechas con una regla de ausencia independiente
  14. 14
    DesafíoComprueba una segunda fila con ambas reglas
  15. 15
    ConexiónAdapta las expresiones de fecha a PostgreSQL
  16. 16
    DesafíoFiltra el importe que muestra realmente el informe
  17. 17
    RepasoComprueba el informe como un conjunto de decisiones explícitas

Ejercicios de Columnas calculadas en SQL

40 Preguntas de Práctica en 4 sets

Set 1: Limpia texto y trabaja con valores de calendario10 Preguntas de Práctica

Pregunta 1 de 10

¿Qué devuelve LOWER(TRIM(' RAE@Mail.COM ')) en SQLite?
  1. ' rae@mail.com '
  2. 'RAE@Mail.COM' (conserva mayúsculas y minúsculas)
  3. 'rae@mail.com'
  4. 'rae@mail.com '
Mostrar respuestaOcultar respuesta
Respuesta: C
TRIM elimina primero los espacios de ambos extremos y después LOWER convierte las letras ASCII en minúsculas. El resultado es el texto limpio 'rae@mail.com'. Conservar el espacio final significaría que solo se recortó el extremo izquierdo; TRIM ordinario trata ambos extremos y no necesita un RTRIM aparte.

Pregunta 2 de 10

Una fila de SQLite desde la versión 3.44 tiene first_name = 'Mira', middle_name = NULL y last_name = 'Shah'. ¿Qué devuelven first_name || ' ' || middle_name || ' ' || last_name y CONCAT_WS(' ', first_name, middle_name, last_name), en ese orden?
  1. NULL; 'Mira Shah'
  2. 'Mira Shah'; 'Mira Shah'
  3. NULL; NULL
  4. 'Mira Shah'; 'Mira Shah'
Mostrar respuestaOcultar respuesta
Respuesta: A
La expresión || propaga su entrada NULL del segundo nombre, haciendo que todo el nombre sea NULL. CONCAT_WS omite la parte ausente y coloca un separador entre Mira y Shah. Habría dos espacios si se conservara una posición vacía para el segundo nombre, pero aquí la entrada es NULL y CONCAT_WS la omite.

Pregunta 3 de 10

En SQLite, ¿qué devuelve SUBSTR('Seattle', 3, 3)?
  1. 'attl'
  2. 'tle'
  3. 'eat'
  4. 'att'
Mostrar respuestaOcultar respuesta
Respuesta: D
Las posiciones SQL empiezan en 1, por lo que la posición 3 es la primera t de Seattle. Tomar tres caracteres desde ahí da 'att'. El fragmento 'eat' empieza en la posición 2 y se obtendría al interpretar la posición inicial indicada como un carácter anterior a la que realmente es.

Pregunta 4 de 10

En PostgreSQL, una columna TEXT email puede contener NULL o texto sin @. Para el texto que contenga @, devuelve todo lo que haya después del primer @; en caso contrario, devuelve NULL. ¿Qué expresión es adecuada?
  1. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@')) END
  2. CASE WHEN STRPOS(email, '@') > 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  3. CASE WHEN STRPOS(email, '@') >= 0 THEN SUBSTR(email, STRPOS(email, '@') + 1) END
  4. CASE WHEN email IS NOT NULL THEN SUBSTR(email, STRPOS(email, '@') + 1) END
Mostrar respuestaOcultar respuesta
Respuesta: B
Un resultado positivo de STRPOS confirma que se encontró un separador; sumar 1 hace que se empiece después de él. Sin coincidencia, WHEN es falso y, con NULL, es UNKNOWN, por lo que ambos devuelven el NULL implícito. Comprobar >= 0 también acepta un separador ausente, cuya posición es cero, y devolvería toda la cadena mal formada.

Pregunta 5 de 10

¿Qué texto de fecha ISO representa el 6 de noviembre de 2027?
  1. '2027-11-06'
  2. '11/06/2027'
  3. '2027-06-11'
  4. '2027-11-6'
Mostrar respuestaOcultar respuesta
Respuesta: A
El texto de fecha ISO utiliza año, mes y día, con mes y día de dos dígitos. Noviembre es el mes 11 y el sexto día es 06, por lo que el resultado es '2027-11-06'. La terminación invertida 06-11 representa el 11 de junio, mientras que un día final de un dígito no sigue el formato de anchura fija.

Pregunta 6 de 10

¿Qué devuelve SQLite actual para date('2027-04-31')?
  1. '2027-04-30'
  2. Un error de fecha no válida
  3. '2027-05-01'
  4. NULL
Mostrar respuestaOcultar respuesta
Respuesta: C
SQLite normaliza el día adicional de abril pasándolo a mayo, lo que da '2027-05-01'. Por tanto, un resultado de fecha que no sea NULL no garantiza que el día original existiera en ese mes. PostgreSQL rechaza el literal DATE con tipo equivalente, pero no se debe suponer ese comportamiento estricto para la función de fecha de SQLite.

Pregunta 7 de 10

En SQLite, d contiene '2027-08-19'. ¿Cuáles son los resultados de strftime('%m', d) = 8 y CAST(strftime('%m', d) AS INTEGER) = 8, en ese orden?
  1. TRUE; TRUE
  2. FALSE; TRUE
  3. FALSE; FALSE
  4. TRUE; FALSE
Mostrar respuestaOcultar respuesta
Respuesta: B
strftime devuelve el texto '08', que no es igual al número 8 en la primera expresión. Convertir ese texto a INTEGER produce 8 y hace verdadera la segunda comparación. El cero inicial forma parte del texto devuelto; mostrar un mes como dígitos no hace numérico el resultado de la función.

Pregunta 8 de 10

Una columna DATE de PostgreSQL, event_date, abarca varios años. Un informe muestra fechas como MM/DD/YYYY y debe mantener el orden cronológico. ¿Cómo debe seleccionar y ordenar la columna?
  1. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY day_label;
  2. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY EXTRACT(MONTH FROM event_date), EXTRACT(DAY FROM event_date);
  3. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY CAST(TO_CHAR(event_date, 'MM/DD/YYYY') AS TEXT);
  4. SELECT TO_CHAR(event_date, 'MM/DD/YYYY') AS day_label FROM events ORDER BY event_date;
Mostrar respuestaOcultar respuesta
Respuesta: D
TO_CHAR proporciona el texto de presentación solicitado, mientras que ordenar el DATE original mantiene el año, el mes y el día en orden cronológico. Ordenar el alias de presentación empieza por los caracteres del mes y puede entremezclar años. Ordenar solo el mes y el día extraídos tiene el mismo problema de ausencia del año, aunque esos componentes sean numéricos.

Pregunta 9 de 10

Una fecha d de SQLite es '2027-04-24'. ¿Qué devuelve date(d, '+10 days')?
  1. '2027-05-03'
  2. '2027-04-34'
  3. '2027-05-04'
  4. '2027-05-05'
Mostrar respuestaOcultar respuesta
Respuesta: C
Seis días después del 24 de abril se llega al 30 de abril y cuatro más llevan al 4 de mayo, por lo que el resultado es '2027-05-04'. El 3 de mayo cuenta la fecha inicial como uno de los diez días añadidos. Un desplazamiento de fecha mide días posteriores al punto de partida y lleva los días restantes al mes siguiente.

Pregunta 10 de 10

Una columna TIMESTAMP de PostgreSQL no tiene zona horaria y registra horas a lo largo de junio de 2027. ¿Qué filtro incluye todos los valores de junio y ninguno de julio?
  1. logged_at >= '2027-06-01' AND logged_at < '2027-07-01'
  2. logged_at BETWEEN '2027-06-01' AND '2027-06-30'
  3. logged_at >= '2027-06-01' AND logged_at <= '2027-07-01'
  4. logged_at > '2027-06-01' AND logged_at < '2027-07-01'
Mostrar respuestaOcultar respuesta
Respuesta: A
El límite inferior inclusivo del 1 de junio conserva el primer instante y el límite superior exclusivo del 1 de julio incluye todas las horas anteriores al mes siguiente. Un BETWEEN que termine el 30 de junio solo llega a medianoche al inicio de ese día. Incluir el 1 de julio admitiría un valor límite no deseado, mientras que excluir el 1 de junio perdería su registro de medianoche.
Set 2: Calcula importes y gestiona datos ausentes10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

Una tabla de PostgreSQL solo tiene units y unit_cost. ¿Qué lista SELECT devuelve su producto con el encabezado extended_cost?
  1. units + unit_cost AS extended_cost
  2. units * unit_cost AS extended_cost
  3. units * unit_cost, extended_cost
  4. units * 'unit_cost' AS extended_cost
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

La tabla lines solo contiene units y price. Una consulta debe ejecutarse en SQLite y PostgreSQL. ¿Cómo debe conservar las filas cuyo producto sea superior a 90 y ordenar primero el producto mayor?
  1. SELECT units * price AS amount FROM lines WHERE amount > 90 ORDER BY amount DESC;
  2. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount ASC;
  3. SELECT units * price AS amount FROM lines ORDER BY amount DESC WHERE units * price > 90;
  4. SELECT units * price AS amount FROM lines WHERE units * price > 90 ORDER BY amount DESC;
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

¿Qué devuelve SELECT 14 + 5 * 3; en SQLite?
  1. 29
  2. 57
  3. 33
  4. 75
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

En SQLite, old_count y new_count son enteros que contienen 60 y 69. ¿Cuál es el resultado de (new_count - old_count) / old_count * 100?
  1. 15
  2. 0.15
  3. 0
  4. 9
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Una fila de factura de SQLite tiene los enteros units = 5 y discount_pct = 12, con price = 18.0. ¿Qué resultado produce ROUND(units * price * (1 - discount_pct / 100), 2)?
  1. 79.2
  2. 90.0
  3. 89.88
  4. 78.0
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

¿Qué devuelve SQLite para CAST('27boxes' AS INTEGER)?
  1. 27
  2. 0
  3. Un error de entero no válido
  4. NULL
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

¿Qué condición encuentra filas sin delivery_date registrada?
  1. delivery_date = NULL
  2. delivery_date <> NULL
  3. delivery_date = ''
  4. delivery_date IS NULL
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Una tabla contiene exactamente cuatro valores de region: 'East', 'West', NULL y 'North'. ¿Cuántas filas cumplen WHERE NOT (region = 'East')?
  1. 3
  2. 2
  3. 1
  4. 4
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Tanto una cadena de teléfono vacía como NULL deben mostrarse como 'unlisted' en SQLite. ¿Qué expresión lo hace conservando los números registrados?
  1. NULLIF(COALESCE(phone, ''), 'unlisted')
  2. COALESCE(phone, '', 'unlisted')
  3. COALESCE(NULLIF(phone, ''), 'unlisted')
  4. COALESCE(NULLIF(phone, 'unlisted'), '')
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Un informe de PostgreSQL tiene los enteros sales y visits. Una tasa debe conservar los porcentajes con parte fraccionaria y seguir siendo NULL cuando visits sea cero. No debe inventar una tasa de cero. ¿Qué expresión es adecuada?
  1. COALESCE(sales * 100.0 / NULLIF(visits, 0), 0)
  2. sales / NULLIF(visits, 0) * 100.0
  3. sales * 100.0 / COALESCE(visits, 1)
  4. sales * 100.0 / NULLIF(visits, 0)
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 3: Clasifica filas y diagnostica la lógica de los informes10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

¿Qué etiqueta produce este CASE para score = 75: CASE WHEN score < 60 THEN 'review' WHEN score < 80 THEN 'ready' ELSE 'strong' END?
  1. 'review'
  2. 'strong'
  3. NULL
  4. 'ready'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

¿Por qué CASE WHEN amount < 500 THEN 'regular' WHEN amount < 100 THEN 'small' ELSE 'large' END nunca devuelve 'small' para importes que no son NULL?
  1. CASE comprueba primero el último intervalo coincidente.
  2. Todo importe inferior a 100 ya cumple la comprobación anterior de ser inferior a 500.
  3. La rama ELSE anula un intervalo coincidente posterior.
  4. La segunda condición solo se comprueba para importes iguales a 500.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

Un balance numérico puede ser NULL. Las etiquetas requeridas son 'unknown' si falta, 'credit' por debajo de 0, 'settled' en 0 y 'due' por encima de 0. ¿Qué CASE cumple todas las reglas?
  1. CASE WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  2. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance <= 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  3. CASE WHEN balance IS NULL THEN 'unknown' WHEN balance < 0 THEN 'credit' WHEN balance = 0 THEN 'settled' ELSE 'due' END
  4. CASE balance WHEN NULL THEN 'unknown' WHEN 0 THEN 'settled' ELSE 'due' END
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

Un valor de state de 'H' significa retenido y 'R' significa liberado. ¿Qué devuelve CASE state WHEN 'H' THEN 'held' WHEN 'R' THEN 'released' ELSE 'other' END para 'R'?
  1. 'released'
  2. 'held'
  3. 'other'
  4. NULL
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Un informe debe ordenar 'urgent', 'normal' y 'deferred' en ese orden, con todas las demás prioridades o las NULL al final. ¿Qué expresión ORDER BY es adecuada?
  1. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END DESC
  2. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END DESC
  3. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 3 WHEN 'deferred' THEN 2 ELSE 4 END ASC
  4. CASE priority WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 WHEN 'deferred' THEN 3 ELSE 4 END ASC
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Una fila de SQLite tiene qty = 4, price = 15.0, discount_pct = NULL y shipped_date = NULL. Un descuento ausente significa que no hay descuento. ¿Qué par se obtiene de ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) y CASE WHEN shipped_date IS NULL THEN 'open' ELSE 'sent' END?
  1. NULL; 'open'
  2. 0.0; 'open'
  3. 60.0; 'open'
  4. 60.0; 'sent'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

Un informe de SQLite muestra LOWER(TRIM(customer)) AS name y date(due_date, '+7 days') AS reminder_date. El valor original de customer es ' IVAN ' y due_date es '2027-09-26'. ¿Qué par de salida debe encontrar una comprobación de una muestra?
  1. 'ivan'; '2027-10-03'
  2. ' ivan '; '2027-10-03'
  3. 'ivan'; '2027-10-02'
  4. 'IVAN' (conserva mayúsculas); '2027-10-03'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Una tabla de PostgreSQL contiene los valores de x 2, 7, NULL y 11. ¿Cuántas filas devuelven WHERE x NOT IN (2, NULL) y WHERE x <> 2 OR x IS NULL, respectivamente?
  1. 2 y 3
  2. 0 y 3
  3. 0 y 2
  4. 3 y 3
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Una persona nació el '1998-12-18'. A fecha de '2027-12-17', ¿cuál es su edad en años cumplidos y por qué puede ser incorrecto restar los dos números de año?
  1. 28; el cumpleaños aún no ha llegado en 2027.
  2. 29; un nuevo año de calendario completa un año de edad.
  3. 28; los nacimientos de diciembre siempre cuentan un año menos.
  4. 29; los días transcurridos divididos por 365 dan la edad.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Una columna INTEGER de PostgreSQL, rating, puede ser NULL. Una columna de presentación debe mostrar la valoración como texto o 'unrated'. ¿Qué expresión es adecuada?
  1. CAST(COALESCE(rating, 'unrated') AS TEXT)
  2. NULLIF(CAST(rating AS TEXT), 'unrated')
  3. COALESCE(CAST(rating AS TEXT), 'unrated')
  4. CAST(NULLIF(rating, 0) AS TEXT)
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 4: Comprueba informes completos y límites difíciles10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

Una tabla de PostgreSQL solo tiene qty entero, price NUMERIC y discount_pct entero. Un descuento ausente significa que no hay descuento. Un informe debe conservar los totales netos redondeados superiores a 75 y ordenarlos de mayor a menor. ¿Qué consulta completa es adecuada?
  1. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE net > 75 ORDER BY net DESC;
  2. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net DESC;
  3. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100), 2) > 75 ORDER BY net DESC;
  4. SELECT ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net FROM lines WHERE ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) > 75 ORDER BY net ASC;
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

Una columna de PostgreSQL, reading, es DOUBLE PRECISION. ¿Cómo puede un informe redondearla a dos decimales sin un error de firma de función?
  1. ROUND(reading, 2)
  2. CAST(ROUND(reading) AS NUMERIC)
  3. ROUND(CAST(reading AS NUMERIC), 2)
  4. ROUND(CAST(reading AS INTEGER), 2)
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

¿Qué devuelve COALESCE(NULL, '', 'backup') en SQLite?
  1. ''
  2. 'backup'
  3. NULL
  4. 'NULL'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

En SQLite, una fila tiene email = 'nora@research.org'. ¿Qué resultado produce SUBSTR(email, INSTR(email, '@'))?
  1. 'research.org'
  2. 'nora'
  3. 'nora@'
  4. '@research.org'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Para '2027-01-31', compara date(d, '+1 month') de SQLite desde la versión 3.46, date(d, '+1 month', 'floor') de SQLite y DATE '2027-01-31' + INTERVAL '1 month' de PostgreSQL. ¿Qué fechas de calendario resultan, en ese orden?
  1. 28 de febrero; 28 de febrero; 28 de febrero
  2. 3 de marzo; 3 de marzo; 28 de febrero
  3. 3 de marzo; 28 de febrero; 28 de febrero
  4. 28 de febrero; 3 de marzo; 3 de marzo
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Un INTEGER de PostgreSQL, stock, puede ser NULL. El indicador numérico requerido es NULL para existencias desconocidas, 1 para existencias inferiores a 5 y 0 en los demás casos. ¿Qué expresión es adecuada?
  1. CASE WHEN stock < 5 THEN 1 ELSE 0 END
  2. CASE WHEN stock IS NULL THEN NULL WHEN stock < 5 THEN 1 ELSE 0 END
  3. CASE WHEN stock IS NULL THEN NULL WHEN stock <= 5 THEN 1 ELSE 0 END
  4. CASE stock WHEN NULL THEN NULL WHEN 5 THEN 0 ELSE 1 END
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

SQLite desde la versión 3.38 registra una sesión desde '2027-05-08 10:15:00' hasta '2027-05-08 13:45:00'. ¿Qué devuelve (unixepoch(end_time) - unixepoch(start_time)) / 3600.0?
  1. 3.0
  2. 210.0
  3. 12600.0
  4. 3.5
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Un pedido de SQLite tiene el entero qty = 6, price = 8.0, discount_pct = 25, fecha de pedido '2027-07-10' y fecha de envío '2027-07-12'. El neto utiliza ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2). Un CASE etiqueta el envío NULL como 'open', los días transcurridos <= 2 como 'fast' y los demás como 'standard'. ¿Qué neto y etiqueta resultan?
  1. 36.0; 'fast'
  2. 48.0; 'fast'
  3. 36.0; 'standard'
  4. 12.0; 'fast'
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Un informe de SQLite necesita números de trimestre del 1 al 4 para cualquier fecha válida d. ¿Cómo puede calcular el trimestre para todos los meses?
  1. CAST(strftime('%m', d) AS INTEGER) / 3 + 1
  2. (CAST(strftime('%m', d) AS INTEGER) + 1) / 3
  3. ROUND(CAST(strftime('%m', d) AS INTEGER) / 3.0)
  4. (CAST(strftime('%m', d) AS INTEGER) + 2) / 3
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Una tabla de SQLite tiene las filas A (qty 3, price 22.0, discount_pct NULL), B (qty 4, price 20.0, discount_pct 25) y C (qty 2, price 40.0, discount_pct 10). Un descuento ausente significa que no hay descuento. Calcula ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net, conserva net > 60 utilizando la expresión completa en WHERE y ordena por net DESC. ¿Cuál es el orden de las filas?
  1. B, C, A
  2. C, A
  3. C, A, B
  4. A, C
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

¿Te atascas con una pregunta tuya? Ayuda con Tareas

Términos Clave

61 Términos Clave, cada uno con su definición

A

Afinidad de tipo
La afinidad de tipo es la preferencia de SQLite sobre cómo almacena valores una columna; una columna ordinaria puede seguir conteniendo valores de distintos tipos.
Una declaración NUMERIC de SQLite puede conservar 7 como entero, por lo que no garantiza una división decimal.
Alias de columna
Un alias de columna es un nombre asignado a una columna de salida de una consulta, a menudo con AS, para que el resultado tenga un encabezado claro.
La consulta etiqueta su importe calculado con AS line_total y puede ordenarlo con ORDER BY line_total.
Anidamiento de funciones
El anidamiento de funciones coloca una llamada a función dentro de otra, de modo que el resultado interno se convierte en un argumento de la llamada que la contiene.
En ROUND(COALESCE(amount, 0), 2), la sustitución se resuelve antes de que la función de redondeo reciba su entrada.

C

Cadena de caracteres
Una cadena de caracteres es un valor de texto formado por caracteres, incluidas letras, dígitos, signos de puntuación y espacios, escrito como literal entre comillas simples en SQL.
La cadena ' New York ' incluye espacios en los extremos y dos espacios interiores que afectan a su longitud.
CASE de búsqueda
Un CASE de búsqueda comprueba condiciones en el orden escrito y devuelve el resultado de la primera condición TRUE para la fila actual.
CASE WHEN total < 50 THEN 'small' ELSE 'large' END elige una etiqueta a partir del importe de la fila.
CASE simple
Un CASE simple compara una expresión mediante igualdad con una secuencia de valores y devuelve el resultado del primer valor coincidente.
CASE status WHEN 'S' THEN 'Shipped' ELSE 'Other' END convierte un código de estado almacenado en una etiqueta.
CEIL
CEIL es una función numérica que devuelve el menor entero mayor o igual que su entrada; CEILING es otro nombre.
El cálculo CEIL(4.1) da 5 porque cuatro está por debajo de la entrada y cinco es el siguiente número entero.
COALESCE
COALESCE es una función de SQL estándar que devuelve el primer argumento que no sea NULL, o NULL cuando todos sus argumentos son NULL.
COALESCE(mobile_phone, home_phone, 'no phone') utiliza el número fijo si falta el número de móvil.
Columna calculada
Una columna calculada en una consulta es una columna de salida cuyo valor se calcula para cada fila, sin cambiar los datos almacenados.
El resultado puede mostrar quantity * unit_price AS line_total aunque la tabla no tenga una columna line_total.
Comparación segura frente a NULL
Una comparación segura frente a NULL proporciona un resultado de comparación concluyente incluso con entradas ausentes y puede tratar dos valores NULL como iguales.
NULL IS NOT DISTINCT FROM NULL es TRUE en PostgreSQL y en SQLite desde la versión 3.39.
Comprobación de una muestra
Una comprobación de una muestra compara las salidas calculadas con resultados obtenidos a mano para unas pocas filas conocidas antes de confiar en el informe completo.
Añadir LIMIT 5 mientras construyes el informe facilita localizar un espacio ausente o un error de división entera.
Concatenación
La concatenación une fragmentos de texto uno a continuación de otro, conservando sus caracteres y requiriendo que se proporcione cualquier separador deseado.
first_name || ' ' || last_name inserta un espacio entre las dos partes del nombre registradas.
Consulta para informes
Una consulta para informes selecciona y presenta datos con un propósito, a menudo combinando importes calculados, etiquetas limpias, fechas y clasificaciones.
Un informe de pedidos puede mostrar un total neto junto a un año y mes de pedido y una etiqueta CASE para la rapidez del envío.
Conversión entre mayúsculas y minúsculas
La conversión entre mayúsculas y minúsculas cambia las letras con funciones como UPPER y LOWER, según las reglas de caracteres de la base de datos.
LOWER(TRIM(email)) uniforma una dirección de correo ASCII limpia para compararla normalizando las mayúsculas y minúsculas.
Conversión explícita
Una conversión explícita es un cambio de tipo solicitado por la consulta, normalmente con CAST, para que la operación prevista quede clara.
La expresión CAST(quantity AS REAL) / 4 cambia el operando de SQLite antes de que la división pueda perder una parte fraccionaria.
Conversión implícita
Una conversión implícita es un cambio de tipo realizado automáticamente por la base de datos al resolver una operación o expresión.
SQLite y PostgreSQL convierten 42 en texto en 'Order #' || 42, produciendo la etiqueta 'Order #42'.

D

DATE
DATE es un tipo de datos para un día del calendario en PostgreSQL y SQL estándar; no tiene componente de hora del día.
DATE '2026-03-14' indica explícitamente el 14 de marzo de 2026 como un valor de fecha de PostgreSQL.
División entera
La división entera divide operandos enteros y elimina la parte fraccionaria hacia cero en SQLite y PostgreSQL.
Una consulta que utiliza 7 / 2 produce 3; convertir el segundo operando en 2.0 conserva la parte fraccionaria y produce 3,5.

E

Edad en años cumplidos
La edad en años cumplidos cuenta los cumpleaños alcanzados hasta una fecha de referencia, por lo que a una diferencia de números de año puede ser necesario restarle un año.
Alguien nacido el 2 de noviembre de 1990 aún tiene 35 años el 21 de octubre de 2026, antes del cumpleaños de ese año.
Etiqueta de año y mes
Una etiqueta de año y mes es una representación textual de un año y un mes que identifica un período del informe sin mezclar años.
La etiqueta '2026-03' mantiene marzo de 2026 separado de marzo de 2025 en la presentación de un informe.
Expresión
Una expresión combina valores, nombres de columnas, operadores o llamadas a funciones para producir un valor que SQL puede utilizar.
En una consulta de pedidos, quantity * unit_price es una expresión que produce el importe de la línea para cada fila.
EXTRACT
EXTRACT es una función de SQL estándar que toma un componente con nombre, como el año o el mes, de un valor de fecha y hora y lo devuelve como número.
EXTRACT(MONTH FROM DATE '2026-03-14') de PostgreSQL devuelve el valor numérico de mes 3.

F

FLOOR
FLOOR es una función numérica que devuelve el mayor entero menor o igual que su entrada, avanzando hacia valores menores.
Para una entrada negativa, FLOOR(-4.1) da -5, por lo que se diferencia de eliminar simplemente la parte fraccionaria.
Formato de fecha ISO
El formato de fecha ISO YYYY-MM-DD coloca el año, el mes y el día de anchura fija en orden de mayor a menor unidad y evita la ambigüedad de los formatos locales.
El texto '2026-03-14' tiene ceros iniciales y se ordena antes de '2026-11-02' en orden cronológico.
Función de una sola fila
Una función de una sola fila devuelve un valor por cada fila de entrada; también se llama función escalar y no agrupa filas.
Utilizar UPPER(city) en SELECT cambia el texto de ciudad mostrado para cada cliente devuelto por la consulta.

I

Indicador numérico
Un indicador numérico es una salida como 1 o 0 que registra si una condición especificada fue verdadera para una fila.
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END asigna cero tanto a los descuentos ausentes como a los no positivos.
INSTR
INSTR es una función de SQLite que devuelve la primera posición de una cadena buscada dentro de un texto, o cero cuando no hay coincidencia.
INSTR('ana@example.com', '@') da 4, mientras que una cadena sin @ produce cero.
Intercalación
Una intercalación proporciona reglas para comparar y ordenar texto, incluido si las letras con distintas mayúsculas y minúsculas se consideran iguales.
La intercalación predeterminada de MySQL, que no distingue mayúsculas y minúsculas, puede hacer que 'Boston' = 'boston' sea verdadero cuando SQLite con su configuración predeterminada no lo hace.
Intervalo
Un intervalo es un valor de PostgreSQL que representa un período de tiempo, como un mes de calendario o la diferencia entre marcas de fecha y hora.
Añadir INTERVAL '1 month' a un DATE de PostgreSQL devuelve una marca de fecha y hora y sigue su regla de final de mes.
Intervalo semiabierto
Un intervalo semiabierto incluye su límite inicial y excluye su límite final, permitiendo que encajen los períodos contiguos de marcas de fecha y hora.
ordered_at >= '2026-03-01' AND ordered_at < '2026-04-01' incluye todas las marcas de fecha y hora de marzo.
IS NULL
IS NULL es una comprobación de ausencia que devuelve TRUE cuando su operando es NULL y FALSE cuando hay un valor presente.
WHERE phone IS NULL recupera clientes sin teléfono registrado sin comparar un valor con NULL mediante igualdad.

L

LENGTH
LENGTH cuenta los caracteres, incluidos los espacios, del texto en SQLite y PostgreSQL; la cadena vacía tiene longitud cero y NULL devuelve NULL.
LENGTH(' Bo ') da 4 porque cuentan tanto los dos espacios de los extremos como las dos letras.
Literal
Un literal es un valor escrito directamente en SQL, como un número o texto entre comillas, en lugar de leerse de una columna.
El espacio de first_name || ' ' || last_name es un literal de texto proporcionado por la consulta.
Lógica trivalente
La lógica trivalente combina TRUE, FALSE y UNKNOWN en las condiciones SQL, por lo que la negación no siempre produce un resultado conocido.
FALSE AND UNKNOWN es FALSE, pero TRUE AND UNKNOWN sigue siendo UNKNOWN porque el segundo requisito no está resuelto.

M

Módulo
El módulo devuelve el resto de la división y se escribe con % en SQLite y PostgreSQL o con MOD en varios dialectos.
Para 135 minutos, 135 % 60 da los 15 minutos que sobran después de dos horas completas.

N

NULL
NULL es un marcador de un valor ausente o desconocido, distinto de cero y, en SQLite y PostgreSQL, de una cadena vacía.
Una bonificación ausente hace que salary + bonus sea desconocido aunque el salario del empleado esté registrado.
NULLIF
NULLIF es una función de SQL estándar que devuelve NULL cuando sus dos argumentos resultan iguales al compararlos y, en caso contrario, devuelve el primer argumento.
NULLIF(visits, 0) conserva los recuentos positivos de visitas, pero convierte el cero en un divisor ausente para una tasa.
Número de coma flotante
Un número de coma flotante es una representación numérica aproximada que puede introducir pequeños errores al almacenar fracciones decimales.
SQLite puede hacer que 0.1 + 0.2 = 0.3 sea falso porque las aproximaciones almacenadas no suman el mismo valor.
Número de día juliano
Un número de día juliano representa una fecha y hora como un recuento numérico de días; restar dos valores mide los días transcurridos.
SQLite utiliza julianday(end_date) - julianday(start_date) en lugar de restar directamente cadenas de fecha ISO.

O

Orden lógico de procesamiento de consultas
El orden lógico de procesamiento de consultas describe cómo las cláusulas construyen un resultado: FROM elige filas, WHERE filtra, SELECT calcula y ORDER BY ordena.
Un alias de salida está disponible para ORDER BY, pero una condición WHERE que deba funcionar en distintas bases de datos repite la expresión calculada que hay detrás de ese alias.

P

Patrón de formato
Un patrón de formato especifica qué componentes de fecha y hora mostrar y cómo organizarlos, mediante símbolos definidos por la base de datos.
SQLite utiliza '%m/%d/%Y' para una etiqueta de fecha estadounidense; TO_CHAR de PostgreSQL utiliza 'MM/DD/YYYY'.
Posición de ordenación personalizada
Una posición de ordenación personalizada asigna posiciones numéricas a valores para que ORDER BY siga una secuencia prevista en lugar del orden alfabético.
Un CASE de prioridad asigna high a 1, medium a 2 y low a 3, y después ordena el resultado de forma ascendente.
Posición de un carácter
La posición de un carácter identifica dónde aparece un carácter en una cadena; las posiciones de texto SQL empiezan en 1 e incluyen los espacios.
El @ de 'ana@example.com' está en la posición 4, por lo que el dominio empieza en la posición 5.
Precedencia de operadores
La precedencia de operadores es la prioridad que determina qué operaciones se realizan primero cuando una expresión no contiene paréntesis que cambien el orden.
SQL multiplica antes de sumar en 10 + 3 * 2, por lo que el resultado es 16 en lugar de 26.

R

Rama WHEN
Una rama WHEN es una opción de condición y resultado en CASE, donde THEN proporciona el valor seleccionado si esa condición es la primera verdadera.
Colocar primero una rama amplia < 200 puede impedir que se seleccione alguna vez una rama posterior < 50.
Relleno
El relleno añade caracteres para alcanzar una anchura de cadena elegida; una operación de relleno de anchura fija también puede recortar un valor demasiado largo.
LPAD('42', 5, '0') de PostgreSQL devuelve '00042', dando cinco caracteres a un código corto.
REPLACE
REPLACE es una función de cadenas que sustituye cada aparición exacta de un fragmento de texto por otro en el valor devuelto.
REPLACE('555-0100', '-', '') elimina el guion y muestra '5550100' sin modificar la tabla.
Resultado alternativo ELSE
Un resultado alternativo ELSE es el resultado de CASE que se utiliza cuando ninguna condición WHEN es TRUE, incluso cuando las condiciones son UNKNOWN.
Un total NULL puede llegar a ELSE 'large' salvo que una rama anterior compruebe explícitamente total IS NULL.
ROUND
ROUND es una función numérica que elige el valor más cercano con la precisión decimal solicitada, con reglas de empate que dependen del tipo.
El informe utiliza ROUND((price - cost) / price * 100, 1) para mostrar un margen con un decimal.

S

strftime
strftime es una función de fecha y hora de SQLite que devuelve texto seleccionado mediante un patrón de formato, incluidos componentes de fecha con ceros iniciales.
strftime('%m', '2026-03-14') devuelve '03', que debe compararse con texto o convertirse antes de un uso numérico.
Subcadena
Una subcadena es un fragmento consecutivo de una cadena, extraído mediante una posición inicial y, cuando hace falta, un número de caracteres.
SUBSTR('Boston', 1, 3) devuelve 'Bos', tomando tres caracteres a partir de la primera posición.

T

Texto numérico
El texto numérico es una cadena que contiene caracteres de un número; su forma textual afecta a la ordenación hasta que se convierte para un uso numérico.
Las cadenas '10', '100' y '9' aparecen en ese orden de texto ascendente, que difiere del orden numérico.
Tiempo Unix
El tiempo Unix mide el tiempo en segundos desde un origen UTC fijo; las diferencias entre tiempos Unix pueden convertirse en horas transcurridas.
SQLite resta dos resultados de unixepoch y divide por 3600.0 para conservar las horas con parte fraccionaria de una duración.
TIMESTAMP
TIMESTAMP contiene una fecha y una hora del día, lo que permite que una consulta distinga instantes dentro del mismo día del calendario.
Un registro en '2026-03-31 14:05:00' es posterior a medianoche al inicio del 31 de marzo.
Tipo de datos
Un tipo de datos describe la clase de valor y ayuda a determinar qué operaciones, conversiones, comparaciones y reglas de ordenación se aplican.
El literal de texto '42' y el entero 42 pueden parecer iguales en una cuadrícula y comportarse de forma distinta en SQL.
TRIM
TRIM es una función de cadenas que elimina de forma predeterminada los espacios de ambos extremos y deja intactos los espacios del interior del texto.
Después de TRIM(' New York '), los dos espacios entre las palabras permanecen en el texto devuelto.

U

UNKNOWN
UNKNOWN es el tercer resultado de una condición SQL, que se produce cuando la falta de información impide una comparación concluyente como verdadera o falsa.
La condición bonus = NULL es UNKNOWN, por lo que no puede identificar una bonificación ausente en un filtro WHERE.
UTC
UTC es la referencia horaria común que SQLite utiliza para CURRENT_DATE y CURRENT_TIMESTAMP, que puede dar una fecha del calendario distinta de la local.
Un informe cerca de medianoche local puede mostrar un día distinto si utiliza CURRENT_DATE de SQLite en lugar de localtime.

V

Valor de sustitución
Un valor de sustitución es el reemplazo elegido cuando faltan los datos preferidos; debe ajustarse tanto al significado como al tipo de la salida.
Un informe puede utilizar cero para una bonificación no pagada y mantener ausente una valoración no registrada en lugar de inventar una puntuación.
Valor límite
Un valor límite se encuentra en un punto de separación entre categorías, por lo que elegir < o <= determina qué categoría lo contiene.
En el límite 50, total < 50 es falso; cambiar la comprobación a total <= 50 hace que sea verdadera.
Valor marcador
Un valor marcador es un valor registrado que representa información ausente, como una cadena vacía, y que puede necesitar convertirse en NULL.
NULLIF(phone, '') convierte una cadena de teléfono vacía en NULL antes de proporcionar una etiqueta de presentación.

Sobre esta unidad

Por StudeliInformar de un error

Crea tus propios Materiales de Estudio

Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.

Comenzar