0% encontró este documento útil (0 votos)
5 vistas17 páginas

05 - Consultas SQL

El documento proporciona una guía sobre la preparación del entorno y el uso del lenguaje SQL para gestionar bases de datos, incluyendo la conexión a la base de datos y la ejecución de consultas. Se detalla el uso de DQL para la consulta de datos, la selección de registros, y se explican conceptos como operadores, filtrado de datos y la vinculación de tablas mediante JOIN. Además, se abordan técnicas para mejorar la legibilidad de las consultas y el tratamiento de valores nulos.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
5 vistas17 páginas

05 - Consultas SQL

El documento proporciona una guía sobre la preparación del entorno y el uso del lenguaje SQL para gestionar bases de datos, incluyendo la conexión a la base de datos y la ejecución de consultas. Se detalla el uso de DQL para la consulta de datos, la selección de registros, y se explican conceptos como operadores, filtrado de datos y la vinculación de tablas mediante JOIN. Además, se abordan técnicas para mejorar la legibilidad de las consultas y el tratamiento de valores nulos.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

1.

PREPARACIÓN DEL ENTORNO


psql -d template1 -f tablas_ett.sql : para iniciar la base de datos:
-d (database) : especifica la base de datos para conectar.
-f (archivo) : para ejecutar el contenido de un archivo.
-U (usuario) : si se necesita conectar como un usuario distinto al del sistema.
psql ett : conectar a la base de datos.
\d : listar los objetos.
\d (tabla) : consultar la estructura de las tablas.

01- SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN


02- DISEÑO DE BASES DE DATOS
03- SISTEMAS GESTORES DE BASES DE DATOS
04- DISEÑO FÍSICO DE BASES DE DATOS
06- EDICIÓN DE LOS DATOS
07- PROGRAMACIÓN CON BASES DE DATOS
208- RELACIONALES

2. DQL
El lenguaje SQL se utiliza para organizar, almacenar y administrar datos dentro de un sistema gestor de bases de datos
relacional, permitiendo su posterior procesamiento y conversión en información útil. En este contexto, es importante distinguir
entre datos e información: los datos son elementos almacenables y estructurados, mientras que la información es el resultado
del análisis y procesamiento de esos datos.

Por ejemplo, una base de datos con 2.700 alumnos contiene datos, pero un listado con los 30 que cursan ASIR representa
información. La inserción de datos puede hacerse manualmente, mediante formularios o de forma automatizada usando
procesos ETL (Extract, Transform and Load).

Inicialmente, el lenguaje SQL se dividía en tres categorías: DDL, DML y DCL. Hoy en día, se reconocen cinco:
Consulta de datos (DQL).
Definición de datos (DDL).
Manipulación de datos (DML).
Control de transacciones (TCL).
Control de datos (DCL).

Entre todas, destaca DQL, centrada en la consulta de datos. En particular, la sentencia SELECT es la más esencial y
poderosa dentro del lenguaje SQL, siendo básica pero también capaz de alcanzar una gran complejidad.

2.1. Selección de registros

SELECT : es fundamental en SQL. Permite recuperar y mostrar información de la base de datos, pudiendo incluir
agrupaciones, ordenamientos, condiciones, entre otros.

SQL

1 SELECT [DISTINCT] {*, campo [alias],...}


2 FROM tabla/s
3 WHERE condiciones
4 GROUP BY campo_agrupacion
5 HAVING condicion_funcion_grupo
6 ORDER BY campo1 [ASC|DESC]
7 LIMIT número_filas;
8

Las sentencias finalizan con ; .


Los corchetes indican partes opcionales.
Cada parte se llama cláusula. Las cláusulas SELECT y FROM son obligatorias, las demás son opcionales según el tipo de
consulta que se quiera realizar.
SELECT : define los campos a mostrar (proyección).
FROM : define la tabla o tablas de origen. Debe al menos haber una tabla enumerada en esta cláusula.

2.1.1. Primera consulta

Después de visualizar las tablas disponibles en el sistema, podemos comenzar a realizar operaciones sobre ellas. Por
defecto, los resultados de las consultas se muestran en formato de filas. Sin embargo, si hay muchos campos o son
demasiado largos, la visualización puede resultar confusa. Para mejorar la legibilidad, se puede usar el comando \x , que
activa el modo expandido y permite mostrar los datos de forma más clara, uno por línea.

2.1.2. Selección específica de campos

Para mostrar campos específicos en una consulta SQL, simplemente se indican los nombres de los campos separados por
comas en la cláusula SELECT .

SQL

1 SELECT nombre, apellidos, titulacion


2 FROM persona;

Este tipo de consulta permite visualizar únicamente las columnas deseadas, facilitando la lectura y análisis de la información.
Además, puede combinarse con el comando \x para mejorar la presentación cuando los valores son extensos.

2.1.3. Etiquetas de los campos

