UD06 · Consultas sobre una tabla y funciones
Resumen del tema
Consultar es la operación más frecuente en cualquier base de datos. En esta unidad aprenderás la sentencia SELECT aplicada a una sola tabla: elegir columnas (proyección), filtrar filas (selección), ordenar, eliminar duplicados, tratar los valores nulos y transformar los datos con las funciones que proporciona Oracle. En la UD07 combinaremos varias tablas y agruparemos resultados.
Todos los ejemplos se ejecutan sobre el esquema de referencia EDUGEST cargado con los scripts del proyecto, y muestran el resultado que debes obtener.
RA3 Consulta la información almacenada en una base de datos empleando asistentes, herramientas gráficas y el lenguaje de manipulación de datos. 2 CE
- RA3.a Se han identificado las herramientas y sentencias para realizar consultas.
- RA3.b Se han realizado consultas simples sobre una tabla.
RA5 Desarrolla procedimientos almacenados evaluando y utilizando las sentencias del lenguaje incorporado en el sistema gestor de bases de datos. 1 CE
- RA5.e Se ha hecho uso de las funciones proporcionadas por el sistema gestor.
Temporalización
La unidad ocupa 23 horas de aula (12 de teoría y 11 de práctica). Es la unidad con más horas del curso: aquí se adquiere la destreza con SELECT que se utilizará hasta el final del módulo.
| Sesión | Horas | Tipo | Contenido | Dónde |
|---|---|---|---|---|
| 1 | 2 | Teoría | Herramientas y sentencia SELECT. Proyección, alias, concatenación y DISTINCT | §1 y §2 |
| 2 | 1 | Práctica | Primeras consultas y herramientas | Práctica 6.1 |
| 3 | 2 | Teoría | Ordenación y selección con WHERE: comparación, LIKE y operadores lógicos | §3 y §4 · laboratorio de SELECT |
| 4 | 3 | Práctica | Consultas para secretaría | Práctica 6.2 |
| 5 | 2 | Teoría | El valor NULL y la lógica de tres valores | §5 · simulador de lógica trivalente |
| 6 | 2 | Práctica | Laboratorio de valores nulos | Práctica 6.3 |
| 7 | 1 | Teoría | Limitar el número de filas | §6 |
| 8 | 3 | Teoría | Funciones de fila (I): texto, numéricas y de fecha | §7.1 a §7.3 |
| 9 | 2 | Teoría | Funciones de fila (II): conversión, CASE, DECODE y expresiones regulares | §7.4 a §7.6 |
| 10 | 3 | Práctica | Funciones para informes | Práctica 6.4 |
| 11 | 1 | Práctica | Validar datos con SQL | Práctica 6.5 |
| 12 | 1 | Práctica | Consultas del día a día en EduGest | Proyecto EduGest-6 |
Las consultas se aprenden escribiéndolas. Antes de ejecutar cada una, predice cuántas filas devolverá y por qué; después compruébalo. Los laboratorios interactivos simulan el comportamiento de Oracle sobre los datos reales de EduGest, pero no sustituyen a un SGBD.
Objetivos de aprendizaje
Al terminar esta unidad serás capaz de:
- Identificar las herramientas y las cláusulas de la sentencia
SELECT. - Seleccionar columnas, calcular expresiones y usar alias.
- Filtrar filas con operadores de comparación, lógicos,
BETWEEN,IN,LIKEeIS NULL. - Ordenar resultados y limitar el número de filas.
- Razonar con la lógica de tres valores que introduce
NULL. - Usar funciones de texto, numéricas, de fecha, de conversión y condicionales de Oracle.
Prepara tu sesión para que las fechas y los números se vean como en estos apuntes. Ejecuta al conectarte:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY'; ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,';El formato de presentación no cambia los datos guardados, solo cómo se muestran.
1. Herramientas y sentencias para consultar
Para consultar una base de datos Oracle puedes usar:
| Herramienta | Uso |
|---|---|
| Hoja de trabajo SQL de SQL Developer o VS Code | Escribir y ejecutar consultas (Ctrl+Intro); el resultado aparece en una rejilla |
| Generador de consultas (Query Builder) de SQL Developer | Construir la consulta arrastrando tablas y marcando columnas; genera el SQL |
| SQLcl / SQL*Plus | Línea de órdenes; ideal para scripts y para guardar evidencias con SPOOL |
| Pestaña Datos de una tabla en SQL Developer | Ver y filtrar el contenido sin escribir SQL |
La sentencia para consultar es SELECT. Su forma general, con todas las cláusulas que verás en esta unidad y en la siguiente, es:
SELECT [DISTINCT] columnas o expresiones -- 5. qué columnas
FROM tabla(s) -- 1. de dónde
WHERE condición sobre las filas -- 2. qué filas
GROUP BY columnas de agrupación -- 3. cómo agrupar (UD07)
HAVING condición sobre los grupos -- 4. qué grupos (UD07)
ORDER BY criterios de ordenación -- 6. en qué orden
FETCH FIRST n ROWS ONLY; -- 7. cuántas filasEl orden en que se escribe una consulta no es el orden en que se evalúa. El SGBD procesa primero
FROM, despuésWHERE,GROUP BY,HAVING,SELECTy finalmenteORDER BY. Por eso un alias definido en elSELECTse puede usar enORDER BYpero no enWHERE.
2. Proyección: elegir columnas
2.1 Todas las columnas o solo algunas
SELECT * FROM ciclo;| COD_CICLO | NOMBRE | GRADO | HORAS_TOTALES |
|---|---|---|---|
| DAM | Desarrollo de Aplicaciones Multiplataforma | SUPERIOR | 2000 |
| DAW | Desarrollo de Aplicaciones Web | SUPERIOR | 2000 |
| ASIR | Administración de Sistemas Informáticos en Red | SUPERIOR | 2000 |
| SMR | Sistemas Microinformáticos y Redes | MEDIO | 2000 |
4 filas
* es útil para explorar, pero en una aplicación o un informe escribe siempre las columnas que necesitas: el resultado es más claro, transfiere menos datos y no cambia si alguien añade una columna a la tabla.
SELECT codigo, nombre, horas
FROM modulo
WHERE cod_ciclo = 'DAM';2.2 Expresiones y alias
En el SELECT se pueden calcular expresiones. Un alias da nombre a la columna resultante; si contiene espacios o mayúsculas, va entre comillas dobles.
SELECT codigo,
nombre,
horas,
horas / 32 AS horas_semana,
ROUND(horas / 32, 1) AS "Horas/semana"
FROM modulo
WHERE cod_ciclo = 'DAW' AND curso = 2;| CODIGO | NOMBRE | HORAS | HORAS_SEMANA | Horas/semana |
|---|---|---|---|---|
| 0612 | Desarrollo web en entorno cliente | 140 | 4.375 | 4.4 |
| 0613 | Desarrollo web en entorno servidor | 160 | 5 | 5 |
| 0614 | Despliegue de aplicaciones web | 80 | 2.5 | 2.5 |
| 0615 | Diseño de interfaces web | 120 | 3.75 | 3.8 |
4 filas
2.3 Concatenación
El operador || une cadenas:
SELECT apellidos || ', ' || nombre AS alumno, localidad
FROM alumno
WHERE cod_grupo = '2DAW'
ORDER BY alumno;| ALUMNO | LOCALIDAD |
|---|---|
| Amorós Guillem, Sara | Mutxamel |
| Carbonell Soriano, Elena | El Campello |
| Planelles Marco, Sofía | Elche |
| Sala Brotons, Mateo | Alicante |
| Verdú Castelló, Nicolás | Alicante |
5 filas
2.4 Eliminar duplicados con DISTINCT
SELECT DISTINCT localidad FROM alumno ORDER BY localidad;| LOCALIDAD |
|---|
| Alicante |
| El Campello |
| Elche |
| Mutxamel |
| San Vicente del Raspeig |
| Sant Joan d’Alacant |
6 filas
DISTINCT se aplica a la fila completa del resultado: SELECT DISTINCT localidad, cod_grupo devuelve las combinaciones distintas de las dos columnas.
Curiosidad La tabla DUAL tiene un nombre por una razón
Según su creador, Chuck Weiss, DUAL se diseñó al principio con dos filas, para poder duplicar filas con un join. Hoy tiene una sola, pero conserva el nombre: sirve para evaluar expresiones, como SELECT SYSDATE FROM DUAL.
2.5 La tabla DUAL
DUAL es una tabla especial de Oracle con una sola fila. Sirve para evaluar expresiones que no dependen de ninguna tabla:
SELECT SYSDATE, 7 * 24 AS horas_semana, UPPER('edugest') FROM dual;Desde Oracle 23ai la cláusula
FROMes opcional en estos casos:SELECT SYSDATE;también funciona. En versiones anteriores (y en el examen, si usas 19c) escribeFROM dual.
3. Ordenación: ORDER BY
SELECT codigo, nombre, cod_ciclo, horas
FROM modulo
WHERE horas > 150
ORDER BY horas DESC, codigo;| CODIGO | NOMBRE | COD_CICLO | HORAS |
|---|---|---|---|
| 0485 | Programación | DAM | 256 |
| 0485 | Programación | DAW | 256 |
| 0369 | Implantación de sistemas operativos | ASIR | 224 |
| 0370 | Planificación y administración de redes | ASIR | 192 |
| 0372 | Gestión de bases de datos | ASIR | 160 |
| 0483 | Sistemas informáticos | DAM | 160 |
| 0483 | Sistemas informáticos | DAW | 160 |
| 0484 | Bases de datos | DAM | 160 |
| 0484 | Bases de datos | DAW | 160 |
| 0613 | Desarrollo web en entorno servidor | DAW | 160 |
10 filas
ASC(por defecto) ordena de menor a mayor yDESCde mayor a menor.- Con varias columnas, la segunda solo decide cuando hay empate en la primera.
- Se puede ordenar por un alias o por una expresión.
- En Oracle, los
NULLvan al final en orden ascendente y al principio en descendente. Puedes cambiarlo conNULLS FIRSToNULLS LAST.
Sin
ORDER BY, el orden de las filas no está garantizado. Aunque hoy salgan ordenadas por la clave primaria, mañana pueden salir en otro orden.Además, la ordenación de textos con tildes depende del parámetro de sesión
NLS_SORT. Con el valor por defecto (BINARY), «Álex» se ordena después de «Zoe». ConALTER SESSION SET NLS_SORT = SPANISH;se ordena como en un diccionario. Si tus resultados aparecen en otro orden que en los apuntes, revisa este parámetro.
1. FROM
Primero decide de dónde salen las filas: FROM alumno. Por eso el alias de una columna definido en el SELECT no se puede usar todavía.
2. WHERE
Descarta las filas que no cumplen la condición: WHERE nota >= 5. Aquí solo existen las columnas de la tabla.
3. SELECT
Calcula las expresiones y los alias de las columnas que se muestran: SELECT nombre, nota * 10 AS sobre_100.
4. ORDER BY
Ordena el resultado. Es la única cláusula que puede usar los alias del SELECT.
5. Límite de filas
Por último se recorta con FETCH FIRST n ROWS ONLY. En la UD07 se añadirán GROUP BY y HAVING entre el WHERE y el SELECT.
4. Selección: filtrar filas con WHERE
4.1 Operadores de comparación
| Operador | Significado | Ejemplo |
|---|---|---|
= | Igual | cod_grupo = '1DAM' |
<> o != | Distinto | turno <> 'M' |
<, >, <=, >= | Menor, mayor… | nota_final >= 5 |
BETWEEN a AND b | Entre a y b, ambos incluidos | horas BETWEEN 100 AND 160 |
IN (lista) | Igual a alguno de la lista | cod_ciclo IN ('DAM', 'DAW') |
LIKE patrón | Coincide con un patrón | apellidos LIKE 'B%' |
IS NULL / IS NOT NULL | Es (o no es) nulo | cod_grupo IS NULL |
SELECT nombre, apellidos, localidad
FROM alumno
WHERE localidad = 'Mutxamel'
ORDER BY apellidos;| NOMBRE | APELLIDOS | LOCALIDAD |
|---|---|---|
| Martina | Alemany Vidal | Mutxamel |
| Sara | Amorós Guillem | Mutxamel |
| Irene | Belda Iborra | Mutxamel |
| Hugo | Brotons Iborra | Mutxamel |
| Álex | Tomás Vidal | Mutxamel |
| Alba | Torregrosa Planelles | Mutxamel |
6 filas
Las comparaciones de texto distinguen mayúsculas y minúsculas:
localidad = 'mutxamel'no devuelve nada. Para comparar sin distinguirlas usaUPPER(localidad) = 'MUTXAMEL'.
4.2 Patrones con LIKE
| Comodín | Significado | Ejemplo | Coincide con |
|---|---|---|---|
% | Cualquier secuencia de caracteres (incluso vacía) | 'B%' | Belda, Brotons |
_ | Exactamente un carácter | '_DAM' | 1DAM, 2DAM |
SELECT nombre, apellidos
FROM alumno
WHERE apellidos LIKE 'B%'
ORDER BY apellidos;| NOMBRE | APELLIDOS |
|---|---|
| Irene | Belda Iborra |
| Lucía | Belda Quiles |
| Hugo | Brotons Iborra |
| Andrea | Brotons Soriano |
4 filas
Para buscar un % o un _ literales se usa ESCAPE: email LIKE '%\_%' ESCAPE '\' busca correos que contengan un guion bajo.
4.3 Operadores lógicos y precedencia
NOT se evalúa antes que AND, y AND antes que OR. Usa paréntesis siempre que mezcles AND y OR.
-- Matrículas suspendidas de los módulos 2 u 8
SELECT id_matricula, id_alumno, nota_final
FROM matricula
WHERE nota_final < 5
AND id_modulo IN (2, 8)
ORDER BY id_matricula;| ID_MATRICULA | ID_ALUMNO | NOTA_FINAL |
|---|---|---|
| 10002 | 1 | 4.75 |
| 10007 | 2 | 4.75 |
| 10038 | 8 | 4 |
3 filas
¿Qué devolvería WHERE nota_final < 5 AND id_modulo = 2 OR id_modulo = 8?
Por la precedencia, se evalúa como (nota_final < 5 AND id_modulo = 2) OR id_modulo = 8: devolvería los suspensos del módulo 2 y todas las matrículas del módulo 8, aprobadas o no. Por eso hay que poner paréntesis, o usar IN.
Laboratorio de SELECT
Construye una consulta sobre la tabla ALUMNO eligiendo columnas, condiciones y orden. Compara el resultado con el que predijiste.
1 · SELECT (columnas)
2 · WHERE (hasta tres condiciones)
3 · ORDER BY y FETCH FIRST
WHERE a OR b AND cno se evalúa de izquierda a derecha:ANDtiene mayor precedencia queOR. Usa paréntesis siempre que mezcles ambos.
Curiosidad NULL no es cero ni «vacío»
NULL significa «valor desconocido». Por eso NULL = NULL no es verdadero, sino desconocido, y por eso SQL usa una lógica de tres valores: verdadero, falso y desconocido.
5. El valor NULL
NULL significa «valor desconocido o no aplicable». No es un cero ni una cadena vacía: es la ausencia de valor.
5.1 Lógica de tres valores
Cualquier comparación con NULL da como resultado desconocido (UNKNOWN), y WHERE solo devuelve las filas cuya condición es verdadera.
| A | B | A AND B | A OR B | NOT A |
|---|---|---|---|---|
| V | V | V | V | F |
| V | F | F | V | F |
| V | ? | ? | V | F |
| F | ? | F | ? | V |
| ? | ? | ? | ? | ? |
Consecuencias prácticas:
SELECT COUNT(*) FROM alumno WHERE cod_grupo = NULL; -- 0 filas: ¡siempre!
SELECT COUNT(*) FROM alumno WHERE cod_grupo IS NULL; -- 3 filas
SELECT COUNT(*) FROM alumno WHERE cod_grupo <> '1DAM'; -- 22: los 3 sin grupo NO salenSELECT nia, nombre, apellidos
FROM alumno
WHERE cod_grupo IS NULL;| NIA | NOMBRE | APELLIDOS |
|---|---|---|
| 10451110 | Zoe | Iborra Valero |
| 10451147 | Lucas | Agulló Cerdá |
| 10451184 | Irene | Belda Iborra |
3 filas
Simulador de lógica de tres valores
Combina TRUE, FALSE y UNKNOWN con AND, OR y NOT, y comprueba qué filas conserva WHERE.
A · Tablas de verdad
B · ¿Qué filas deja pasar WHERE?
5.2 Funciones para tratar los nulos
| Función | Devuelve | Ejemplo |
|---|---|---|
NVL(expr, valor) | valor si expr es nulo; si no, expr | NVL(email, '(sin correo)') |
NVL2(expr, si_no_nulo, si_nulo) | Un valor u otro según expr sea nulo | NVL2(id_tutor, 'Con tutor', 'Sin tutor') |
COALESCE(e1, e2, ...) | El primer valor no nulo (estándar SQL) | COALESCE(email, telefono, 'sin contacto') |
NULLIF(a, b) | NULL si a = b; si no, a | NULLIF(horas, 0) evita dividir por cero |
SELECT id_alumno, nombre, NVL(email, '(sin correo)') AS email
FROM alumno
WHERE email IS NULL OR telefono IS NULL
ORDER BY id_alumno;| ID_ALUMNO | NOMBRE | |
|---|---|---|
| 4 | Paula | paulaferri4@alu.edugest.es |
| 8 | Iván | (sin correo) |
| 10 | Nerea | nereacerda10@alu.edugest.es |
| 16 | Julia | juliaespi16@alu.edugest.es |
| 19 | Alba | (sin correo) |
| 22 | Sofía | sofiaplanelles22@alu.edugest.es |
| 28 | Pablo | pabloamoros28@alu.edugest.es |
| 30 | Zoe | (sin correo) |
8 filas
Cualquier operación aritmética con
NULLdaNULL:nota_final + 1esNULLsi no hay nota. Y en Oracle,''esNULL. Compruébalo conSELECT NVL('', 'era nulo') FROM dual;.
6. Limitar el número de filas
-- Las cinco mejores notas (con desempate por id_matricula)
SELECT id_matricula, id_alumno, id_modulo, nota_final
FROM matricula
WHERE nota_final IS NOT NULL
ORDER BY nota_final DESC, id_matricula
FETCH FIRST 5 ROWS ONLY;| ID_MATRICULA | ID_ALUMNO | ID_MODULO | NOTA_FINAL |
|---|---|---|---|
| 10143 | 29 | 24 | 10 |
| 10045 | 9 | 10 | 9.75 |
| 10132 | 27 | 23 | 9.75 |
| 10020 | 4 | 5 | 9.5 |
| 10048 | 10 | 8 | 9.25 |
5 filas
| Variante | Efecto |
|---|---|
FETCH FIRST 5 ROWS ONLY | Las 5 primeras filas |
FETCH FIRST 5 ROWS WITH TIES | Las 5 primeras y las empatadas con la quinta |
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY | Filas 11 a 20 (paginación) |
FETCH FIRST 10 PERCENT ROWS ONLY | El 10 % de las filas |
FETCH FIRSTes SQL estándar y está en Oracle desde la versión 12c. En código antiguo verás la pseudocolumnaROWNUM(WHERE ROWNUM <= 5), que se evalúa antes delORDER BYy produce errores si no se usa con una subconsulta. MySQL y PostgreSQL usanLIMIT 5.
7. Funciones de fila
Las funciones de fila se aplican a cada fila y devuelven un valor por fila. Forman parte de las funciones que proporciona el sistema gestor (RA5.e). Las funciones de grupo (COUNT, SUM, AVG…), que resumen varias filas, se estudian en la UD07.
7.1 Funciones de texto
| Función | Resultado de ejemplo |
|---|---|
UPPER('Bases de Datos') / LOWER(...) | BASES DE DATOS / bases de datos |
INITCAP('marta soler') | Marta Soler |
LENGTH('Oracle') | 6 |
SUBSTR('10450037', 1, 4) | 1045 (desde la posición 1, 4 caracteres) |
INSTR('msoler@edugest.es', '@') | 7 (posición de la primera @) |
TRIM(' hola '), LTRIM, RTRIM | hola |
LPAD('7', 3, '0') / RPAD('7', 3, '*') | 007 / 7** |
REPLACE('1DAM', 'DAM', 'DAW') | 1DAW |
CONCAT('a', 'b') | ab (solo dos argumentos; mejor ||) |
-- Usuario del correo del profesorado (lo que va antes de la @)
SELECT nombre, email, SUBSTR(email, 1, INSTR(email, '@') - 1) AS usuario
FROM profesor
WHERE id_departamento = 2;| NOMBRE | USUARIO | |
|---|---|---|
| Carmen | cortiz@edugest.es | cortiz |
| Sergio | sramos@edugest.es | sramos |
SELECT UPPER(apellidos) || ', ' || nombre AS alumno, LENGTH(nombre) AS letras
FROM alumno
WHERE cod_grupo = '1ASIR'
ORDER BY apellidos;| ALUMNO | LETRAS |
|---|---|
| AMORÓS CARBONELL, Pablo | 5 |
| IBORRA TORREGROSA, Diego | 5 |
| PASCUAL BROTONS, Aitana | 6 |
| TOMÁS GUILLEM, Víctor | 6 |
| TOMÁS VIDAL, Álex | 4 |
7.2 Funciones numéricas
| Función | Resultado |
|---|---|
ROUND(7.256, 2) / ROUND(7.5) | 7.26 / 8 |
TRUNC(7.256, 1) / TRUNC(7.9) | 7.2 / 7 |
CEIL(4.1) / FLOOR(4.9) | 5 / 4 |
MOD(17, 5) | 2 (resto) |
ABS(-3), POWER(2, 10), SQRT(81) | 3, 1024, 9 |
-- Notas redondeadas al entero, como aparecen en el boletín
SELECT id_matricula, nota_final, ROUND(nota_final) AS nota_boletin, TRUNC(nota_final) AS nota_truncada
FROM matricula
WHERE id_alumno = 1
ORDER BY id_matricula;| ID_MATRICULA | NOTA_FINAL | NOTA_BOLETIN | NOTA_TRUNCADA |
|---|---|---|---|
| 10001 | 8.75 | 9 | 8 |
| 10002 | 4.75 | 5 | 4 |
| 10003 | 7.25 | 7 | 7 |
| 10004 | 4.75 | 5 | 4 |
| 10005 | 6.75 | 7 | 6 |
Fíjate en la matrícula 10002: con
ROUND, un 4,75 aparece como 5 en el boletín, pero el módulo está suspendido. Las decisiones (aprobar o no) se toman siempre sobre el valor real, nunca sobre el valor formateado.
7.3 Funciones de fecha
En Oracle, restar dos fechas da el número de días entre ellas, y sumar un número a una fecha añade días.
| Función | Resultado |
|---|---|
SYSDATE / SYSTIMESTAMP | Fecha y hora actuales del servidor |
ADD_MONTHS(DATE '2026-01-31', 1) | 28/02/2026 |
MONTHS_BETWEEN(fecha1, fecha2) | Meses entre dos fechas (con decimales) |
EXTRACT(YEAR FROM fecha) | El año (también MONTH, DAY) |
TRUNC(SYSDATE) | La fecha de hoy a las 00:00:00 |
LAST_DAY(DATE '2026-02-10') | 28/02/2026 |
NEXT_DAY(DATE '2026-10-06', 'LUNES') | El lunes siguiente (el nombre depende del idioma de la sesión) |
-- Edad del alumnado de 2DAW a fecha 6 de octubre de 2026
SELECT id_alumno, nombre, fecha_nacimiento,
TRUNC(MONTHS_BETWEEN(DATE '2026-10-06', fecha_nacimiento) / 12) AS edad
FROM alumno
WHERE cod_grupo = '2DAW'
ORDER BY fecha_nacimiento;| ID_ALUMNO | NOMBRE | FECHA_NACIMIENTO | EDAD |
|---|---|---|---|
| 23 | Sara | 07/08/2000 | 26 |
| 20 | Mateo | 09/04/2003 | 23 |
| 22 | Sofía | 13/07/2004 | 22 |
| 24 | Nicolás | 11/05/2005 | 21 |
| 21 | Elena | 21/06/2005 | 21 |
En una aplicación real se usaría
SYSDATEen lugar deDATE '2026-10-06'. Aquí se fija la fecha para que el resultado no cambie según el día en que ejecutes la consulta. Los literales de fechaDATE 'AAAA-MM-DD'son SQL estándar y no dependen de la configuración de la sesión: úsalos siempre en lugar de cadenas como'15/09/2025'.
Comparar fechas que tienen hora. Como DATE guarda la hora, para buscar «lo del día 15» compara con un intervalo semiabierto:
SELECT * FROM matricula
WHERE fecha_matricula >= DATE '2025-09-15'
AND fecha_matricula < DATE '2025-09-16';7.4 Funciones de conversión
| Función | Uso | Ejemplo | Resultado |
|---|---|---|---|
TO_CHAR(fecha, formato) | Fecha → texto | TO_CHAR(DATE '2026-10-06', 'DD/MM/YYYY') | 06/10/2026 |
TO_CHAR(DATE '2026-10-06', 'fmDay, DD "de" Month', 'NLS_DATE_LANGUAGE=SPANISH') | Martes, 6 de Octubre | ||
TO_CHAR(número, formato) | Número → texto | TO_CHAR(1520.5, '9G990D00') | 1,520.50 (según NLS) |
TO_DATE(texto, formato) | Texto → fecha | TO_DATE('15/09/2025', 'DD/MM/YYYY') | fecha |
TO_NUMBER(texto) | Texto → número | TO_NUMBER('42') | 42 |
Elementos de formato de fecha más usados: DD (día), MM (mes), MON/MONTH (nombre del mes), YYYY (año), HH24 (hora), MI (minutos), SS (segundos), D (día de la semana), Q (trimestre).
SELECT nombre, apellidos,
TO_CHAR(fecha_alta, 'DD/MM/YYYY') AS alta,
EXTRACT(YEAR FROM DATE '2026-10-06') - EXTRACT(YEAR FROM fecha_alta) AS cursos_aprox
FROM profesor
WHERE fecha_alta < DATE '2015-01-01'
ORDER BY fecha_alta;| NOMBRE | APELLIDOS | ALTA | CURSOS_APROX |
|---|---|---|---|
| Marta | Soler Ivars | 01/09/2009 | 17 |
| Carmen | Ortiz Llorca | 01/09/2010 | 16 |
| Javier | Pastor Gil | 01/09/2012 | 14 |
Evita las conversiones implícitas:
WHERE fecha_alta < '01/01/2015'funciona o falla según elNLS_DATE_FORMATde cada sesión, yWHERE nia = 10450037(sin comillas) obliga a Oracle a convertir todas las filas de la columna, lo que impide usar su índice.
7.5 Funciones condicionales: CASE y DECODE
CASE es estándar SQL y permite elegir un valor según condiciones.
SELECT id_matricula, id_modulo, nota_final,
CASE
WHEN nota_final IS NULL THEN 'Sin calificar'
WHEN nota_final < 5 THEN 'Insuficiente'
WHEN nota_final < 6 THEN 'Suficiente'
WHEN nota_final < 7 THEN 'Bien'
WHEN nota_final < 9 THEN 'Notable'
ELSE 'Sobresaliente'
END AS calificacion
FROM matricula
WHERE id_alumno = 1
ORDER BY id_modulo;| ID_MATRICULA | ID_MODULO | NOTA_FINAL | CALIFICACION |
|---|---|---|---|
| 10001 | 1 | 8.75 | Notable |
| 10002 | 2 | 4.75 | Insuficiente |
| 10003 | 3 | 7.25 | Notable |
| 10004 | 4 | 4.75 | Insuficiente |
| 10005 | 5 | 6.75 | Bien |
5 filas
Las condiciones se evalúan en orden y se usa la primera que se cumple. Por eso basta con nota_final < 6 en la segunda rama: si fuera menor que 5, ya se habría quedado en la primera.
CASE simple (compara una expresión con valores) y su equivalente propio de Oracle, DECODE:
SELECT cod_grupo,
CASE turno WHEN 'M' THEN 'Mañana' WHEN 'T' THEN 'Tarde' END AS turno,
DECODE(turno, 'M', 'Mañana', 'T', 'Tarde', 'Desconocido') AS turno_decode
FROM grupo
ORDER BY cod_grupo;| COD_GRUPO | TURNO | TURNO_DECODE |
|---|---|---|
| 1ASIR | Mañana | Mañana |
| 1DAM | Mañana | Mañana |
| 1DAW | Tarde | Tarde |
| 2ASIR | Mañana | Mañana |
| 2DAM | Mañana | Mañana |
| 2DAW | Tarde | Tarde |
6 filas
7.6 Expresiones regulares
Oracle incluye funciones de expresiones regulares para búsquedas más potentes que LIKE: REGEXP_LIKE, REGEXP_SUBSTR, REGEXP_REPLACE, REGEXP_INSTR, REGEXP_COUNT.
-- Profesorado con DNI que empieza por 2 y termina en C o E
SELECT nombre, dni FROM profesor WHERE REGEXP_LIKE(dni, '^2[0-9]{7}[CE]$') ORDER BY nombre;| NOMBRE | DNI |
|---|---|
| Carmen | 21369874E |
| Marta | 21456789C |
8. Errores frecuentes
| Error | Ejemplo | Corrección |
|---|---|---|
Comparar con = NULL | WHERE email = NULL | WHERE email IS NULL |
Usar un alias del SELECT en el WHERE | WHERE edad > 20 | Repite la expresión o usa una subconsulta (UD07) |
| Comillas dobles para textos | WHERE turno = "M" | Los textos van entre comillas simples; las dobles son para identificadores (ORA-00904) |
Olvidar paréntesis al mezclar AND y OR | a AND b OR c | a AND (b OR c) |
Confiar en el orden sin ORDER BY | — | Ordena siempre que el orden importe |
| Comparar fechas con texto | fecha > '01/09/2025' | fecha > DATE '2025-09-01' |
BETWEEN con fechas con hora | BETWEEN DATE '2025-09-15' AND DATE '2025-09-15' | Intervalo semiabierto >= y < |
9. Buenas prácticas
- Escribe las palabras reservadas en mayúsculas y alinea las cláusulas: la consulta se lee mejor.
- Nombra explícitamente las columnas; usa
*solo para explorar. - Usa alias claros para las expresiones calculadas.
- Usa literales
DATE 'AAAA-MM-DD'y evita las conversiones implícitas. - Comenta las consultas que entregues: qué pregunta responden y qué decisiones has tomado.
10. Resumen
SELECTelige columnas (proyección),WHEREfiltra filas (selección) yORDER BYordena.- El SGBD evalúa
FROM→WHERE→SELECT→ORDER BY. NULLintroduce una lógica de tres valores: se compara conIS NULLy se trata conNVL,COALESCEoNVL2.FETCH FIRST n ROWS ONLYlimita el número de filas.- Oracle proporciona funciones de texto, numéricas, de fecha, de conversión y condicionales (
CASE,DECODE).