Módulo 3. SQL - Final
Módulo 3. SQL - Final
SQL
Introducción
Introducción a SQL
Del inglés Structured Query Language, (SQL) es el lenguaje estándar para trabajar con bases
de datos relacionales y es soportado prácticamente por todos los productos en el mercado.
Originalmente, SQL fue desarrollado en IBM Research a principios de los años setenta. Se
usó por primera vez a gran escala en un prototipo de IBM denominado System R, luego fue
aplicado en numerosos productos comerciales de IBM y de otros fabricantes. En este
capítulo, presentamos una introducción al lenguaje SQL, los tipos de datos y cómo generar
la estructura de una base de datos. Esto último es lo que se conoce por sus siglas en inglés
como DDL (Data Definition Language). En cuanto a la actualización, se especifica también
otro lenguaje, el DML (Data Manipulation Language) que nos permite modificar el estado
de la base de datos.
1
de ellos define SQL y muestra algo de historia del estándar ANSI para, en el segundo
artículo, ver más en detalle la historia del lenguaje.
Fuente:
Fuente:
Las bases de datos almacenan datos mediante registros, pueden ser distintos en
su característica, soporte, etc. Así, como un aspecto previo, es necesario conocer la
naturaleza de los distintos tipos de datos.
Los DBMS proveen distintos tipos de datos con los cuales podemos trabajar, sin embargo, es
necesario especificar cuál nos conviene más y, para eso, debemos saber
sus características en búsqueda, capacidad, uso de los recursos, etc.
En este curso en particular, recomendamos el uso del motor Postgre SQL. Como en todos los
administradores de bases de datos, implementa los tipos de datos definidos para el
estándar SQL3 y aumenta algunos otros. Detallando algunos de los tipos mencionados
antes, veamos los tipos definidos por el estándar SQL3 que se muestran en la tabla 2.
Tablas
Los datos son almacenados en las tablas por medio de filas y columnas. La definición de las
tablas se realiza con un nombre que la identifica unívocamente y un conjunto de columnas.
Una vez creada se le pueden insertar datos en las filas. Sobre las filas de las tablas se pueden
hacer operaciones de consulta, eliminación o actualización de datos.
Columna: una columna o atributo representa un tipo de datos en una tabla, por ejemplo, el
nombre de un artículo en la tabla “artículos”. Cada columna cuenta con un nombre, un tipo
de dato (char, date o number) y un tamaño (cantidad de caracteres, si es un tipo texto, un
ancho, si es un tipo fecha) o una escala y precisión (para tipos numéricos). Los valores de
una columna siempre van a tener el mismo tipo de datos. Las columnas se van creando de
izquierda a derecha, este dato no es relevante a la hora de recuperar los datos de una tabla.
Fila: una fila es una composición de los valores de las columnas de una tabla, por ejemplo, la
información acerca de un artículo (nombre, precio) en la tabla “artículos”. Las filas también
son conocidas como tuplas o registros. Cada tabla puede contener cero o más registros o
filas y su contenido es un único valor en cada columna. Por defecto, las filas están
desordenadas, se van disponiendo en la medida que se insertan.
Campo: la intersección de una fila con una columna es el campo. Es la unidad más atómica
de una tabla, no puede ser descompuesto en valores más pequeños. El campo puede o no
contener datos, la ausencia de datos se conoce como campo nulo.
Según vimos antes, es necesario un lenguaje que nos permita crear tanto la estructura, es
decir, las tablas, como el acceso, consulta y actualización de los datos, además de la
inserción, selección y eliminación de tuplas o registros. SQL provee ambos lenguajes (DDL y
DML). Comencemos viendo unos ejemplos de cómo crear tablas a través de SQL.
Para crear nuestras tablas, primero tendremos que hacer un esquema de base de datos.
Teniendo en cuenta el motor utilizado, cada esquema puede tener varias bases de datos.
Previo a las tablas, veamos las sentencias necesarias para crear el esquema.
CREATE SCHEMA {<nombre_esquema>|AUTHORIZATION<usuario>}
[<lista_elementos_esquema>];
La nomenclatura utilizada en esta sentencia y, de aquí en adelante, es la siguiente:
• La notación [...] quiere decir que lo que hay entre los corchetes se
todas las opciones que hay entre las llaves. Pero tenemos que poner una
obligatoriamente.
Como ya hemos visto, la estructura de almacenamiento de los datos del modelo relacional
son las tablas. Para crear una tabla hay que utilizar la sentencia create table. Veamos el
formato:
El proceso que hay que seguir para crear una tabla es el siguiente:
2) Dar nombre a cada uno de los atributos que formarán las columnas de
4) Una vez definidas las columnas, solo habrá que dar las restricciones
Si queremos crear una tabla para almacenar los empleados de una empresa, donde cada
empleado tiene obligatoriamente que tener un DNI y fecha de ingreso y, opcionalmente, se
almacenará su nombre, su apellido y su edad, podríamos tener la siguiente sentencia SQL
Las columnas que no pueden tener valores nulos se indican con las palabras reservadas not
null.
Restricciones de columna
En cada una de las columnas de la tabla, una vez que les hemos dado un nombre y
tendrán que cumplir. Las restricciones que se pueden dar son las que aparecen en la
https://bit.ly/4479X3D)
Clave primaria: la clave primaria está compuesta por una o más columnas que permiten
identificar de manera unívoca a cada fila de una tabla, por ejemplo, el código de barras de
un artículo. La clave primaria es única por tabla y siempre debe contener un valor.
Clave foránea: la clave foránea está compuesta por una o más columnas que hacen
referencia a una clave primaria de otra tabla o de la misma, por eso la relación entre las
tablas que las contienen se conoce como padre/hijo. Las claves foráneas tienen el fin de
ayudar al cumplimiento de las reglas de diseño de la base de datos relacional. Se puede
contar con más de una clave foránea por tabla. Estas claves surgen de la necesidad de
relacionar diferentes tablas. Como vimos en el ejemplo de curso-alumno (en la lectura 2), la
forma de relacionar una tabla con otra es a través de este tipo de claves.
Restricciones de tabla
Una vez que hemos dado un nombre, definido un dominio y hemos impuesto ciertas
restricciones para cada una de las columnas, podemos aplicar restricciones sobre toda la
tabla que siempre se tendrán que cumplir. Las restricciones que se pueden dar son las
siguientes:
Vistas
Los índices y las vistas son mecanismos que facilitan el acceso a los datos. Para el caso de los
índices, como vimos en el módulo 1, sirven para mejorar la performance de la base de datos,
ya que son estructuras auxiliares de rápido acceso. El caso de las vistas nos permite resumir
o conjugar diferentes consultas agrupándolas con un mismo nombre lógico. Veamos la
estructura de la consulta SQL y algunos ejemplos.
CREATEVIEW<nombre_vista>[(lista_colum
nas)]AS(consulta) [WITH CHECKOPTION];
VP Vistas: https://vimeo.com/567515973
bien, poner nombre a alguna que en principio no tenía, lo podemos hacer en lista de
columnas. A partir de ahí, solo nos quedará definir la consulta que formará nuestra
vista.
nombre de tablas básicas (o tablas de base). La no existencia real de las vistas hace
Creamos una vista que dé, por ejemplo, para cada cliente, el número de
https://bit.ly/4479X3D)
Más adelante detallaremos, pero vemos en esta vista varios componentes nuevos. La
consulta propiamente dicha (select) retorna lo indicado en el enunciado y nos permite
consultar los datos directamente utilizando la vista “proyectos por cliente”, si tuviésemos las
siguientes extensiones:
Tabla 5. Clientes
Clientes
codigo_c nombre_ Nif direcció ciudad teléfono
li cli n
10 ECIGSA 38.567.89 Aragón Barcel NULL
3-C 11 ona
20 CME 38.123.89 Valenci Geron 972.23.5
8-E a 22 a 7.21
30 ACME 36.432.12 Mallorc Lérida 973.23.4
7-A a 33 5.67
Fuente: elaboración propia con base en Programación, 1 de julio de 2015,
https://bit.ly/2OXHQ23
Tabla 6. Proyectos
Proyectos
codigo_proy nombre_pro preci fecha_inici fecha_prev_ fecha_fi codigo_client
y o o fin n e
1 GESCOM 1,0E+ 1-1-98 1-1-99 NULL 10
6
2 PESCI 2,0E+ 1-10-96 31-3-98 1-5-98 10
6
3 SALSA 1,0E+ 10-2-98 1-2-99 NULL 20
6
4 TINELL 4,0E+ 1-1-97 1-12-99 NULL 30
6
Fuente: Programación, 2015, https://bit.ly/2OXHQ23
Índices
Los índices, si bien siempre están asociados a una tabla, son objetos independientes, ya sea
desde el punto de vista lógico como del punto de vista físico. Ellos se pueden crear o
eliminar sin que afecten a la información almacenada en una tabla.
El DBMS utiliza el índice como se puede utilizar el índice de un libro. El índice contiene una
entrada por cada valor que aparece en las columnas indexadas de la tabla y punteros
(orowid) a las filas que contienen esos valores. “Cada puntero conduce directamente a la fila
apropiada; en consecuencia, se evita el barrido total de la tabla” (Oracle, s. f., p. 22).
En el índice, los valores de los datos están dispuestos en orden ascendente o descendente,
de modo que el DBMS es capaz de buscar rápidamente el índice para encontrar un valor
particular. A continuación, podemos seguir el puntero para localizar la fila que contiene el
valor.
VP Índices: https://vimeo.com/567516053
El video ya no aparece en el enlace.
En general, es una buena idea crear un índice para las columnas que se utilizan con
frecuencia en las condiciones de búsqueda. La indexación también es más apropiada cuando
las consultas en una tabla son más frecuentes que las inserciones y las actualizaciones.
Clave primaria: la mayoría de los productos de DBMS siempre establecen un índice para la
clave primaria de una tabla porque anticipan que el acceso a la tabla será más frecuente a
través de la clave primaria. El índice de clave primaria también ayuda al DBMS a comprobar
rápidamente los valores duplicados a medida que se insertan nuevas filas en la tabla.
Desventajas de los índices: consumen espacio adicional en disco. Deben actualizarse cada
vez que se agrega una fila a la tabla. Imponen una sobrecarga adicional en inserts y updates.
Tipos de índices
Algunos productos DBMS soportan dos o más tipos diferentes de índices, que están
optimizados para diferentes tipos de acceso a la base de datos.
Árbol B (B*Tree): es el tipo predeterminado en casi todos los productos de DBMS. Utiliza
una estructura de árbol de entradas de índice y bloques de índice (grupos de entradas de
índice) para organizar los valores de datos que contiene en orden ascendente o
descendente. Proporciona una búsqueda eficiente de un valor único o de un intervalo de
valores, como lo es la búsqueda requerida para un operador de comparación de desigualdad
o una operación de prueba de intervalo (between).e.
La sentencia asigna un nombre al índice y especifica la tabla para la que se crea el índice. La
sentencia también especifica las columnas que se van a indexar y si deben ser indexadas en
orden ascendente o descendente. Veamos unos ejemplos de creación de índices:
Para manipular los datos de cualquier base de datos, se cuenta con dos operaciones básicas:
las de recuperación y las de inserción o actualización de datos. Para realizar estas
operaciones utilizamos el lenguaje SQL, específicamente, el sublenguaje que permite
manipular los datos (Data Manipulation Language).
La sentencia del lenguaje utilizada para la recuperación de datos a partir de la base de datos
es la sentencia select. SQL posee diversos operadores que pueden ser utilizados al escribir
una consulta SQL o select. La sentencia select, además, posee cláusulas que permiten
restringir y ordenar el conjunto resultado, lo que permite presentar el resultado de una
consulta según el formato requerido por el usuario final de la base de datos. SQL también
provee la facilidad de invocar funciones, programas que reciben argumentos y calculan o
retornan un valor en la sentencia select. La invocación de funciones brinda mayor
flexibilidad y potencia al lenguaje, a la vez que provee un mecanismo de extensión.
Los datos en una base de datos relacional se almacenan en diferentes tablas que se
encuentran relacionadas por valores en común. Utilizando la sentencia select es posible
escribir consultas que unen dos o más tablas relacionadas y presentan la información de
manera unificada.
Aparte del acceso a datos almacenados en diferentes tablas, es posible agregar o agrupar
datos según valores comunes, de esta manera, se pueden calcular valores sumarizados en el
grupo de filas. La sentencia select posee una cláusula para especificar el agrupamiento de
datos y existen diferentes funciones de grupo para llevar a cabo cálculos en el grupo. Este
tipo de consultas son las que se denominan agrupadas.
Todas las palabras marcadas en negrita son reservadas del lenguaje SQL y el orden que se ve
es el que debemos seguir al momento de crear nuestras consultas.
Para hacer consultas sobre una tabla con SQL, es preciso utilizar la sentencia select from,
que tiene el siguiente formato:
SELECTnombre_columna_a_seleccionar [nombre_columna_a_seleccionar...]
FROM tabla_a_consultar
WHERE restricciones;
La selección es el proceso por el cual elegimos qué registros tomamos de una tabla en
particular. Esto se hace a través del where, es opcional, ya que si no se escribe, indica que
queremos todas las tuplas o registros de una tabla. La proyección es la que nos permite
elegir qué campos o atributos mostrar de una determinada tabla, se hace a través del select.
Por último, pero no menos importante, aparece el from. A través de esta palabra indicamos
sobre qué tabla estamos realizando la consulta. Veamos unos ejemplos.
Si tenemos una tabla clientes (código, nombre, dirección, ciudad) y queremos listar todos
los clientes mostrando todas las columnas, simplemente basta con escribir:
Select*
From clientes;
Vemos que con “*” indicamos todas las columnas. Ahora, si quisiéramos ver solo el código
del cliente y el nombre, sería así:
Por último, si quisiéramos solo ver aquellos códigos de clientes de la ciudad de Buenos
Aires, se vería:
Select código
From clientes Where ciudad = “Buenos Aires”.
Condiciones y operadores
Para definir las condiciones en la cláusula where, podemos utilizar los operadores que
dispone SQL.
Operadores de comparación
= Igual
< Menor
> Mayor
<= Menor o igual
>= Mayor o igual
<> Distinto
Fuente: elaboración propia.
Unión
La cláusula unión permite unir consultas de dos o más sentencias select from. Su formato es
el siguiente:
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>]
UNION [ALL]
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>];
Si se utiliza la opción all aparecen todas las filas obtenidas al hacer la unión. No se escribirá
esta opción si se quieren eliminar las filas repetidas. Lo más importante de la unión es que
somos nosotros los que tenemos que vigilar que se haga entre columnas definidas sobre
dominios compatibles; es decir, que tengan la misma interpretación semántica. Como ya se
ha dicho, SQL no ofrece herramientas para asegurar la compatibilidad semántica entre
columnas.
La intersección
Para hacer la intersección entre dos o más sentencias select from, se puede utilizar la
cláusula intersect, cuyo formato es el siguiente:
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>]
INTERSECT [ALL]
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>];
Si se utiliza la opción all, aparecen todas las filas obtenidas al hacer la intersección. No se
escribirá esta opción si se quieren eliminar las filas repetidas. En la intersección, es de suma
importancia tener en cuenta que somos nosotros los que tenemos que vigilar que se aplique
entre columnas definidas sobre dominios compatibles, es decir, que tengan la misma
interpretación semántica.
La diferencia
Para encontrar la diferencia entre dos o más sentencias select from podemos utilizar la
cláusula except que tiene este formato:
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>]
EXCEPT [ALL]
SELECT <nombre_columnas>
FROM <tabla>
[WHERE <condiciones>];
Si se utiliza la opción all, aparecen todas las filas obtenidas al hacer la diferencia. No se
escribirá esta opción si se quieren eliminar las filas repetidas. Lo más importante de la
diferencia es que somos nosotros los que tenemos que vigilar que se haga entre columnas
definidas sobre dominios compatibles.
En las operaciones de conjunto, las columnas de los conjuntos que van a operar deben ser
las mismas.
Verdadero
Falso
Para que dos o más conjuntos sean compatibles entre sí y podamos operar entre ellos, es
condición necesaria que las columnas de ambos sean iguales. De lo contrario, no podremos
operar ambos conjuntos entre sí.
Combinación
https://bit.ly/438I3Tp)
Si queremos saber el NIF, el código y el precio del proyecto que se desarrolla para el cliente
número 20:
SELECT proyectos.codigo_proy, proyectos.precio, clientes.nif FROM clientes,
proyectos
WHERE clientes.codigo_cli = proyectos.codigo_cliente
AND clientes.codigo_cli = 20;
Si trabajamos con más de una tabla, puede pasar que la tabla resultante tenga dos columnas
con el mismo nombre. Por eso, es obligatorio especificar a qué tabla corresponden las
columnas a las que nos referimos, se nombra la tabla a la que pertenecen antes de ponerlas
(por ejemplo, clientes.codigo_cli). Para simplificarlo, se utilizan los alias que, en este caso, se
definen en la cláusula from.
Nota: un alias se define automáticamente después de nombrar la tabla dentro del from
(ejemplo: from persona p, p es un alias para persona).
La opción on, además de expresar condiciones con la igualdad en caso de que las
sean el de igualdad. También podemos utilizar una misma tabla dos veces con alias
Combinación natural
hacer una equicombinación entre columnas del mismo nombre y eliminar las
SELECT codigo_empl,nombre_empl
FROM empleados NATURAL JOIN departamentos WHERE telefono ="977.333.852";
join) solo se queda con las filas que tienen valores idénticos en las columnas de las
tablas que compara. Esto puede hacer que se pierda alguna fila interesante de
alguna de las dos tablas, por ejemplo, porque se encuentra null en el momento de
SELECT <nombre_columnas_seleccionar>
FROM <tabla1> [NATURAL] [INNER] JOIN <tabla2>
{ON <condiciones>|
USING (<nombre_columna> [,<nombre_columna>...])} [WHERE
<condiciones>];
Si no se quiere perder ninguna fila en una tabla determinada se puede hacer una
combinación externa (outer join). Permite obtener todos los valores de la tabla que
hemos puesto a la derecha, los valores de la que hemos puesto a la izquierda o todos
SELECT <nombre_columnas_seleccionar>
FROM <tabla1> [NATURAL] {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla2>
{ON <condiciones>|
USING (<nombre_columna> [,<nombre_columna>...])} [WHERE
<condiciones>];
from y los vínculos necesarios en el where. Hay que ir haciendo combinaciones por
siguiente.
Veamos ejemplos de los dos casos. Supongamos que se quieren combinar tablas de
SELECT *
FROM empleados, proyectos, clientes
WHERE num_proy = codigo_proy AND codigo_cliente = codigo_cli;
O bien,
SELECT *
FROM (empleados JOIN proyectos ON num_proy = codigo_proy) JOIN clientes ON
codigo_cliente = codigo_cli;
Funciones de agregación
SQL ofrece las siguientes funciones de agregación para efectuar diferentes operaciones con
los datos de una BD.
Funciones de agregación
Función Descripción
Count Nos da el número total de filas seleccionadas
Sum Suma los valores de una columna
Min Nos da el valor mínimo de una columna
Max Nos da el valor máximo de una columna
AVG Calcula la media de una columna
Fuente: Escofet, 2013, p. 30.
tablas seleccionadas: count (*) contaría las filas de la tabla o tablas que cumplan las
Las cláusulas que añadimos a la sentencia select from permiten organizar las filas por
grupos:
- La cláusula group by nos sirve para agrupar filas según las columnas que indique esta
cláusula.
SELECT <nombre_columnas_seleccionar>
FROM <tabla_consultar> [WHERE <condiciones>]
Prestemos especial atención a que en las sentencias SQL se van añadiendo cláusulas a
medida que la dificultad o la exigencia de la consulta lo requiere.
Consulta con agrupación de filas: se quiere saber el sueldo medio que ganan los empleados
de cada departamento.
Factores de agrupación
Los factores de agrupación de la cláusula group by tienen que ser, como mínimo, las
columnas que figuran en select, exceptuando las columnas afectadas por las funciones de
agregación.
Veamos un ejemplo de uso de una función de agregación SUM de SQL que aparece en la
cláusula having de group by: queremos saber los códigos de los proyectos en los cuales la
suma de los sueldos de los empleados es mayor de EUR 180 000.
SELECT
num_proy FROM
empleados GROUP BY
num_proy
HAVING SUM(sueldo)>180000.0;
Consultas ordenadas
Si se quiere que, al hacer una consulta, los datos aparezcan en un orden determinado, hay
que utilizar la cláusula order by en la sentencia select, que tiene el siguiente formato:
SELECT <nombre_columnas_seleccionar>
FROM <tabla_consultar> [WHERE
<condiciones>]
ORDER BY <nombre_columna_según_la_que_ordenar> [DESC]
[, <nombre_columna_según_la_que_ordenar>
[DESC]...];
Ejemplo: se quiere consultar los nombres de los empleados ordenados según el sueldo que
ganan y si ganan el mismo sueldo, ordenados alfabéticamente por el nombre.
Si no se especifica nada más, el orden que se seguirá será ascendente, pero si se quiere
seguir un orden descendente, hay que añadir desc detrás de cada factor de ordenación
expresado en la cláusula order by:
También se puede explicitar un orden ascendente poniendo la palabra clave ASC (opción
por defecto).
Microactividades
Cierre
Dataprix. (22 de septiembre de 2009 B). Creación y borrador de una base de datos
relacional. https://www.dataprix.com/es/bases-datos-master-software-libre-uoc/11-
creacion-y-borrador-una-base-datos-relacional
Programación. (1 de julio de 2015). SQL creación y borrado de vistas. Creación de una vista
en BDUOC. https://ayudaparaprogramacion.blogspot.com/2015/07/sql-creacion-y-
borrado-de-vistas.html