Una consulta SQL devuelve un encabezado (nombres de los campos) y un cuerpo (filas de resultados).
La alineación de los datos varía según el tipo:
Fechas, cadenas y booleanos: alineados a la izquierda.
Datos numéricos: alineados a la derecha.
Por defecto, los nombres de los campos se muestran en minúsculas.
Para cambiar la etiqueta de un campo, se usa un alias.

2.1.4. Alias de los campos

Se define un alias para cambiar el nombre de la columna al mostrar los resultados.


Se puede usar la palabra clave AS (opcional).
Se recomienda usar comillas dobles para respetar mayúsculas, caracteres especiales o espacios.
Si no se pone alias, la columna puede aparecer como ?column? .

Ejemplo sin redondeo:

SQL

1 SELECT dni, salario, (salario * 1.15) "Salario aumentado"


2 FROM contrato;

Ejemplo con redondeo (función ROUND ):

SQL

1 SELECT dni, salario, ROUND(salario * 1.15, 2) "Salario aumentado"


2 FROM contrato;

ROUND(expresión, número_de_decimales) : permite controlar los decimales mostrados.

2.1.5. Operadores unarios y binarios

Operadores unarios, requieren un solo operando:


NOT : negación lógica.
- : cambio de signo.
Operadores binarios, requieren dos operandos:
Aritméticos: + , - , * , / , % .
Relacionales: = , != , > , < , >= , <= .
Lógicos: AND , OR .
Otros: JOIN .
Los operandos pueden ser:
Campos: columnas de una tabla.
Escalares: valores literales simples.

2.1.6. Expresiones aritméticas

Se usan con campos numéricos o de tipo fecha.


Operadores disponibles:
+ : suma.
- : resta.
* : multiplicación.
/ : división.
% : módulo o resto.

SQL

1 SELECT dni, fechaAlta Alta, fechaBaja Baja, fechaBaja - fechaAlta Días


2 FROM contrato;

Si usamos una función o una expresión, la etiqueta por defecto será genérica (como ?column? o el nombre de la función).

Ejemplo usando la función INITCAP :

SQL

1 SELECT nombre, apellidos, INITCAP(nivelTitulacion)


2 FROM persona;

Para renombrar la etiqueta se usa un alias. El alias se puede poner sin comillas si no contiene espacios ni caracteres
especiales:

SQL

1 SELECT nombre, apellidos, INITCAP(nivelTitulacion) nivel


2 FROM persona;

2.1.7. Precedencia de operadores

Multiplicación ( * ) y división ( / ) tienen mayor prioridad que suma ( + ) y resta ( - ).


Los operadores con la misma prioridad se evalúan de izquierda a derecha.
Los paréntesis pueden modificar el orden de evaluación y mejoran la legibilidad.

SQL
1 SELECT a + b * c FROM tabla; -- primero se multiplica, luego se suma
2 SELECT (a + b) * c FROM tabla; -- primero se suma, luego se multiplica

2.1.8. Filas duplicadas

DISTINCT : para eliminar filas duplicadas:

SQL

1 SELECT DISTINCT(tipoContrato) FROM contrato;

No distingue mayúsculas/minúsculas, así que para normalizar, se usa:

SQL

1 SELECT DISTINCT(INITCAP(tipoContrato)) "Tipos" FROM contrato;

Funciones útiles para normalizar texto:


LOWER() : convierte a minúsculas.
UPPER() : convierte a mayúsculas.
INITCAP() : pone la primera letra en mayúscula.

2.1.9. Filtrado de contenido de los datos

WHERE : para filtrar registros según condiciones.

SQL

1 SELECT nombre, apellidos


2 FROM persona
3 WHERE LOWER(nombre) = 'ariadna';

2.1.10. Operadores relacionales

Permiten construir condiciones de comparación en WHERE :

Operador Significado
= Igual que
> Mayor que
>= Mayor o igual que
< Menor que
<= Menor o igual que
<> / != Diferente de

2.1.11. Operadores lógicos

Se usan para combinar varias condiciones:

Operador Significado Tipo


AND Y Binario
OR O Binario
NOT No Unario

SQL
1 -- Jornada completa e indefinido
2 SELECT dni, jornada, tipoContrato
3 FROM contrato
4 WHERE jornada = 40 AND LOWER(tipoContrato) = 'indefinido';
5
6 -- Jornada completa o salario mayor a 30.000
7 SELECT dni, salario, jornada
8 FROM contrato
9 WHERE jornada = 40 OR salario > 30000;

2.1.12. Tratamiento de valores nulos

¿Qué es un NULL ?:
Representa ausencia de valor.
No es ni un 0 ni un espacio en blanco.
Si se opera con un NULL , el resultado será siempre NULL .
No se puede comparar con operadores normales ( = , != , etc.).

COALESCE() : permite transformar valores NULL , pero ambos argumentos deben ser del mismo tipo.

Este ejemplo muestra Trabajando si fechaBaja está vacía. Se hace un casting con ::text para convertir el campo
fechaBaja (de tipo fecha) en texto.

SQL

1 SELECT dni,
2 fechaAlta AS alta,
3 COALESCE(fechaBaja::text, 'Trabajando') AS baja
4 FROM contrato;

IS NULL : para obtener filas donde el campo no tiene valor.

IS NOT NULL : para obtener filas donde el campo sí tiene valor.

SQL

1 SELECT dni, fechaAlta, fechaBaja


2 FROM contrato
3 WHERE fechaBaja IS NULL;

En resumen: los valores NULL no se operan directamente, sino que se transforman con COALESCE() o se filtran con IS
NULL o IS NOT NULL .

El valor nulo se puede escribir en mayúsculas o minúsculas pero nunca entrecomillado, porque entonces
correspondería a la cadena de caracteres ‘NULL’ o ‘null’.

2.1.13. Operador de concatenación

El operador de concatenación ( || ) se usa para unir cadenas de texto.

SQL

1 SELECT dni, apellidos || ' ' || nombre AS candidato


2 FROM persona;

Si no se usa alias, la columna aparece como ?column? .

Se puede concatenar texto con fechas, pero si hay NULL , el resultado será también NULL .

SQL

1 SELECT dni, 'baja de contrato: ' || fechaBaja


2 FROM contrato;

Si fechaBaja es NULL , no aparecerá texto.

Para evitar que la concatenación devuelva NULL , usamos COALESCE() :

SQL

1 SELECT dni,
2 'baja de contrato: ' || COALESCE(fechaBaja::TEXT, 'En activo') AS situación
3 FROM contrato;

fechaBaja::TEXT : convierte la fecha a texto.


'En activo' : se muestra si el valor es NULL .

Corrección de errores en consola:


Si olvidas cerrar un paréntesis o una comilla, el prompt cambia (por ejemplo, a ett(> ).
Pulsa [Ctrl] + [C] para cancelar la consulta y luego usa \e para editarla correctamente.

2.1.14. Ordenación de los datos

ORDER BY : para ordenar por nombre de columna, alias, expresión o número de columna.

SQL

1 SELECT dni, fechaAlta, salario, jornada


2 FROM contrato
3 ORDER BY 2 DESC, 3;

También se pueden ordenar resultados usando expresiones aritméticas:

SQL

1 SELECT dni,
2 jornada,
3 salario * 1.03 AS "Salario + 3%"
4 FROM contrato
5 ORDER BY 3 DESC, 1;

2.1.15. Otros operadores relacionales

BETWEEN … AND ... : se usan para filtrar valores dentro de un rango. Los valores del rango están incluidos.

SQL

1 SELECT dni, fechaAlta, fechaBaja, jornada, tipoContrato


2 FROM contrato
3 WHERE salario BETWEEN 12000 AND 25000
4 ORDER BY jornada;

También es equivalente a usar los operadores >= y <= .

SQL

1 SELECT *
2 FROM contrato
3 WHERE salario >= 12000 AND salario <= 25000
4 ORDER BY salario;

IN : compara si un valor existe dentro de una lista de valores. Puede ser de cualquier tipo de dato.

SQL
1 SELECT dni, cif, jornada, tipoContrato
2 FROM contrato
3 WHERE LOWER(tipoContrato) IN ('formación', 'prácticas', 'temporal');

El equivalente con operadores lógicos sería:

SQL

1 SELECT dni, cif, jornada, tipoContrato


2 FROM contrato
3 WHERE LOWER(tipoContrato) = 'formación' OR
4 LOWER(tipoContrato) = 'prácticas' OR
5 LOWER(tipoContrato) = 'temporal';

LIKE : se usa para realizar búsquedas con patrones utilizando metacaracteres.

% : representa cero o más caracteres.


_ : representa un solo carácter.

SQL

1 SELECT nombre, apellidos


2 FROM persona
3 WHERE nombre LIKE 'A%'; -- Buscar nombres que comienzan con "A"

SQL

1 SELECT titulacion
2 FROM persona
3 WHERE LOWER(titulacion) LIKE '%técnica%'; -- Buscar titulaciones que contienen la palabra "técnica"

2.2. Vinculación de tablas

Un JOIN es juntar una fila de una tabla con una fila de otra tabla a través de un campo común, para formar una nueva fila
cuya cabecera (conjunto de campos) será la suma de ambas cabeceras.

Habitualmente la operación de JOIN es una igualdad entre clave ajena (FOREIGN KEY) y clave
primaria (PRIMARY KEY), pero no siempre es así. Se puede realizar JOIN a través de dos campos
cualesquiera siempre y cuando sean del mismo tipo y semánticamente compatibles.

2.2.1. "Inner Join"

INNER JOIN : es el operador más básico de la operación de JOIN, utilizado para combinar filas de dos tablas a través de un
campo común. Para que la operación se lleve a cabo, los valores del campo clave ajena deben coincidir con los valores del
campo clave primaria de la otra tabla.

SQL
1 SELECT tabla1.campo1, tabla1.campo2, tabla2.campo1, ...
2 FROM tabla1 [INNER JOIN] tabla2
3 ON tabla1.Clave_Ajena = tabla2.Clave_Primaria;

Ejemplo de consulta: consultar contratos de personas combinando las tablas persona y contrato:

SQL

1 SELECT *
2 FROM persona INNER JOIN contrato
3 ON [Link] = [Link];

El resultado será una combinación de ambas tablas donde el valor del dni de la tabla persona coincida con el valor de dni en
la tabla contrato. Si alguna persona no tiene un contrato, no aparecerá en el resultado.

Estructura de las tablas:


La tabla persona tiene una clave primaria llamada dni.
La tabla contrato tiene una clave ajena llamada dni que hace referencia a la tabla persona.

Cuando se tienen campos con el mismo nombre en varias tablas, es necesario anteponer el nombre de la tabla a los campos
para evitar confusiones.

Ejemplo de un error de ambigüedad:

SQL

1 ERROR: column reference "nombre" is ambiguous

Para resolver este tipo de errores, se deben especificar las tablas de forma explícita:

SQL

1 SELECT [Link] || ' ' || apellidos AS Empleado, [Link] AS Empresa, [Link], [Link]
2 FROM persona p
3 JOIN contrato c ON [Link] = [Link]
4 JOIN empresa e ON [Link] = [Link]
5 ORDER BY 1, 3;

En este caso:
[Link] hace referencia al campo nombre de la tabla persona.
[Link] hace referencia al campo nombre de la tabla empresa.

Podemos usar alias de tabla. La diferencia entre alias de campo y de tabla es que el primero se coloca
para cambiar la etiqueta de la cabecera y en el segundo caso los utilizamos para comodidad del
programador.
Una vez declarado el alias de tabla, no se puede volver a utilizar en la consulta el nombre original de la
tabla porque daría error.

2.2.2. "Outer Join"

OUTER JOIN : es un tipo de JOIN que incluye todas las filas de una tabla, incluso si no cumplen la condición de unión.
Dependiendo de la tabla de referencia, se utiliza:
LEFT OUTER JOIN : muestra todas las filas de la tabla de la izquierda (siempre que no se cumpla la condición de
unión, muestra los valores nulos para la tabla de la derecha).
RIGHT OUTER JOIN : muestra todas las filas de la tabla de la derecha, mostrando valores nulos para la tabla de la
izquierda cuando no se cumple la condición.

SQL

1 SELECT [Link] || ' ' || apellidos AS Empleado, [Link] AS Empresa, [Link], [Link]
2 FROM persona p LEFT JOIN contrato c ON [Link] = [Link]
3 LEFT JOIN empresa e ON [Link] = [Link]
4 ORDER BY 1, 3;

Se puede realizar la misma consulta con un RIGHT JOIN para obtener los mismos resultados. Ambas consultas devuelven el
mismo resultado, pero el tipo de JOIN cambia, priorizando la tabla de la izquierda o derecha según se necesite.

SQL

1 SELECT [Link] || ' ' || apellidos AS Empleado, [Link] AS Empresa, [Link], [Link]
2 FROM contrato c JOIN empresa e ON [Link] = [Link]
3 RIGHT JOIN persona p ON [Link] = [Link]
4 ORDER BY 1, 3;

FULL OUTER JOIN : muestra todas las filas de ambas tablas, incluso si no cumplen la condición de unión. Es útil cuando se
necesita obtener todos los registros, tanto de la tabla de la izquierda como de la de la derecha.

SQL

1 SELECT nombre || ' ' || apellidos AS Persona, [Link]


2 FROM persona p FULL OUTER JOIN entrevista e ON [Link] = [Link]
3 FULL OUTER JOIN oferta o ON [Link] = [Link];

En el ejemplo anterior se muestra el nombre de cada persona y la profesión de la oferta a la que se ha presentado,
incluyendo personas que no se han presentado a ninguna oferta. En este caso, Ariadna Navarro aparece sin una
profesión asociada, ya que no se ha presentado a ninguna oferta. Además, algunas ofertas aparecen sin personas
asociadas, lo cual es el comportamiento del FULL OUTER JOIN .

La elección del tipo de OUTER JOIN dependerá de cuál tabla se desea priorizar en la consulta y la necesidad de mostrar
datos nulos cuando no se cumple la condición de unión.

2.2.3. "Cross Join"

CROSS JOIN : genera el producto cartesiano de dos tablas, es decir, muestra todas las combinaciones posibles entre las
filas de las dos tablas sin necesidad de especificar una condición de unión.
Aunque la utilidad directa del CROSS JOIN es limitada, puede ser útil cuando se combina con restricciones adicionales, como
operadores relacionales (por ejemplo, BETWEEN ) para filtrar las combinaciones generadas.

SQL

1 SELECT [Link] || ' ' || apellidos AS Empleado, salario, rango


2 FROM persona p LEFT JOIN contrato c ON [Link] = [Link]
3 CROSS JOIN rango_salario
4 WHERE salario BETWEEN salMinimo AND salMaximo;

En el anterior ejemplo se muestra el nombre de cada persona, su salario y su rango salarial según la franja
correspondiente. En este ejemplo, CROSS JOIN genera todas las combinaciones posibles entre las personas y los rangos
salariales, pero la condición WHERE restringe las filas a aquellas cuyo salario se encuentra dentro del rango especificado.

2.2.4. "Self Join"

SELF JOIN : no es un tipo de JOIN en sí mismo, sino que se refiere a cuando una tabla se une consigo misma. Esto puede
ser útil cuando se necesita comparar filas dentro de la misma tabla.

Consideraciones para un SELF JOIN :


Se debe usar un alias para la tabla, ya que al unirse a sí misma, la tabla aparece dos veces.
Es necesario especificar el alias de la tabla antes de cada campo para evitar errores de ambigüedad.

SQL

1 SELECT [Link] AS Empleado, [Link] AS Jefe


2 FROM persona p JOIN persona j ON [Link] = [Link];

En el anterior ejemplo se muestran las personas que tienen jefe, considerando que el campo jefe de la tabla persona se
refiere a otra persona. En este ejemplo, p y j son dos alias de la misma tabla persona. El resultado muestra el nombre de
las personas (empleados) junto con el nombre de su jefe (si tienen uno).

2.3. Consultas de resumen

Las funciones de agregación o de grupo se utilizan para realizar cálculos sobre un conjunto de filas, en lugar de operar en
filas individuales. Estas funciones operan sobre grupos de datos y son esenciales para el análisis de grandes volúmenes de
información.

Las funciones de grupo más comunes son:


AVG([DISTINCT | ALL] n) : calcula el promedio (media) de un conjunto de valores.
COUNT({ *| [DISTINCT | ALL] expresion}) : cuenta el número de filas o el número de valores no nulos en una
columna.
MAX([DISTINCT | ALL] expresion) : devuelve el valor más grande de una columna.
MIN([DISTINCT | ALL] expresión) : devuelve el valor más pequeño de una columna.
SUM([DISTINCT | ALL] n) : calcula la suma de los valores de una columna.

SQL

1 SELECT COUNT(*) "Núm. contratos",


2 MAX(salario) "Sal. más alto",
3 MIN(salario) "Sal. más bajo",
4 ROUND(AVG(salario), 2) "Media salarios"
5 FROM contrato;

Ejemplo para obtener el número total de contratos, el salario más alto, el salario más bajo y la media de los salarios.

SQL

1 SELECT MIN(fechaAlta) "Fecha del contrato más antiguo",


2 MAX(fechaAlta) "Fecha del contrato más reciente"
3 FROM contrato;
En este otro ejemplo, obtenemos las fechas de los contratos más antiguos y más recientes.

Consideraciones:
DISTINCT : si se usa, las funciones de agregación solo considerarán los valores únicos.
ALL : se incluye por defecto, considerando todos los valores, incluyendo duplicados.
Formato de nombres de columnas: en las consultas, las columnas con nombres compuestos
suelen escribirse en camelCase para seguir la convención de estilo, aunque en PostgreSQL las
estructuras se muestran en minúsculas al usar \d .

2.3.1. "Count"

La función COUNT se utiliza para contar filas, ya sea de manera incondicional (contando todas las filas) o de manera
condicional (solo contando aquellas filas donde un campo tiene un valor no nulo). Su uso básico y común es con COUNT(*) ,
que cuenta todas las filas sin importar el contenido de sus campos. Sin embargo, al usar COUNT con un campo específico, la
función solo contará aquellas filas en las que ese campo no sea nulo.

Contar todas las filas (sin importar el valor de los campos):

SQL

1 SELECT COUNT(*) "Número de contratos"


2 FROM contrato;

Contar filas según un campo específico (solo si el campo tiene valor no nulo):

SQL

1 SELECT COUNT(fechaAlta) "Número de contratos"


2 FROM contrato;

Contar filas de acuerdo con un campo que puede tener valores nulos (por ejemplo, fechaBaja):

SQL

1 SELECT COUNT(fechaBaja) "Número de contratos"


2 FROM contrato;

Cuando se usan funciones de agregación como AVG , SUM , MAX , MIN , los valores nulos no se consideran en los cálculos.
Por ejemplo, si se calcula el promedio de un campo que contiene valores nulos, estos valores no se tomarán en cuenta.

SQL

1 SELECT idOferta, numVacantes


2 FROM oferta;

Supongamos que tenemos la anterior tabla de ofertas con valores nulos en el campo numVacantes para algunas filas:

idOferta numVacantes
1 2
2 NULL
3 1

Al calcular el promedio de numVacantes:

SQL

1 SELECT ROUND(AVG(numVacantes), 2) Media


2 FROM oferta;

Esto se debe a que la segunda fila tiene un valor nulo y, por lo tanto, no es considerada en el cálculo de la media. Si la
intención es que el valor nulo sea tratado como 0, se puede utilizar la función COALESCE para reemplazar los valores nulos:
SQL

1 SELECT ROUND(AVG(COALESCE(numVacantes, 0)), 2) Media


2 FROM oferta;

Al usar COALESCE(numVacantes, 0) , los valores nulos son convertidos en ceros antes de realizar el cálculo, corrigiendo así el
promedio.

Se recomienda utilizar siempre COUNT(*) excepto cuando el enunciado sea condicional (aparezca la
condición literalmente o algún adjetivo), en cuyo caso se usará COUNT(campo) .

2.3.2. "Group by"

La cláusula GROUP BY se utiliza en SQL para agrupar filas en subgrupos basados en un campo específico, y luego realizar
funciones de agregación (como COUNT , AVG , SUM , etc.) sobre esos grupos. Cada subgrupo representará un valor distinto en
el campo de agrupación.

GROUP BY : se utiliza cuando se necesita agrupar filas basadas en un criterio específico. El enunciado de la consulta
usualmente indicará qué campo se debe usar para la agrupación. Si no se usa, solo se devolverá una fila con el resultado
global.

SQL

1 SELECT dni, COUNT(*) "Número de contratos"


2 FROM contrato
3 GROUP BY dni;

En el anterior ejemplo, para mostrar el número de contratos por persona, agrupamos por el campo dni y luego usamos
COUNT para contar las filas dentro de cada grupo.
En este caso, el GROUP BY agrupa las filas por dni y calcula el número de contratos para cada persona.

Si una columna aparece en la cláusula SELECT y no está dentro de una función de agregación, debe aparecer también en la
cláusula GROUP BY . Por ejemplo, si queremos contar el número de aspirantes por oferta, pero también mostrar el nombre de
la oferta, debemos agrupar por idOferta y profesion.

SQL

1 SELECT [Link], profesion "Oferta de trabajo", COUNT(*) "Núm. aspirantes"


2 FROM entrevista e JOIN oferta o ON [Link] = [Link]
3 GROUP BY [Link], profesion;

Error de agregación en WHERE : no se pueden usar funciones de agregación directamente en la cláusula WHERE . Para filtrar
grupos basados en funciones de agregación, se debe usar la cláusula HAVING después de GROUP BY .

SQL

1 SELECT [Link], profesion "Oferta de trabajo", COUNT(*) "Núm. aspirantes"


2 FROM entrevista e JOIN oferta o ON [Link] = [Link]
3 WHERE COUNT(*) >= 3
4 GROUP BY [Link], profesion;

Este código genera un error porque COUNT(*) no se puede usar en WHERE . La solución es mover la condición a HAVING :

SQL

1 SELECT [Link], profesion "Oferta de trabajo", COUNT(*) "Núm. aspirantes"


2 FROM entrevista e JOIN oferta o ON [Link] = [Link]
3 GROUP BY [Link], profesion
4 HAVING COUNT(*) >= 3;
Las funciones de grupo no tienen en cuenta las filas con el campo en uso a nulo, con lo cual mostrarán
datos sesgados. Y la responsabilidad sería del programador por no tenerlo en cuenta.

Orden de ejecución en una consulta SQL:


Filtrado de filas con la cláusula WHERE .
Creación de grupos con GROUP BY .
Cálculo de funciones de agregación como COUNT , AVG , etc.
Filtrado de funciones de agregación con HAVING .
Ordenación con ORDER BY .
Selección de columnas con SELECT .

2.3.3. Anidamiento de funcione de grupo

Las funciones agregadas, como AVG (promedio) y MAX (máximo), se utilizan para realizar cálculos sobre grupos de filas.
Cuando se trabaja con funciones agregadas, es importante entender cómo manejarlas correctamente, especialmente en
casos de anidamiento.

SQL

1 SELECT ROUND(AVG(salario),2)
2 FROM contrato
3 GROUP BY dni;

Error al anidar funciones agregadas: si se intenta calcular la media más alta del sistema usando MAX(AVG(salario)) , se
obtiene un error. El error indica que las funciones agregadas no pueden ser "anidadas" directamente.

SQL

1 SELECT MAX(ROUND(AVG(salario),2))
2 FROM contrato
3 GROUP BY dni;

Error: aggregate function calls cannot be nested.

Para solucionar este problema, se puede crear una tabla temporal usando una subconsulta. Esto permite calcular la media
de los salarios primero y luego aplicar la función MAX sobre el resultado de esa subconsulta.

SQL

1 SELECT MAX(mediana)
2 FROM (SELECT ROUND(AVG(salario),2) mediana
3 FROM contrato
4 GROUP BY dni) tabla_mediana;

Este método funciona correctamente porque las funciones agregadas ya no están anidadas, sino que se calculan en dos
pasos diferentes.

2.4. Subconsultas

Las subconsultas son consultas dentro de otras consultas. Se ejecutan primero y devuelven resultados a la consulta
principal para que los utilice. Los datos generados por una subconsulta no son visibles fuera de ella y siempre se encuentran
entre paréntesis, colocados a la derecha del operador.

Tipos de subconsultas:
Monoregistro: devuelve una única fila y un solo campo.
Multiregistro: devuelve varias filas y un solo campo.
Multicolumna: devuelve varias filas y varios campos.
Supongamos que queremos saber cuál es el salario anual más alto registrado en la base de datos y qué persona lo gana.
Usamos MAX para obtener el salario más alto, pero luego necesitamos una subconsulta para encontrar la persona asociada a
ese salario.

En una consulta que requiere un dato previamente obtenido (como el salario máximo), la subconsulta se utiliza para obtener
primero ese dato y luego usarlo en la consulta principal.

La subconsulta puede devolver:


Cero filas.
Una fila.
Varias filas (sin importar cuántos campos).

Consideraciones:
La subconsulta no debe incluir ORDER BY .
Dependiendo de cuántas filas devuelva la subconsulta, la consulta principal debe adaptarse para
manejar correctamente esos resultados.

2.4.1. Subconsultas monoregistro

Las subconsultas monoregistro devuelven un único valor (una fila y un campo). Este tipo de subconsulta utiliza
operadores relacionales (también llamados de comparación) para filtrar los resultados de la consulta principal. Se usan
cuando necesitamos un único valor calculado en la subconsulta para hacer una comparación en la consulta principal.

Sin subconsulta: si supiéramos el valor del salario máximo, podríamos hacer la consulta directamente con ese valor.

SQL

1 SELECT nombre, titulacion, salario


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE salario = 33000;

Con subconsulta: como desconocemos el valor, usamos una subconsulta para obtener el salario máximo.

SQL

1 SELECT nombre, titulacion, salario


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE salario = (SELECT MAX(salario) FROM contrato);

Aunque podríamos pensar en usar la cláusula LIMIT para obtener un único valor, LIMIT no es adecuado en muchas
situaciones, especialmente cuando hay varias filas que cumplen con una condición.

Ejemplo incorrecto usando LIMIT : mostrar la persona con el salario más alto:

SQL

1 SELECT nombre, titulacion, salario


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 ORDER BY salario DESC
4 LIMIT 1;

El uso de LIMIT puede dar un resultado incorrecto si varias personas tienen el mismo salario máximo, ya que solo devolvería
una fila en lugar de todas las que cumplan la condición.

Ejemplo incorrecto usando LIMIT : para obtener la persona con la fecha de contratación más antigua:

SQL

1 SELECT nombre, apellidos, fechaAlta


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 ORDER BY fechaAlta ASC
4 LIMIT 1;
Este enfoque anterior también puede ser incorrecto si varias personas tienen la misma fecha de contratación más antigua.

La solución correcta es usar una subconsulta para obtener el valor que estamos buscando. Por ejemplo, si queremos
obtener la persona con la fecha de contratación más antigua:

SQL

1 SELECT nombre, apellidos, [Link] "Fecha contratación"


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE [Link] = (SELECT MIN(fechaAlta) FROM contrato);

Esto devuelve todas las personas que tienen la fecha de contratación más antigua, sin omitir ninguna fila, como ocurriría con
LIMIT .

2.4.2. Subconsultas multiregistro

Las subconsultas multiregistro retornan varias filas de un campo y se utilizan con operadores multiregistro. Estos
operadores permiten realizar comparaciones con múltiples valores.

Operadores utilizados:
IN : se evalúa a true si el valor del campo está en la lista de valores proporcionada.
ANY : se evalúa a true si la comparación es válida para al menos un valor de la lista.
ALL : se evalúa a true si la comparación es válida para todos los valores de la lista.

SQL

1 SELECT nombre, apellidos


2 FROM persona
3 WHERE dni NOT IN (SELECT dni FROM entrevista);

El anterior ejemplo muestra las personas que no realizaron ninguna entrevista.

SQL

1 SELECT dni
2 FROM entrevista
3 WHERE dni IN (SELECT dni FROM contrato);

El anterior ejemplo muestra el DNI de las personas que fueron entrevistadas y luego contratadas.

En algunos casos, una subconsulta multiregistro puede reformularse como una subconsulta monoregistro. Esto ocurre
cuando la subconsulta devuelve varios valores que se pueden comparar con una sola fila o campo en la consulta principal.

Subconsulta multiregistro: con el operador ALL (salario menor que todos los de contrato indefinido):

SQL

1 SELECT nombre || ' ' || apellidos trabajador, cif empresa, [Link] Desde, fechaBaja Hasta,
tipoContrato
2 FROM contrato c JOIN persona p ON [Link] = [Link]
3 WHERE salario < ALL ( SELECT salario FROM contrato WHERE LOWER(tipoContrato) = 'indefinido');

Aquí se muestran los contratos de personas cuyo salario es menor que cualquiera de los salarios de personas con contrato
indefinido.

Transformación a subconsulta monoregistro: utilizando MIN para obtener el salario más bajo de los contratos indefinidos:

SQL

1 SELECT nombre || ' ' || apellidos trabajador, cif empresa, [Link] Desde, fechaBaja Hasta,
tipoContrato
2 FROM contrato c JOIN persona p ON [Link] = [Link]
3 WHERE salario < ( SELECT MIN(salario) FROM contrato WHERE LOWER(tipoContrato) = 'indefinido');

Aquí se muestra el mismo conjunto de trabajadores con salarios inferiores al salario más bajo de los contratos indefinidos.
2.4.3. Subconsultas multicolumna

Las subconsultas multicolumna devuelven varias filas con múltiples columnas, y se deben utilizar operadores
multiregistro. En este tipo de subconsulta, los resultados deben coincidir en el número de columnas tanto en la consulta
principal como en la subconsulta.

Este tipo de subconsulta es útil cuando necesitamos comparar múltiples columnas simultáneamente.

SQL

1 SELECT [Link], [Link], [Link]


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE [Link] IS NOT NULL
4 AND ([Link], [Link]) IN (SELECT [Link], [Link]
5 FROM persona p JOIN contrato c ON [Link] = [Link]
6 WHERE [Link] IS NULL);

Aquí se mostrarían las personas que trabajan actualmente en una empresa en la que ya habían trabajado antes.

2.4.4. Subconsultas correlacionadas

Las subconsultas correlacionadas hacen referencia a valores de la consulta principal en su cláusula WHERE . Estas
subconsultas se ejecutan para cada fila de la consulta principal, utilizando su valor actual en la condición.

Esta subconsulta hace referencia a valores de la consulta principal y permite filtrar los resultados de manera más precisa.

SQL

1 SELECT [Link], [Link], [Link]


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE [Link] IS NOT NULL
4 AND [Link] IN (SELECT [Link]
5 FROM persona p1 JOIN contrato c1 ON [Link] = [Link]
6 WHERE [Link] IS NULL AND [Link] = [Link]);

Aquí se mostrarían las personas que trabajan actualmente en una empresa donde ya habían trabajado.

2.5. Operaciones de conjuntos

En álgebra relacional, se tratan las tablas como conjuntos y las filas como elementos. Existen tres operaciones
fundamentales de conjuntos en SQL: INTERSECT , UNION , EXCEPT .

INTERSECT : muestra los elementos comunes entre dos conjuntos. Es conmutativo, lo que significa que el orden de las tablas
no afecta al resultado.

SQL

1 SELECT [Link], [Link], [Link]


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE [Link] IS NOT NULL
4 INTERSECT
5 SELECT [Link], [Link], [Link]
6 FROM persona p JOIN contrato c ON [Link] = [Link]
7 WHERE [Link] IS NULL;

En el ejemplo anterior se muestran las personas que han trabajado tanto en contratos con fecha de baja como sin fecha de
baja.

UNION : une dos conjuntos de datos. Muestra todos los elementos de ambos conjuntos, eliminando duplicados. También es
conmutativa.

SQL

1 SELECT dni
2 FROM contrato
3 WHERE LOWER(tipoContrato) = 'indefinido'
4 UNION
5 SELECT dni
6 FROM contrato
7 WHERE LOWER(tipoContrato) = 'practicas';

EXCEPT : es la resta de conjuntos. Muestra los elementos que están en el primer conjunto pero no en el segundo. No es
conmutativa. Este operador muestra el complemento de los elementos del primer conjunto respecto al segundo.

SQL

1 SELECT dni
2 FROM persona
3 EXCEPT
4 SELECT dni
5 FROM entrevista;

El ejemplo anterior muestra personas que no han realizado ninguna entrevista.

2.6. Cálculo relacional

EXISTS : permite verificar si existe una fila que cumpla con una condición específica. Es útil para consultas que dependen de
la existencia de datos en otra tabla.

SQL

1 SELECT [Link], [Link], [Link]


2 FROM persona p JOIN contrato c ON [Link] = [Link]
3 WHERE [Link] IS NOT NULL
4 AND EXISTS (SELECT *
5 FROM persona p1 JOIN contrato c1 ON [Link] = [Link]
6 WHERE [Link] IS NULL AND [Link] = [Link] AND [Link] = [Link]);

El anterior ejemplo muestra personas dadas de alta en la ETT pero que nunca realizaron una entrevista.

También podría gustarte