0% encontró este documento útil (0 votos)
7 vistas105 páginas

Introducción a SQL y Bases de Datos Relacionales

El documento introduce SQL como un lenguaje de consulta estructurado utilizado para interactuar con bases de datos relacionales, permitiendo crear, manipular y consultar datos. Se detalla la historia de SQL desde su creación en 1974 hasta su estandarización por ANSI e ISO, así como las características y diseño de bases de datos relacionales, incluyendo entidades, atributos y relaciones. Además, se enfatiza la importancia de un buen diseño de base de datos para garantizar eficiencia, fiabilidad y seguridad.
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)
7 vistas105 páginas

Introducción a SQL y Bases de Datos Relacionales

El documento introduce SQL como un lenguaje de consulta estructurado utilizado para interactuar con bases de datos relacionales, permitiendo crear, manipular y consultar datos. Se detalla la historia de SQL desde su creación en 1974 hasta su estandarización por ANSI e ISO, así como las características y diseño de bases de datos relacionales, incluyendo entidades, atributos y relaciones. Además, se enfatiza la importancia de un buen diseño de base de datos para garantizar eficiencia, fiabilidad y seguridad.
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

UNIDAD 1

1.1. Introducción al SQL


1.2. ¿Qué se puede hacer con SQL?
1.3. Breve historia del SQL
1.4. Bases de datos relacionales
1.5. Inicio al SQL
1.1. Introducción al SQL

SQL (Structured Query Language o lenguaje de consulta estructurado) es un potente


lenguaje normalizado, que se utiliza como lenguaje de comunicación con bases de datos.

Nos permite embeberlo en cualquier lenguaje (PHP, Java, ASP...) para trabajar en
combinación con cualquier sistema de bases de datos como pueda ser Access, MySQL, SQL
Server... asumiendo que en el uso de los diferentes sistemas de bases de datos pueden darse
unas diferencias de sintaxis mínimas, que no afectarán en ningún caso a la esencia del propio
lenguaje SQL.

1.2. ¿Qué se puede hacer con SQL?

Hemos comentado en la introducción que SQL es (a grandes rasgos) el lenguaje que permite
comunicar una aplicación programada en cualquier lenguaje con un sistema de base de datos.

Esto significa que SQL nos permitirá crear y manipular bases de datos, crear tablas, insertar
o eliminar datos, realizar consultas sobre ellos, ... todo tipo de operaciones sobre bases de
datos.

En este curso aprenderemos su utilización y manejo.

1.3. Breve historia del SQL

La historia de SQL (que se pronuncia deletreando en inglés las letras que lo componen, es
decir “ese-cu-ele” y no “siquel” como se oye a menudo) empieza en 1974 con la definición,
por parte de Donald Chamberlin y de otras personas que trabajaban en los laboratorios de
investigación de IBM, de un lenguaje para la especificación de las características de las bases
de datos que adoptaban el modelo relacional. Este lenguaje se llamaba SEQUEL (Structured
English Query Language) y se implementó en un prototipo llamado SEQUEL-XRM entre 1974 y
1975. Las experimentaciones con ese prototipo condujeron, entre 1976 y 1977, a una revisión
del lenguaje (SEQUEL/2), que a partir de ese momento cambió de nombre por motivos legales,
convirtiéndose en SQL. El prototipo (System R), basado en este lenguaje, se adoptó y utilizó
internamente en IBM y lo adoptaron algunos de sus clientes elegidos. Gracias al éxito de
este sistema, que no estaba todavía comercializado, también otras compañías empezaron
a desarrollar sus productos relacionales basados en SQL. A partir de 1981, IBM comenzó
a entregar sus productos relacionales y en 1983 empezó a vender DB2. En el curso de los
años ochenta, numerosas compañías (por ejemplo Oracle y Sybase, sólo por citar algunos)
comercializaron productos basados en SQL, que se convierte en el estándar industrial de hecho
por lo que respecta a las bases de datos relacionales.

En 1986, el ANSI adoptó SQL (sustancialmente adoptó el dialecto SQL de IBM) como
estándar para los lenguajes relacionales y en 1987 se transfomó en estándar ISO. Esta versión
del estándar va con el nombre de SQL/86. En los años siguientes, éste ha sufrido diversas
revisiones que han conducido primero a la versión SQL/89 y, posteriormente, a la actual SQL/92.

El hecho de tener un estándar definido por un lenguaje para bases de datos relacionales
abre potencialmente el camino a la intercomunicabilidad entre todos los productos que se
basan en él. Desde el punto de vista práctico, por desgracia las cosas fueron de otro modo.
Efectivamente, en general cada productor adopta e implementa en la propia base de datos
sólo el corazón del lenguaje SQL (el así llamado Entry level o al máximo el Intermediate level),
extendiéndolo de manera individual según la propia visión que cada cual tenga del mundo de
las bases de datos.

Actualmente, está en marcha un proceso de revisión del lenguaje por parte de los comités
ANSI e ISO, que debería terminar en la definición de lo que en este momento se conoce
como SQL3. Las características principales de esta nueva encarnación de SQL deberían ser su
transformación en un lenguaje stand-alone (mientras ahora se usa como lenguaje hospedado
en otros lenguajes) y la introducción de nuevos tipos de datos más complejos que permitan,
por ejemplo, el tratamiento de datos multimediales.

1.4. Bases de datos relacionales

Puesto que SQL es un lenguaje diseñado para trabajar sobre bases de datos relacionales, es
imprescindible tener una clara referencia de qué son exactamente este tipo de bases de datos
y que propiedades las caracterizan, para entender como funcionan y poder trabajar con ellas
de una manera eficiente.

1.4.1. ¿Qué es una base de datos relacional?

Una base de datos relacional es una base de datos que cumple con el modelo relacional,
que es el modelo más utilizado en la actualidad para modelar problemas reales y administrar
datos dinámicamente.

Las bases de datos relacionales permiten establecer interconexiones (relaciones) entre los
datos (que están guardados en tablas), y trabajar con ellos conjuntamente. Tras ser postuladas
sus bases en 1970 por Edgar Frank Codd, de los laboratorios IBM en San José (California), no
tardó en consolidarse como un nuevo paradigma en los modelos de base de datos.

En la siguiente figura se representa un esquema de una base de datos con el modelo


relacional.
1.4.2. Diseño del esquema de la base de datos

Es de gran importancia realizar un buen diseño de la base de datos (siempre basado en un


estudio previo de los requisitos que la BD debe cumplir, según las necesidades del cliente), para
garantizar un uso eficiente tanto del espacio que va a ocupar como del tiempo que va a costar
realizar operaciones sobre ella y obtener un resultado, garantizando aspectos tan importantes
como la integridad de los datos, la privacidad de los mismos si es necesario, o la seguridad ante
fallos del sistema.

En la estructura de la BD se diferencia entre:


• Estructura Lógica: se trata de una representación gráfica, mediante símbolos y signos
normalizados, de la base de datos. Su objetivo es representar la estructura de los datos y las
dependencias de los mismos, garantizando la consistencia y evitando la duplicidad.
• Estructura Física: se trata del almacén de los datos, es la base de datos en sí misma, el
soporte donde se almacenan los datos y de donde se extraen para convertir los datos en
información. Las reglas de almacenamiento varían en función del gestor de bases de datos
empleado.

Existen una serie de criterios importantes a tener en cuenta para garantizar la calidad del
diseño de la BD, algunos de los más esenciales se reflejan a continuación:
• Legibilidad: El diseño de una base de datos se redactará de una forma clara y concisa
para que pueda ser entendido rápidamente, suficientemente detallada para que explique
con total claridad el diseño del modelo, sus objetivos, sus restricciones... y en general todo
aquello que afecte al sistema en cualquier forma.

• Portabilidad: El diseño de la base de datos deberá permitir la implementación del modelo


físico en gestores diferentes.

• Modificabilidad: Adaptabilidad de la base de datos a las nuevas necesidades, por lo que se


necesita que un buen diseño facilite el mantenimiento, las modificaciones y actualizaciones
que sean necesarias en cada momento.

• Eficiencia: Se deben aprovechar al máximo los recursos disponibles, minimizando la


memoria utilizada y el tiempo de proceso o ejecución, en la medida en que otros requisitos
importantes no se vean afectados.
• Fiabilidad: Se buscará diseñar un sistema de bases de datos lo suficientemente robusto
para que sea capaz de recuperarse frente a errores o usos inadecuados por parte del
usuario.

• Coherencia: Se mantendrá uniformidad en las anotaciones y terminología utilizada, para


ello se debe seguir algún tipo de metodología estándar, indicado cual se ha empleado.
En los casos en que se utilice alguna metodología no estándar se debe adjuntar a la
documentación precisando la terminología que se seguirá.

• Concisión: Se evitarán aquellos elementos inútiles y redundantes. En este apartado hay


que prestar especial atención en la repetición de datos en diferentes tablas, hay que evitar
que el mismo dato se repita en varias tablas de la base de datos.

• Generalidad: Se intentará que la base de datos que diseñemos sea capaz de adaptarse a
cualquier circunstancia en la medida de lo posible.

• Independencia de Sistema: Las prestaciones y diseño de la base de datos no deben estar


ligadas al entorno actual.

• Independencia de usuario: La base de datos no debe estar ligada a la utilización en una


única instalación, hay que tener en cuenta que en un futuro se podría realizar la instalación
en un cliente diferente.

• Independencia de Instalación: Es interesante que la base de datos se pueda migrar


fácilmente de una instalación a otra en caso de que fuera necesario.

• Modularidad: La base de datos puede estar compuesta por diversos elementos


independientes, creando módulos funcionales que facilitarán el diseño y la posterior
implantación.

• Precisión: Los cálculos efectuados deben ser lo más precisos posibles para un óptimo
funcionamiento de la base de datos.
• Protección: El diseño de la base de datos debe permitir la protección de los datos frente
a usos indebidos, por lo que hay que elaborar un sistema de accesos definiendo diferentes
usuarios con claves personalizadas y especificar los permisos de cada uno de ellos sobre los
datos almacenados.

1.4.3. Modelo Relacional

Las bases de datos que implementan el modelo relacional son el tipo de bases de datos más
difundido actualmente, fundamentalmente debido a estos dos motivos:
1. nos ofrecen sistemas simples y eficaces para representar y manipular los datos.
2. se basan en un modelo teórico con bases muy sólidas.

Un modelo relacional estructura la información que se pretende representar como


entidades y relaciones entre dichas entidades.

Entidades
Una entidad representa un objeto del mundo real con existencia independiente (ya sea
física o conceptual), diferenciándose de forma unívoca de cualquier otro objeto.

Se puede definir cono entidad a cualquier objeto, real o abstracto, que existe en un contexto
determinado o puede llegar a existir y del cual deseamos guardar información, por ejemplo:
“CLIENTE”, “HOTEL”. Las entidades las podemos clasificar en:
• Regulares: aquellas que existen por sí mismas y que la existencia de un ejemplar en
la entidad no depende de la existencia de otros ejemplares en otra entidad. Por ejemplo
“CLIENTE”. La representación gráfica dentro del diagrama es la siguiente:

CLIENTE

• Débiles: son aquellas entidades en las que se hace necesaria la existencia de ejemplares
de otras entidades distintas para que puedan existir ejemplares en esta entidad. Un ejemplo
sería la entidad “ALBARÁN” que sólo existe si previamente existe el correspondiente pedido.
La representación gráfica dentro del diagrama es la siguiente:
ALBARÁN

Atributos
Las entidades se componen de atributos que son cada una de las propiedades o características
que tienen las entidades. Cada ejemplar de una misma entidad posee los mismos atributos,
tanto en nombre como en número, diferenciándose cada uno de los ejemplares por los valores
que toman dichos atributos. Si consideramos la entidad “CLIENTE” y definimos los atributos
Nombre, DNI, Direccion, contato podríamos obtener los siguientes registros:
{Luis Perez, 50699878, Juglares 26, luis@[Link]}
{Antonio López, 48697878, luna 25, antonio@[Link]}
{Ana Martin, 33333878, castilla 12, ana@[Link]}

Existen cuatro tipos de atributos:


• Obligatorios: aquellos que deben tomar un valor y no se permite ningún ejemplar no
tenga un valor determinado en el atributo.
• Opcional: aquellos atributos que pueden tener valores o no tenerlo.
• Monoevaluado: aquel atributo que sólo puede tener un único valor.
• Multievaluado: aquellos atributos que pueden tener varios valores.

La representación gráfica de los atributos, en función del tipo es la siguiente:

Multievaluado Obligatorio Multievaluado Opcional

Contácto Teléfono

Monoevaluado Obligatorio Monoevaluado Opcional

Nombre Edad

Dentro del diagrama la entidad “CLIENTE” y sus atributos quedarían de la siguiente forma:
Contacto Teléfono

ALBARÁN

Nombre Edad

Existen atributos, llamados derivados, cuyo valor se obtiene a partir de los valores de otros
atributos. Pongamos como ejemplo la entidad “CLIENTE” que tiene los atributos “NOMBRE”,
“FECHA DE NACIMIENTO”, “EDAD”; el atributo “EDAD” es un atributo derivado por que se
calcula a partir del valor del atributo “FECHA DE NACIMIENTO”. Su representación gráfica es la
siguiente:

En determinadas ocasiones es necesaria la descomposición de un atributo para definirlos


en más de un dominio, podría ser el caso del atributo “TELEFONO” que toma valores del
dominio “PREFIJOS” y del dominio “NUMEROS DE TELEFONO”. Estos atributos se representan
de la siguiente forma:

Ejemplo:

Se pide diseñar una base de datos para un pequeño hotel donde se tendrán en cuenta los
clientes y las habitaciones.

Clientes es una entidad, que podría guardar, como atributos, los siguientes:
• DNI
• nombre
• dirección
• contacto

Habitaciones es otra entidad, de la que se pueden guardar los siguientes datos:


• numero de habitación
• tipo
• precio

Dominios
Se define dominio como un conjunto de valores que puede tomar un determinado atributo
dentro de una entidad. Por ejemplo:
Atributo Dominio
Fecha de Alta Calendario Gregoriano
Teléfono Conjunto de números de teléfonos
Edad 0 - 120

De forma casi inherente al término dominio aparece el concepto restricción para un atributo.
Cada atributo puede adoptar una serie de valores de un dominio restringiendo determinados
valores. El atributo “EDAD” toma sus valores del dominio N (números naturales) pero se puede
poner como restricción aquellos que estén en un intervalo por ejemplo de (0-120).

Claves
El modelo entidad - relación exige que cada entidad tenga un identificador, se trata de un
atributo o conjunto de atributos que identifican de forma única a cada uno de los ejemplares
de la entidad. De tal forma que ningún par de ejemplares de la entidad puedan tener el mismo
valor en ese identificador.

Un ejemplo de identificador es el atributo “DNI” que, en la entidad “ESPAÑOLES”, identifica


de forma única a cada uno de los españoles. Estos identificadores reciben en nombre de
Identificador Principal (IP) o Clave Primaria (PK - Primary Key-). Se puede dar el caso de existir
algún identificador más en la entidad, a estos identificadores se les denomina Identificadores
Candidatos (IC).

Los atributos identificadores de una entidad se representan en los diagramas de la siguiente


forma:

Relaciones

Las relaciones representan una asociación entre dos o más entidades, describiendo
dependencias entre ellas
Ejemplo:
Siguiendo el ejemplo anterior, la relación que completaría el diseño anterior sería la Reserva
(un Cliente reserva Habitaciones, o lo que es igual, una Habitación es reservada por un Cliente).

En un diseño de Entidad – Relación, esto se representaría de la siguiente forma:

dni reserva

cliente habitación

nombre dirección contacto contacto tipo precio

Figura 1

En el caso que nos ocupa, se establecerían como claves primarias, es decir, las que se
utilizarán como índices únicos de identificación, el DNI de cada Cliente y el Número de cada
Habitación

Cardinalidad
Es importante tener en cuenta la cardinalidad de las relaciones entre entidades, es decir
cuántos elementos como máximo y como mínimo intervienen en la relación.

• Interrelaciones uno a uno


Una interrelación es de uno a uno entre la tabla A y la tabla B cuando a cada elemento de
la clave de A se le asigna un único elemento de la tabla B y para cada elemento de la clave
de la tabla B contiene un único elemento en la tabla A. Un ejemplo de interrelación de este
tipo es la formada por las tablas Datos Generales de Clientes y Datos Contables de Clientes.
En esta relación cada cliente tiene una única dirección y una dirección en cada una de las
tablas. Representamos la relación como A 1: 1 B.

Ante la presencia de este tipo de relación nos podemos plantear el caso de unificar todos
los datos en única tabla pues no es necesario mantener ambas tablas a la misma vez.
Este tipo de relación se genera cuando aparecen tablas muy grandes, con gran cantidad
de campos, disgregando la tabla principal en dos para evitar tener una tabla muy grande.
También surge cuando los diferentes grupos de usuario cumplimentan una información
diferente para un mismo registros; en este caso se crean tantas tablas como registros,
evitando así tener que acceder a información que el usuario del grupo actual no necesita

• Interrelaciones uno a varios


Una interrelación es de uno a varios entre las tablas A y B cuando una clave de la tabla A
posee varios elementos relacionados en la tabla B y cuando una clave de la tabla B posee
un único elemento relacionado en la tabla A.

Estudiemos la relación entre un tabla de clientes y una tabla de pedidos. Un cliente puede
realizar varios pedidos pero un pedido pertenece a un único cliente, por tanto se trata de
una relación uno a varios y la representamos A 1: n B. Estas relaciones suelen surgir de
aplicar la 1NF a una tabla.

Muchas a una (N,1): una entidad A está asociada a una entidad B, pero una entidad B está
asociada a varias entidades A.

• Interrelaciones varios a varios


Una interrelación es de varios a varios entre las tablas A y B cuando una clave de la tabla A
posee varios elementos relacionados en la tabla B y cuando una clave de la tabla B posee
varios elementos relacionados en la tabla A.

Un caso muy característico de esta interrelación es la que surge entre las tablas de Puestos
de Trabajo y Empleados de una empresa. Un Empleado puede desempeñar realizar varias
funciones dentro de una empresa (desempeñar varios puestos de trabajo), y un puesto de
trabajo puede estar ocupado por varios empleados a la misma vez. Esta interrelación la
representamos como A n: n B.

No se deben definir relaciones de este tipo en un sistema de bases de datos, debido a su


complejidad a la hora de su mantenimiento, por este motivo se debe transformar este
tipo de relación es dos interrelaciones de tipo 1: n, empleando para ello una tabla que
denominaremos puente y que estará formada por las claves de ambas tablas. Esta tabla
puente debe contener una única clave compuesta formada por los campos clave de las
tablas primeras.
Ejemplo:
En nuestro ejemplo anterior, vemos que la cardinalidad de la relación es de una a muchos:
Un cliente puede reservar varias habitaciones, pero cada habitación solo puede estar reservada
por un cliente.

Figura 2: Creación de la base de datos

Problemas con la cardinalidad


A la hora de establecer la cardinalidad existente en un sistema de bases de datos nos
podemos encontrar dos problemas:
1. Cardinalidad recursivas: un elemento se relaciona consigo mismo directamente.
2. Cardinalidad circulares o cíclicas: A se relaciona con B, B se relaciona con C y C se relaciona
con A.

Ambos casos pueden suponer un grave problema si definimos una relación con integridad
referencial y decimos eliminar en cascada (al eliminar una clave de la tabla A se eliminan los
elementos relacionados en la tabla B). Supongamos la relación recursiva existen en la relación
Empleado y Supervisor (ambos son empleados de la empresa). Está claro que un empleado
está supervisado por otro empleado.

Veamos la forma de solucionarlo:

Empleados
Código Nombre Supervisor
102 Juan NO
105 Luis SI
821 María NO
956 Martín SI

Para solucionar la relación debemos crear una tabla formada por dos campos. Ambos
campos deben ser el código del empleado pero como no podemos tener dos campos con el
mismo nombre a uno de ellos le llamaremos código supervisor.

Tabla Puente
Código Empleado Código Supervisor
102 105
105 956
821 105
956 105

Para terminar de resolver la interrelación recursiva basta con definir dos interrelaciones
entre la tabla empleados y la tabla puente de tipo 1: n. La primera relación se crea
utilizando las claves Empleados[Código] y Tabla Puente[Código Empleado]. La segunda entre
Empleados[Código] y Tabla Puente [Código Supervisor].

Las interrelaciones cíclicas o circulares no son muy frecuentes y no existe una metodología
estándar para su eliminación, normalmente son debidas a errores de diseño en la base de
datos, principalmente en el diseño conceptual del sistema de datos. Por tanto si llegamos a
este punto hay que volver a replantearse todo el diseño de la base de datos.
Atributos de las interrelaciones
En la mayoría de las interrelaciones definidas será conveniente exigir integridad relacional
entre las claves. Exigiendo la integridad referencial se consigue que en una relación de tipo
1: n o de tipo 1: 1, no se puede añadir ningún valor en la tabla destino si no existe en la tabla
origen. Dicho con un ejemplo: en la relación Clientes y Pedidos la tabla Pedidos contiene un
campo que se corresponde con el código del Cliente, si se exige la integridad referencia no se
podrá escribir un código de cliente en la tabla Pedidos que no exista en la tabla Clientes; de no
exigir la integridad referencial se podrán crear pedidos con códigos de clientes que no existen,
generando incongruencia de datos en la base de datos.

Definida la integridad referencial (siempre necesaria) podemos exigir la actualización


en cascada (siempre necesaria); esta actualización implica que si cambiamos el código a un
cliente, debemos actualizar dicho código en la tabla de pedidos, de no ser así, al cambiar el
código a un cliente, perderemos los pedidos que tenía realizados.

Para concluir debemos hablar de la eliminación en cascada (NO siempre necesaria), la


eliminación en cascada consiste en eliminar todos los datos dependientes de una clave. En
nuestro ejemplo implica que al borrar un cliente hay que eliminar todos los pendidos que
ha realizado. En muchas ocasiones no interesa realizar esta operación de eliminación en
cascada por motivos diversos. Si en el caso de clientes y pedidos no se exige eliminación
en cascada no se podrá borrar ningún cliente en tanto en cuanto tenga realizado algún
pedido (de lo contrario tendríamos incongruencia de datos).

1.4.4. Álgebra Relacional

Las operaciones de álgebra relacional trabajan con relaciones, lo que significa que estas
operaciones usan una o más relaciones existentes para crear una nueva relación. Esta nueva
relación puede entonces usarse como entrada para una nueva operación. Este concepto
tan potente, la creación de una nueva relación a partir de relaciones existentes, hace
considerablemente más fácil la solución de las consultas, debido a que se puede experimentar
con soluciones parciales hasta encontrar la qué más se adecue a nuestras necesidades.

A continuación se detallan las operaciones que define el álgebra relacional:


Unión
La operación de unión permite combinar datos de varias relaciones. No siempre es posible
realizar consultas de unión entre varias tablas, para poder realizar esta operación es necesario
e imprescindible que las tablas a unir tengan las mismas estructuras, que sus campos sean
iguales.

Intersección
La operación de intersección permite identificar filas que son comunes en dos relaciones.

Diferencia
La operación diferencia permite identificar filas que están en una relación y no en otra.
Tomando como referencia el caso anterior, deberíamos aplicar una diferencia entre la tabla
empleados y la tabla asistentes al curso para saber aquellos asistentes externos a la organización
que han asistido al curso.

Producto cartesiano
La operación producto consiste en la realización de un producto cartesiano entre dos tablas
dando como resultado todas las posibles combinaciones entre los registros de la primera y los
registros de la segunda.

Selección
La operación selección consiste en recuperar un conjunto de registros de una tabla o de
una relación indicando las condiciones que deben cumplir los registros recuperados, de tal
forma que los registros devueltos por la selección han de satisfacer todas las condiciones que
se hayan establecido. Esta operación es la que normalmente se conoce como consulta.

Los diferentes operadores que pueden emplearse en este tipo de consulta son los
operadores de comparación (=,>, <, >=, <=, <>), los operadores lógicos (and, or, xor) o la
negación lógica (not).

Proyección
La proyección es un caso concreto de la operación selección, que devuelve todos los
campos de aquellos registros que cumplen la condición que he establecido. Una proyección es
una selección en la que seleccionamos aquellos campos que deseamos recuperar.
Reunión
Se utiliza para recuperar datos a través de varias tablas conectadas unas con otras mediante
cláusulas JOIN, en cualquiera de sus tres variantes INNER, LEFT, RIGHT. La operación reunión se
puede combinar con las operaciones selección y proyección.

División
La operación división es la contraria a la operación producto.

Queda formada por las tuplas que al completarse con las tuplas de la segunda relación
permiten obtener la primera.

Asignación
Esta operación algebraica consiste en asignar un valor a5 uno o varios campos de una tabla.

1.4.5. Normalización

Todo diseño de modelo relacional deberá someterse a un proceso de normalización.

El proceso de normalización es un estándar que consiste, básicamente, en un proceso de


conversión de las relaciones entre las entidades, evitando:
• La redundancia de los datos: repetición de datos en un sistema.
• Anomalías de actualización: inconsistencias de los datos como resultado de datos
redundantes y actualizaciones parciales.
• Anomalías de borrado: pérdidas no intencionadas de datos debido a que se han borrado
otros datos.
• Anomalías de inserción: imposibilidad de adicionar datos en la base de datos debido a la
ausencia de otros datos.

Tomando como referencia la tabla siguiente:

AUTORES Y LIBROS
NOMBRE NACION CODLIBRO TITULO EDITOR
Date POR 111 BHJ MH
[Link]. ESP 222 JJP AN
[Link]. ITA 333 PYC AN
Date FRAN 444 LMN RM
Se plantean una serie de problemas:
• Redundancia: cuando un autor tiene varios libros, se repite la nacionalidad.
• Anomalías de modificación: Si [Link]. y [Link]. desean cambiar de editor, se modifica
en los 2 lugares. A priori no podemos saber cuántos autores tiene un libro. Los errores son
frecuentes al olvidar la modificación de un autor. Se pretende modificar en un sólo sitio.
• Anomalías de inserción: Se desea dar de alta un autor sin libros, en un principio. NOMBRE
y CODLIBRO son campos clave, una clave no puede tomar valores nulos.
Asegurando:
• Integridad entre los datos: consistencia de la información.

El proceso de normalización nos conduce hasta el modelo físico de datos y consta de varias
fases denominadas formas normales, estas formas se detallan a continuación.

Definición de la clave
Antes de proceder a la normalización de la tabla lo primero que debemos de definir es
una clave, esta clave deberá contener un valor único para cada registro (no podrán existir dos
valores iguales en toda la tabla) y podrá estar formado por un único campo o por un grupo de
campos.

En la tabla de alumnos de un centro de estudios no podemos definir como campo clave el


nombre del alumno ya que pueden existir varios alumnos con el mismo nombre. Podríamos
considerar la posibilidad de definir como clave los campos nombre y apellidos, pero estamos
en la misma situación: podría darse el caso de alumnos que tuvieran los mismos apellidos y el
mismo nombre (Luis López Sánchez).

La solución en este caso es asignar un código de alumno a cada uno, un número que
identifique al alumno y que estemos seguros que es ú[Link] vez definida la clave podremos
pasar a estudiar la primera forma normal.

Primera forma normal (1NF)


Se dice que una tabla se encuentra en primera forma normal (1NF) si y solo si cada uno de
los campos contiene un único valor para un registro determinado. Supongamos que deseamos
realizar una tabla para guardar los cursos que están realizando los alumnos de un determinado
centro de estudios, podríamos considerar el siguiente diseño:
Código Nombre Cursos
1 Ana Chino
2 Luis Francés, Informática
3 Juan Inglés, Contabilidad

Podemos observar que el registro de código 1 si cumple la primera forma normal, cada
campo del registro contiene un único dato, pero no ocurre así con los registros 2 y 3 ya que en
el campo cursos contiene más de un dato cada uno. La solución en este caso es crear dos tablas
del siguiente modo:

TABLA A TABLA B
Código Nombre Código Curso
1 Ana 1 Chino
2 Luis 2 Francés
3 Juan 2 Informática
3 Inglés
3 Contabilidad

Como se puede comprobar ahora todos los registros de ambas tablas contienen valores
únicos en sus campos, por lo tanto ambas tablas cumplen la primera forma normal.
Una vez normalizada la tabla en 1NF, podemos pasar a la segunda forma normal.

Segunda forma normal (2NF)


La segunda forma normal compara todos y cada uno de los campos de la tabla con la clave
definida. Si todos los campos dependen directamente de la clave se dice que la tabla está es
segunda forma normal (2NF).

Supongamos que construimos una tabla con los años que cada empleado ha estado
trabajando en cada departamento de una empresa:
Código Empleado Código Dpto. Nombre Departamento Años
1 4 Ana Contabilidad 6
2 2 Luis Sistemas 3
3 3 Juan I+D 1
4 1 Rosa Auditoria 10
2 4 Luis Contabilidad 5

Tomando como punto de partida que la clave de esta tabla está formada por los campos
código de empleado y código de departamento, podemos decir que la tabla se encuentra en
primera forma normal, por tanto vamos a estudiar la segunda:
1. El campo nombre no depende funcionalmente de toda la clave, sólo depende del código
del empleado.
2. El campo departamento no depende funcionalmente de toda la clave, sólo del código del
departamento.
3. El campo años si que depende funcionalmente de la clave ya que depende del código
del empleado y del código del departamento (representa el número de años que cada
empleado ha trabajado en cada departamento)

Por tanto, al no depender todos los campos de la totalidad de la clave la tabla no está en
segunda forma normal, la solución es la siguiente:

Tabla A Tabla B Tabla C


Código Código Código Código
Nombre Dpto. Años
Empleado Departamento Empleado Departamento
1 Ana 1 Auditoria 1 4 6
2 Luis 2 Sistemas 2 2 3
3 Juan 3 I+D 3 3 1
4 Rosa 4 Contabilidad 4 1 10
2 4 5

Podemos observar que ahora si se encuentras las tres tablas en segunda forma normal, con-
siderando que la tabla A tiene como índice el campo Código Empleado, la tabla B Código Departa-
mento y la tabla C una clave compuesta por los campos Código Empleado y Código Departamento.
Tercera forma normal (3NF)
Se dice que una tabla está en tercera forma normal si y solo si los campos de la tabla
dependen únicamente de la clave, dicho en otras palabras los campos de las tablas no dependen
unos de otros. Tomando como referencia el ejemplo anterior, supongamos que cada alumno
sólo puede realizar un único curso a la vez y que deseamos guardar en que aula se imparte el
curso. A voz de pronto podemos plantear la siguiente estructura:

Código Nombre Curso Aula


1 Ana Chino Aula A
2 Luis Francés Aula B
3 Juan Informática Aula C

Estudiemos la dependencia de cada campo con respecto a la clave código:


• Nombre depende directamente del código del alumno.
• Curso depende de igual modo del código del alumno.
• El aula, aunque en parte también depende del alumno, está más ligado al curso que el
alumno está realizando.

Por esta última razón se dice que la tabla no está en 3NF. La solución sería la siguiente:

Tabla A Tabla B

Código Nombre Curso Curso Aula

1 Ana Chino Chino Aula A

2 Luis Francés Francés Aula B

3 Juan Informática Informática Aula C

Una vez conseguida la tercera forma normal, se puede estudiar la cuarta forma normal.

Cuarta forma normal (4NF)


Una tabla está en cuarta forma normal si y sólo si para cualquier combinación clave - campo
no existen valores duplicados. Veámoslo con un ejemplo:
Geometría
Figura Color Tamaño
Triangulo Amarillo Pequeño
Triangulo Rojo Pequeño
Triangulo Rojo Mediano
Rectángulo Verde Mediano
Rectángulo Azul Grande
Rectángulo Azul Mediano

Comparemos ahora la clave (Figura) con el atributo Tamaño, podemos observar que Cua-
drado Grande está repetido; igual pasa con Círculo Azul, entre otras. Estas repeticiones son las
que se deben evitar para tener una tabla en 4NF.

La solución en este caso sería la siguiente:

Tamaño Color
Figura Tamaño Figura Color
Rectángulo Grande Rectángulo Verde
Rectángulo Mediano Rectángulo Azul
Triangulo Mediano Triangulo Amarillo
Triangulo Pequeño Triangulo Rojo

Ahora si tenemos nuestra base de datos en 4NF.

Otras formas normales


Existen otras dos formas normales:
• La quinta forma normal (5FN) que no detallo por su dudoso valor práctico ya que conduce
a una gran división de tablas.
• La forma normal dominio / clave (FNDLL) de la que no existe método alguno para su
implantación.
1.5. Inicio al SQL

SQL es un lenguaje que se compone por diversos elementos: comandos, cláusulas,


operadores y funciones de agregado, los cuales se combinan en instrucciones para crear,
actualizar y manipular las bases de datos y las tablas de que se componen.

1.5.1. Comandos

Los tipos de comandos SQL son los siquientes:


• DLL que permiten crear y definir nuevas bases de datos, campos e índices.
- CREATE: para crear nuevas tablas, campos e índices.
- DROP: para eliminar tablas e índices.
- ALTER: para modificar las tablas agregando campos o cambiando la definición de los
campos.
• DML que permiten generar consultas para ordenar, filtrar y extraer datos de la base de
datos.
- SELECT: para consultar registros de la base de datos que satisfagan un criterio
determinado
- INSERT: para cargar lotes de datos en la base de datos en una única operación.
- UPDATE: para modificar los valores de los campos y registros especificados.
- DELETE: para eliminar registros de una tabla de una base de datos.

1.5.2. Cláusulas

Son condiciones de modificación, que se utilizan para definir los datos que desea seleccionar
o manipular.
• FROM: para especificar la tabla de la cual se van a seleccionar los registros
• WHERE: para especificar las condiciones que deben reunir los registros que se van a
seleccionar
• GROUP BY: para separar los registros seleccionados en grupos específicos
• HAVING: para expresar la condición que debe satisfacer cada grupo
• ORDER BY: para ordenar los registros seleccionados de acuerdo con un orden específico

En una sentencia SQL de selección que incluya todas las posibles cláusulas, el orden de
ejecución de las mismas sería el siguiente:
1. Cláusula FROM
2. Cláusula WHERE
3. Cláusula GROUP BY
4. Cláusula HAVING
5. Cláusula SELECT
6. Cláusula ORDER BY

1.5.3. Operadores

• Lógicos
- AND: Es el “y” lógico. Evalúa dos condiciones y devuelve un valor de verdad sólo si
ambas son ciertas.
- OR: Es el “o” lógico. Evalúa dos condiciones y devuelve un valor de verdad si alguna de
las dos es cierta.
- NOT: Negación lógica. Devuelve el valor contrario de la expresión.
• De comparación
- < Menor que
- > Mayor que
- <> Distinto de
- <= Menor o igual que
- >= Mayor o igual que
- = Igual que
- BETWEEN: para especificar un intervalo de valores.
- LIKE: para la comparación de un modelo
- IN: para especificar registros de una base de datos

1.5.4. Funciones de Agregado

Estas funciones se usan dentro de una cláusula SELECT, en grupos de registros, para devolver
un valor único que se aplica a un grupo de registros.
• AVG: para calcular el promedio de los valores de un campo determinado.
• COUNT: para devolver el número de registros de la selección.
• SUM: para devolver la suma de todos los valores de un campo determinado.
• MAX: para devolver el valor más alto de un campo especificado.
• MIN: para devolver el valor más bajo de un campo especificado.
UNIDAD 2
2.1. Tipos de Datos
2.2. Consultas de acción
2.1. Tipos de Datos

Para poder trabajar con el lenguaje SQL es esencial conocer los tipos de datos que admite.
Estos tipos de datos SQL se clasifican en tipos de datos primarios y en sinónimos válidos
reconocidos por dichos tipos de datos.

A continuación se presentan dos tablas detalladas de los mismos:


• Tipos de datos primarios:

Tipo de Datos Tamaño Descripción


Para consultas sobre tabla adjunta de productos de bases de
BINARY 1 byte
datos que definen un tipo de datos Binario.
BIT 1 byte Valores Si/No ó True/False
BYTE 1 byte Un valor entero entre 0 y 255.
COUNTER 4 bytes Un número incrementado automáticamente (de tipo Long)
Un entero escalable entre [Link].477,5808 y
CURRENCY 8 bytes
[Link].477,5807.
DATETIME 8 bytes Un valor de fecha u hora entre los años 100 y 9999.
Un valor en punto flotante de precisión simple con un rango
SINGLE 4 bytes de - 3.402823*1038 a -1.401298*10-45 para valores negativos,
1.401298*10- 45 a 3.402823*1038 para valores positivos, y 0.
Un valor en punto flotante de doble precisión con un rango
de - 1.79769313486232*10308 a -4.94065645841247*10-
DOUBLE 8 bytes 324
para valores negativos, 4.94065645841247*10-324 a
1.79769313486232*10308 para valores positivos, y 0.
SHORT 2 bytes Un entero corto entre -32,768 y 32,767.
LONG 4 bytes Un entero largo entre -2,147,483,648 y 2,147,483,647.
1 byte por
LONGTEXT De cero a un máximo de 1.2 gigabytes.
carácter
Según se
LONGBINARY De cero 1 gigabyte. Utilizado para objetos OLE.
necesite
1 byte por
TEXT De cero a 255 caracteres.
carácter
• Sinónimos de los tipos de datos definidos:

Tipo de Dato Sinónimos


BINARY VARBINARY
BOOLEAN
LOGICAL
BIT
LOGICAL1
YESNO
BYTE INTEGER1
COUNTER AUTOINCREMENT
CURRENCY MONEY
DATE
DATETIME TIME
TIMESTAMP
FLOAT4
SINGLE IEEESINGLE
REAL
FLOAT
FLOAT8
DOUBLE IEEEDOUBLE
NUMBER
NUMERIC
INTEGER2
SHORT
SMALLINT
INT
LONG INTEGER
INTEGER4
GENERAL
LONGBINARY
OLEOBJECT
LONGCHAR
LONGTEXT MEMO
NOTE
ALPHANUMERIC
TEXT CHAR - CHARACTER
STRING - VARCHAR
VARIANT (No Admitido) VALUE
2.2. Consultas de acción

Las consultas de acción son aquellas que no devuelven ningún resultado, sino que ejecutan
una operación.

Se presenta este tipo de sentencias en primer lugar para mostrar el proceso


completo de creación de las tablas que compongan la base de datos, la inserción o
borrado de datos, y por último, la ejecución de consultas sobre ellas.

2.2.1. Creación de tablas

Como ya se ha visto anteriormente, una base de datos en un sistema relacional está


compuesta por un conjunto de tablas, que corresponden a las relaciones del modelo relacional.

Una sentencia de creación de tablas en SQL seguiría una estructura como la siguiente:

CREATE TABLE tabla


( campo1 tipo (tamaño) índice1,
campo2 tipo (tamaño) índice2,
... ,
índice multicampo , ... )

• Tabla: Es el nombre de la tabla que se va a crear.


• Campo1, campo2... : Es el nombre del campo o de los campos que se van a crear en la
nueva tabla. La nueva tabla debe contener, al menos, un campo.
• Tipo: Es el tipo de datos de campo en la nueva tabla.
• Tamaño: Es el tamaño del campo sólo se aplica para campos de tipo texto.
• Índice1, índice2...: Es una cláusula CONSTRAINT, opcional, que define el tipo de índice a
crear.
• Índice multicampo: Es una cláusula CONSTRAINT, opcional, que define el tipo de índice
multicampo a crear.
• Un índice multicampo es aquél que está indexado por el contenido de varios campos.
Ejemplo:
CREATE TABLE Clientes
( Nombre TEXT (50),
Direccion TEXT (50),
Contacto TEXT (10)
)

Ejemplo:
CREATE TABLE Clientes
( DNICliente INTEGER CONSTRAINT IndicePrimario PRIMARY KEY,
Nombre TEXT (50),
Direccion TEXT (50),
Contacto TEXT (10)
)

Figura 3: Creación de la tabla clientes

Como se muestra en los ejemplos previos, una tabla puede crearse directamente con el
campo que va a servir como clave, indicando que va a ser índice y de qué tipo, o bien puede
crearse la tabla únicamente con los campos que va a contener como información y más
adelante ya se incorporará el índice.

A continuación desarrollaremos las cláusulas CONSTRAINT para detallar su utilización.


2.2.2. La cláusula CONSTRAINT

La cláusula CONSTRAINT se utiliza en las instrucciones ALTER TABLE y CREATE TABLE para
crear o eliminar índices.

Hay dos formas de establecer la sintaxis para esta cláusula, en función de si se desea crear
ó eliminar un índice de un único campo o si se trata de un campo multi-índice.

Para los índices de campos únicos se empleará esta sintaxis:


CONSTRAINT nombre {PRIMARY KEY | UNIQUE | REFERENCES tabla
externa
[(campo externo1, campo externo2)]}

Esta otra se usará para los índices de campos múltiples:


CONSTRAINT nombre {PRIMARY KEY (primario1[, primario2 [,
...]]) |
UNIQUE (único1[, único2 [, ...]]) | FOREIGN KEY (ref1[, ref2
[, ...]]) REFERENCES tabla externa [(campo externo1 [,campo
externo2 [, ...]])]}

• Nombre: Nombre del índice que se va a crear.


• PrimarioN: Nombre del campo o de los campos que forman el índice primario.
• ÚnicoN: Nombre del campo o de los campos que forman el índice de clave única.
• RefN: Nombre del campo o de los campos que forman el índice externo (hacen referencia
a campos de otra tabla).
• Tabla externa: Nombre de la tabla que contiene el campo o los campos referenciados en
refN
• Campos externos: Nombre del campo o de los campos de la tabla externa especificados
por ref1, ref2, ..., refN

En los casos en que se desea crear un índice para un campo cuando se está utilizando
las instrucciones ALTER TABLE (que se detallará más adelante) o CREATE TABLE la cláusula
CONTRAINT debe aparecer inmediatamente después de la especificación del campo indexado.
Cuando se desea crear un índice con múltiples campos mientras se está utilizando las
instrucciones ALTER TABLE o CREATE TABLE la cláusula CONSTRAINT debe aparecer fuera de la
cláusula de creación de tabla.

Figura 4: Ejemplo de constraint

Tipos de índices:
• UNIQUE: Crea un índice de clave única por lo que los registros de la tabla no pueden
contener el mismo valor en los campos indexados.
• PRIMARY KEY: Crea un índice primario el campo o los campos especificados. Al utilizar
este tipo de índice todos los campos de la clave principal deben ser únicos y no nulos, y
cada tabla sólo puede contener una única clave principal.
• FOREIGN KEY: Crea un índice externo, tomando como valor del índice campos contenidos
en otras tablas. Si la clave principal de la tabla externa consta de más de un campo, se
debe utilizar una definición de índice de múltiples campos, listando todos los campos de
referencia, el nombre de la tabla externa, y los nombres de los campos referenciados en
la tabla externa en el mismo orden que los campos de referencia listados. Si los campos
referenciados son la clave principal de la tabla externa, no necesita especificar los campos
referenciados.

2.2.3. Creación de Índices

Para crear un índice en una tabla que ya está definida se hará de la siguiente manera:
CREATE [ UNIQUE ] INDEX índice ON tabla (campo [ASC|DESC][,
campo [ASC|DESC], ...]) [WITH { PRIMARY | DISALLOW NULL | IGNORE
NULL }]
• Índice: Nombre del índice a crear.
• Tabla: Nombre de una tabla existente en la que se creará el índice.
• Campo: Nombre del campo o lista de campos que consituyen el índice.
• ASC|DESC: Indica el orden de los valores de los campos, ASC para un orden ascendente
(valor predeterminado) y DESC para orden descendente.
• UNIQUE: Indica que el índice no puede contener valores duplicados.
• DISALLOW NULL: Prohíbe valores nulos en el índice
• IGNORE NULL: Excluye del índice los valores nulos incluidos en los campos que lo
componen.
• PRIMARY: Asigna al índice la categoría de clave principal, en cada tabla sólo puede existir
un único índice que sea “Clave Principal”. Si un índice es clave principal implica que no
puede contener valores nulos ni duplicados.

Se puede utilizar CREATE INDEX para crear un pseudo índice sobre una tabla adjunta que
no tenga todavía un índice. Se utiliza la misma sintaxis para las tabla adjunta que para las
originales. Esto resulta especialmente útil para crear un índice en una tabla que sería de sólo
lectura debido a la falta de un índice.

Ejemplo:
CREATE INDEX Mi_Indice ON Clientes (Nombre, Dirección,
Contacto);

Crea un índice llamado Mi_Indice en la tabla empleados con los campos Nombre, Dirección
y Contacto.

Ejemplo:
CREATE UNIQUE INDEX Mi_Indice ON Clientes (DNI) WITH DISALLOW
NULL;

Crea un índice en la tabla Clientes utilizando el campo ID, obligando que el campo DNI no
contenga valores nulos ni repetidos, lo cual resultará de gran utilidad para nuestra tabla.
Figura 5: Creación de índices

2.2.4. Modificar el Diseño de una Tabla

Es posible modificar el diseño de una tabla ya existente, cambiando los campos o los índices
existentes de la siguiente forma:

ALTER TABLE tabla {ADD {COLUMN tipo de campo[(tamaño)]


[CONSTRAINT índice]
CONSTRAINT índice multicampo} | DROP {COLUMN campo I
CONSTRAINT nombre del índice} }

• Tabla: Nombre de la tabla que se desea modificar.


• Campo: Nombre del campo que se va a añadir o eliminar.
• Tipo: Tipo de campo que se va a añadir.
• Tamaño: Tamaño del campo que se va a añadir (sólo para campos de texto).
• Índice: Nombre del índice del campo (cuando se crean campos) o el nombre del índice
de la tabla que se desea eliminar.
• Índice multicampo: Nombre del índice del campo multicampo (cuando se crean campos)
o el del índice de la tabla que se desea eliminar.

Las operaciones que se pueden realizar para modificar la estructura de una tabla ya creada
son las siguientes:
• ADD COLUMN: para añadir un nuevo campo a la tabla, indicando el nombre, el tipo de
campo y opcionalmente el tamaño (para campos de tipo texto).
• ADD: para agregar un índice de multicampos o de un único campo.
• DROP COLUMN: para borrar un campo. Se especifica únicamente el nombre del campo.
• DROP: para eliminar un índice. Se especifica únicamente el nombre del índice a
continuación de la palabra reservada CONSTRAINT.

A continuación se presenta una serie de ejemplos para ilustrar como utilizar las operaciones
descritas anteriormente:

Ejemplo:
ALTER TABLE Clientes ADD COLUMN Descripcion TEXT;

Añade un campo Descripcion de tipo textto a la tabla Clientes.

Ejemplo:
ALTER TABLE Clientes DROP COLUMN Descripcion;

Elimina el campo Descripción de la tabla Clientes.

Ejemplo:
ALTER TABLE Reservas ADD CONSTRAINT RelacionReservas FOREIGN
KEY
(DNI) REFERENCES Clientes (DNI);

Añade un índice externo a la tabla Pedidos. El índice externo se basa en el campo DNI y se
refiere al campo DNI de la tabla Clientes.

No es necesario indicar el campo junto al nombre de la tabla en la cláusula REFERENCES ya


que DNI es la clave principal de la tabla Clientes.

Ejemplo:
ALTER TABLE Reservas DROP CONSTRAINT RelacionReservas;

Elimina el índice de la tabla Reservas.


Figura 6: Modificar una tabla

2.2.5. INSERT INTO

Añade registros en una tabla ya sea un único registro ó los registros contenidos en otra
tabla diferente.

Se puede utilizar la instrucción INSERT INTO para agregar un registro único a una tabla,
utilizando la sintaxis de la consulta de adición de registro único. En este caso, su código
especifica el nombre y el valor de cada campo del registro. Debe especificar cada uno de los
campos del registro al que se le va a asignar un valor así como el valor para dicho campo.
Cuando no se especifica dicho campo, se inserta el valor predeterminado o Null.

Los registros se agregan al final de la tabla.

Se puede especificar los valores de cada campo en un nuevo registro utilizando la cláusula
VALUES. Si se omite la lista de campos, la cláusula VALUES debe incluir un valor para cada
campo de la tabla, de otra forma fallará INSERT.

INSERT INTO Tabla (campo1, campo2, ..., campoN)


VALUES (valor1, valor2, ..., valorN)

Esta consulta graba en el campo1 el valor1, en el campo2 y valor2 y así sucesivamente.


También se puede agregar un conjunto de registros pertenecientes a otra tabla o consulta
utilizando la cláusula SELECT... FROM. En este caso la cláusula SELECT especifica los campos
que se van a agregar en la tabla destino especificada.

La tabla destino u origen puede especificar una tabla o una consulta. Si la tabla destino
contiene una clave principal, hay que asegurarse que es única, y con valores no nulos; si no es
así, no se agregarán los registros. Si se agregan registros a una tabla con un campo Contador, no
se debe incluir el campo Contador en la consulta. Se puede emplear la cláusula IN para agregar
registros a una tabla en otra base de datos.

Se pueden averiguar los registros que se agregarán en la consulta ejecutando primero una
consulta de selección que utilice el mismo criterio de selección y ver el resultado. Una consulta
de adición copia los registros de una o más tablas en otra. Las tablas que contienen los registros
que se van a agregar no se verán afectadas por la consulta de adición.

SELECT campo1, campo2, ..., campoN INTO nueva_tabla


FROM tabla_origen [WHERE criterios]

La condición SELECT puede incluir la cláusula WHERE para filtrar los registros a copiar.

En la siguiente unidad se estudiarán en profundidad las consultas de selección, que después


se podrán aplicar aquí.

INSERT INTO Tabla [IN base_externa] (campo1, campo2, ,


campoN)
SELECT TablaOrigen.campo1, TablaOrigen.campo2,,TablaOrigen.
campoN
FROM Tabla Origen

En este caso se seleccionarán los campos 1,2,..., n de la tabla origen y se grabarán en los
campos 1,2,.., n de la Tabla.

Si Tabla y Tabla Origen poseen la misma estructura podemos simplificar la sintaxis de esta
forma:

INSERT INTO Tabla SELECT Tabla_Origen.* FROM Tabla_Origen


De esta forma los campos de Tabla_Origen se grabarán en Tabla. Para realizar esta operación
es necesario que todos los campos de Tabla Origen estén contenidos con igual nombre en Tabla
e igual tipo.

En este tipo de consulta hay que tener especial atención con los campos contadores o
autonuméricos puesto que al insertar un valor en un campo de este tipo se escribe el valor que
contenga su campo homólogo en la tabla origen, no incrementándose como le corresponde.

Figura 7: Inserta registros en la tabla Clientes

Ejemplo:
INSERT INTO Clientes
SELECT ClientesAntiguos.*
FROM ClientesNuevos
Ejemplo:
SELECT Clientes.* INTO Manolos
FROM Clientes
WHERE Nombre = ‘Manolo’

Esta consulta crea una tabla nueva llamada manolos con igual estructura que la tabla
empleado y copia aquellos registros cuyo campo nombre sea exactamente Manolo.

Ejemplo:
INSERT INTO Clientes (Nombre, Direccion, Contacto)
VALUES
(
‘Juan García’, ‘C/Corona, 12’, ‘912456845’
)

Ejemplo:
INSERT INTO Manolos
SELECT Clientes.*
FROM Clientes
WHERE Nombre = ‘Manuel’

2.2.6. DELETE

Elimina los registros de una o más de las tablas listadas en la cláusula FROM que cumplan
la cláusula WHERE.

Esta consulta elimina los registros completos, no es posible eliminar el contenido de algún
campo en concreto.

Su sintaxis es:
DELETE FROM Tabla WHERE criterio

Una vez que se han eliminado los registros utilizando una consulta de borrado, no puede
deshacer la operación. Si desea saber qué registros se eliminarán, primero examine los
resultados de una consulta de selección que utilice el mismo criterio y después ejecute la
consulta de borrado. Una buena práctica consiste en mantener copias de seguridad de los
datos en todo momento. Si elimina los registros por equivocación se podrán recuperar desde
las copias de seguridad.

Ejemplo:
DELETE FROM Clientes
WHERE Nombre = ‘Juan García’

Figura 8: Uso del comando delete

2.2.7. UPDATE

Actualiza los valores de los campos de la tabla especificada basándose en un criterio


específico definido en la cláusula WHERE.

Su sintaxis es:
UPDATE Tabla SET Campo1=Valor1, Campo2=Valor2, CampoN=ValorN
WHERE Criterio

Es especialmente útil cuando se desea cambiar un gran número de registros o cuando éstos
se encuentran en múltiples tablas.

Como sucede en todas las consultas de acción, no se genera ningún resultado. Para saber
qué registros se van a cambiar, hay que examinar primero el resultado de una consulta de
selección que utilice el mismo criterio y después ejecutar la consulta de actualización.

Si en una consulta de actualización suprimimos la cláusula WHERE todos los registros de la


tabla señalada serán actualizados.
Figura 9: Actualizando datos con update

Ejemplo:
UPDATE Habitaciones
SET Precio = Precio * 1.15

Ejemplo:
UPDATE Clientes
SET Contacto = 912345642
WHERE Nombre = Juan García
Se pueden cambiar varios campos a la vez.

Ejemplo:
UPDATE Habitaciones
SET Precio = Precio * 1.15,
DescuentoNiños = 0.40
WHERE TipoHabitación = ‘Familiar’
UNIDAD 3
3.1. Consultas de selección
3.2. Criterios de Selección
3.1. Consultas de selección

Este tipo de consultas se utilizan para conseguir que el motor de datos devuelva la
información que se requiere de las bases de datos.

Esta información es devuelta en forma de conjunto de registros que se pueden almacenar


y modificar.

3.1.1. Consultas básicas

La sintaxis de una consulta de selección básica es sencilla, como puede verse a continuación:
SELECT Campos
FROM Tabla

• Campos: Es la lista de campos que se deseen recuperar


• Tabla: Es la tabla origen de los datos que se quieren extraer

Ejemplo:
SELECT Nombre, Contacto
FROM Clientes

Esta consulta devuelve un conjunto de resultados con todos los registros con el campo
Nombre y Contacto de la tabla clientes.

Para realizar búsquedas realizando algún tipo de filtrado, o estableciendo un criterio de


búsqueda, se añade en la sentencia la cláusula WHERE, de la siguiente forma:
SELECT Campos
FROM Tabla
WHERE Criterios de filtrado

Ejemplo:
SELECT Nombre, Contacto
FROM Clientes
WHERE Contacto = 915487548
En esta ocasión la sentencia devuelve únicamente aquellos registros, con el campo Nombre
y Contacto de la tabla clientes, que cumplan la condición de que el campo Contacto coincida
con 915487548.

3.1.2. Ordenar los registros

Es posible especificar el orden en que se desean recuperar los registros de las tablas
mediante la cláusula:
ORDER BY Lista_de_Campos: Lista de campos representa los
campos a ordenar.

Figura 10: Ordenación de los clientes

Ejemplo:
SELECT Nombre, Contacto
FROM Clientes
ORDER BY Nombre;

Con esta consulta conseguimos los campos Nombre y Contacto de la tabla


Clientes ordenados por el campo Nombre.
Se pueden ordenar los registros por mas de un campo.

Ejemplo:
SELECT Nombre, Dirección, Contacto
FROM Clientes
ORDER BY Dirección, Nombre;
También es posible especificar el orden de los registros:
• ascendente mediante la claúsula ASC (se toma este valor por defecto)
• descendente mediante la claúsula DESC

Ejemplo:
SELECT Nombre, Dirección, Contacto
FROM Clientes
ORDER BY Dirección DESC, Nombre ASC;

3.1.3. Consultas con Predicado

Los predicados que se quieran incluir en una consulta deben colocarse entre la cláusula y el
primer nombre del campo que se quiere recuperar.
• ALL: Devuelve todos los campos de la tabla. Si no se incluye ninguno de los predicados
se asume ALL por defecto.

Ejemplo:
SELECT ALL FROM Clientes;
SELECT * FROM Clientes;

• TOP: Devuelve un determinado número de registros de la tabla, que entran entre al


principio o al final de un rango especificado por una cláusula ORDER BY.

Ejemplo:
SELECT TOP 10 Nombre
FROM Clientes
ORDER BY Direccion DESC;

Si no se incluye la cláusula ORDER BY, la consulta devolverá un conjunto arbitrario de


registros de la tabla Clientes.

Este predicado no elige entre valores iguales.

La palabra reservada PERCENT se puede usar para devolver un cierto porcentaje de registros
que caen al principio o al final de un rango especificado por la cláusula ORDER BY.
El valor que va a continuación de TOP debe ser un Integer sin signo.

Ejemplo:
SELECT TOP 10 PERCENT Nombre
FROM Clientes
ORDER BY Dirección DESC;

Figura 11: Sentencia TOP

• DISTINCT: Con este predicado se omiten los registros cuyos campos seleccionados
coincidan totalmente (duplicados), es decir, que para que los valores de cada campo listado
en la instrucción SELECT se incluyan en la consulta, estos deben ser únicos.

Ejemplo:
SELECT DISTINCT Nombre
FROM Clientes;

• DISTINCTROW: Se omiten los registros duplicados basándose en la totalidad del registro


y no sólo en los campos seleccionados. A diferencia del predicado anterior que sólo se
fijaba en el contenido de los campos seleccionados, éste lo hace en el contenido del registro
completo, independientemente de los campo indicados en la cláusula SELECT.
Ejemplo:
SELECT DISTINCTROW Nombre
FROM Clientes;

Figura 12: Ejemplo de Alias y Distinct

3.1.4. Alias

Es posible asignar un nombre a alguna columna determinada de un conjunto devuelto. Se


puede conseguir empleando la palabra reservada AS, que se encarga de asignar el nombre que
deseamos a la columna elegida.

Ejemplo:
SELECT DISTINCTROW Direccion AS calle
FROM Clientes;

3.2. Criterios de Selección

Existen muchas posibilidades de filtrar los registros que se devuelven tras realizar una
consulta de selección, con el fin de recuperar solamente aquellos que cumplan una condiciones
preestablecidas.

Es necesario tener en cuenta una serie de normas de sintaxis:


• Para establecer una condición referida a un campo de texto la condición de búsqueda
debe ir entre comillas simples
• No es posible establecer condiciones de búsqueda en los campos memo
• Las fechas se deben escribir siempre en formato mm-dd-aaaa en donde mm representa
el mes, dd el día y aaaa el año. Los separadores serán siempre guiones (-), y además la fecha
debe ir encerrada entre almohadillas (#).

Ejemplo:
#15-03-2009# ó #15-3-2009#.

3.2.1. Operadores Lógicos

SQL soporta una serie de operadores lógicos: AND, OR, XOR, Eqv, Imp, Is y Not.

Todos poseen la siguiente sintaxis:


<expresión1> operador <expresión2>

a excepción de los dos últimos, que tienen la siguiente:


operador <expresión1>

Dependiendo del operador se obtiene un resultado diferente, como se muestra a


continuación:
NOT:
NOT Verdad -> Falso
NOT Falso -> Verdad

AND:
Verdad AND Falso -> Falso
Verdad AND Verdad -> Verdad
Falso AND Verdad -> Falso
Falso AND Falso -> Falso

OR:
Verdad OR Falso -> Verdad
Verdad OR Verdad -> Verdad
Falso OR Verdad -> Verdad
Falso OR Falso -> Falso
XOR:
Verdad XOR Verdad -> Falso
Verdad XOR Falso -> Verdad
Falso XOR Verdad-> Verdad
Falso XOR Falso -> Falso

EQV:
Verdad Eqv Verdad -> Verdad
Verdad Eqv Falso -> Falso
Falso Eqv Verdad -> Falso
Falso Eqv Falso->Verdad

IMP:
Verdad Imp Verdad -> Verdad
Verdad Imp Falso-> Falso
Verdad Imp Null -> Null
Falso Imp Verdad -> Verdad
Falso Imp Falso -> Verdad
Falso Imp Null-> Verdad
Null Imp Verdad -> Verdad
Null Imp Falso -> Null
Null Imp Null -> Null

El operador denominado IS se emplea para comparar dos variables de tipo Objeto, y


devuelve verdad si los dos objetos son iguales.

Ejemplo:
SELECT *
FROM Habitaciones
WHERE Precio > 25 AND Precio < 50;

SELECT * FROM Habitaciones


WHERE (Precio > 25 AND Precio < 60) OR Numero = 100;

SELECT * FROM Habitaciones


WHERE NOT Estado = ‘Libre’;
SELECT * FROM Habitaciones
WHERE (Numero > 100 AND Numero < 500) OR
(Precio = 75 AND Estado = ‘Reservado’);

3.2.2. Rangos de Valores

La forma de indicar que deseamos recuperar los registros según el intervalo de valores de
un campo es utilizar el operador Between:
campo [Not] Between valor1 And valor2

Una consulta de este tipo devolvería los registros que contengan en “campo” un valor entre
valor1 y valor2 (ambos incluidos). Si se antepone la condición Not devolverá aquellos valores
no incluidos en el intervalo.

Ejemplo:
SELECT *
FROM Habitaciones
WHERE Numero Between 201 And 350;

Figura 13: Uso de Between

3.2.3. Like

Este operador se utiliza para comparar cadenas.


<expresión> LIKE modelo
Se puede utilizar el operador LIKE para encontrar valores en los campos, que coincidan con
el modelo especificado, es decir, comparar un valor de un campo con una expresión de cadena.

Como modelo puede especificar un valor completo, o bien se pueden utilizar caracteres
comodín para encontrar un rango de valores.

En la siguiente tabla se puede ver detalladamente el uso de los comodines en los modelos
de comparación:

Tipo de coincidencia Modelo establecido Coincidencia No coincidencia

Varios caracteres ‘a*a’ ‘aa’, ‘aBa’, ‘aBBBa’ ‘aBC’


Carácter especial ‘a[*]a’ ‘a*a’ ‘aaa’
Varios caracteres ‘ab*’ ‘abcdefg’, ‘abc’ ‘cab’, ‘aab’
Un solo carácter ‘a?a’ ‘aaa’, ‘a3a’, ‘aBa’ ‘aBBBa’
Un solo dígito ‘a#a’ ‘a0a’, ‘a1a’, ‘a2a’ ‘aaa’, ‘a10a’
Rango de caracteres ‘[a-z]’ ‘f’, ‘p’, ‘j’ ‘2’, ‘&’
Fuera de un rango ‘[!a-z]’ ‘9’, ‘&’, ‘%’ ‘b’, ‘a’
Distinto de un dígito ‘[!0-9]’ ‘A’, ‘a’, ‘&’, ‘~’ ‘0’, ‘1’, ‘9’
Combinada ‘a[!b-m]#’ ‘An9’, ‘az0’, ‘a99’ ‘abc’, ‘aj0’

Ejemplo:
Like ‘P[A-Z]?’

Devuelve los datos que comienzan con la letra P seguido de una letra entre A y Z y finalizando
por un carácter cualquiera.

Ejemplo:
Like ‘[E-M]#’

Devuelve los campos cuyo contenido empiece con una letra de la E a la M seguidas de un
dígito.
Figura 14: Sentencia con el comando Like

3.3.4. In

Este operador devuelve aquellos registros cuyo campo indicado este incluido en una lista.
expresión [Not] In(valor1, valor2, . . .)

Ejemplo:
SELECT *
FROM Clientes
WHERE Nombre IN (‘Juan’, ‘Daniel’, ‘Sandra’);

Figura 15: Negación del comando In


3.3.5. WHERE

Se utiliza para determinar qué registros de las tablas enumeradas en la cláusula FROM
aparecerán en los resultados de la instrucción SELECT. Tras escribir esta cláusula se deben
especificar las condiciones que se desean como criterios de selección. Si no se emplea esta
cláusula, la consulta devolverá todas las filas de la tabla.

Es una cláusula opcional, pero cuando aparece debe ir a continuación de FROM para
generar un resultado válido.

SELECT Numero
FROM Habitaciones
WHERE Precio > 50;

SELECT *
FROM Reservas
WHERE Fecha_Reserva = #5-10-2009#;

SELECT Nombre, Contacto


FROM Clientes
WHERE Direccion Like ‘Pza*’;

3.3.6. Agrupamiento de Registros

• GROUP BY (opcional).
Esta cláusula consigue combinar aquellos registros con valores idénticos, en la lista de
campos especificados, en un único registro. Para cada registro se crea un valor sumario
si se incluye una función SQL agregada, como por ejemplo Sum o Count, en la instrucción
SELECT de la siguiente forma.

SELECT campos FROM tabla


WHERE criterio GROUP BY campos del grupo

Mientras que los valores de resumen se omiten si no existe una función SQL agregada en
la instrucción SELECT, los valores Null en los campos GROUP BY se agrupan y no se omiten,
aunque no se evalúan.
Un campo de la lista de campos GROUP BY puede referirse a cualquier campo de las tablas
que aparecen en la cláusula FROM, incluso si el campo no esta incluido en la instrucción SELECT,
siempre y cuando la instrucción SELECT incluya al menos una función SQL agregada.

Todos los campos de la lista de campos de SELECT deben o bien incluirse en la cláusula
GROUP BY o como argumentos de una función SQL agregada.

SELECT Numero, Sum(Precio)


FROM Habitaciones
GROUP BY Numero;

Se utiliza la cláusula WHERE para excluir aquellas filas que no desea agrupar, y la cláusula
HAVING para filtrar los registros una vez agrupados.

Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier registro
agrupado por la cláusula GROUP BY que satisfaga las condiciones de la cláusula HAVING.

La cláusula HAVING es parecida a la cláusula WHERE, determina qué registros se seleccionan.


Una vez que los registros se han agrupado utilizando GROUP BY, HAVING determina cuales de
ellos se van a mostrar.

SELECT Numero, Sum(Precio)


FROM Habitaciones
GROUP BY Numero
HAVING Sum(Precio) > 100;

Figura 16: Group y Having en una misma sentencia


• AVG:
Se utiliza para calcular la media aritmética de un conjunto de valores contenidos en un
campo con datos numéricos especificado de una consulta.

SELECT Avg(Precios) AS Promedio


FROM Habitaciones
WHERE Precios > 50;

• Count
Se utiliza para calcular el número de registros devueltos por una consulta. Puede contar
cualquier tipo de datos, incluso texto, ya que cuenta el número de registros sin tener en
cuenta qué valores se almacenan en ellos.
SELECT Count(*) AS Total
FROM Clientes;

• Max, Min
Devuelven el mínimo o el máximo de un conjunto de valores contenidos en un campo
especifico de una consulta.

SELECT Min(Precio) AS ElMin


FROM Habitaciones;

SELECT Max(Precio) AS ElMax


FROM Habitaciones;

Figura 17: Varias sentencias avg, count, max y min


• StDev,StDevP
Devuelve estimaciones de la desviación estándar para la población (el total de los
registros de la tabla) o una muestra de la población representada (muestra aleatoria) .

StDevP evalúa una población, y StDev evalúa una muestra de la población. Si la consulta
contiene menos de dos registros (o ningún registro para StDevP), estas funciones devuelven
un valor Null.

SELECT StDev(Precio) AS Desviacion


FROM Habitaciones;

SELECT StDevP(Precio) AS Desviacion


FROM Habitaciones;

• Sum
Calcula la suma del conjunto de valores contenido en un campo especifico de una consulta.

SELECT Sum(Precio) AS Total


FROM Habitaciones
WHERE Numero beetwen(201,215);

• Var, VarP
Se utiliza para calcular una estimación de la varianza de una población (sobre el total de los
registros) o una muestra de la población (muestra aleatoria de registros) sobre los valores
de un campo.

VarP evalúa una población, y Var evalúa una muestra de la población.

Si la consulta contiene menos de dos registros, Var y VarP devuelven Null

SELECT Var(Precio) AS Varianza


FROM Habitaciones;

SELECT VarP(Precio) AS Varianza


FROM Habitaciones;
UNIDAD 4
4.1. Consultas de unión
4.2. Subconsultas
4.3. Consultas con Parámetros
4.4. Referencias Cruzadas
4.5. Bases de Datos Externas
4.1. Consultas de unión

4.1.1. Internas

Para realizar vinculaciones entre tablas se utiliza la cláusula INNER, que combina registros
de dos tablas (siempre que haya concordancia de valores en un campo común), con la siguiente
sintaxis:

SELECT campos
FROM tabla1 INNER JOIN tabla2 ON tabla1.campo1 comp tabla2.campo2

tabla1, tabla2
Nombres de las tablas desde las que se combinan los registros.

campo1, campo2
Nombres de los campos que se combinan. Si no son numéricos, los campos deben ser del
mismo tipo de datos y contener el mismo tipo de datos, pero no tienen que tener el mismo
nombre.

Comp.
Cualquier operador de comparación relacional: =, <,<>, <=, =>, ó >.

Una operación INNER JOIN se podrá utilizar en cualquier cláusula FROM, creando una
combinación por equivalencia que se conoce como unión interna.

Este tipo de combinaciones equivalentes son las más comunes; combinan los registros de
dos tablas siempre que haya concordancia de valores en un campo común a ambas tablas.

Cláusulas LEFT y RIGHT. LEFT toma todos los registros de la tabla de la izquierda aunque
no tengan ningún registro en la tabla de la izquierda. RIGHT realiza la misma operación pero al
contrario, toma todos los registros de la tabla de la derecha aunque no tenga ningún registro
en la tabla de la izquierda. Es decir, para los casos en los que se quiera hacer la unión de tabla1
y tabla2 pero haya correspondencias que no existen en tabla2, se emplea LEFT JOIN. Si por el
contrario, donde no existen todas las correspondencias es en tabla1, se utilizará RIGHT JOIN.

No se pueden combinar campos que contengan datos Memo u Objeto OLE.


Ejemplo:
Para seleccionar todos los empleados de cada departamento se utiliza INNER JOIN con las
tablas Departamentos y Empleados.

Para seleccionar todos los departamentos siendo que alguno de ellos no tiene ningún
empleado asignado se emplea LEFT JOIN, pero para seleccionar todos los empleados aún
cuando alguno no está asignado a ningún departamento, se usa ese caso RIGHT JOIN.

Figura 18: Ejemplo de uso de Inner Join

La combinación de las tablas Departamentos y Empleados se basará en el campo IDdepto,


presente en ambas tablas.

SELECT NombreDepto, NombreEmpleado


FROM Departamentos INNER JOIN Empleados
ON Departamentos. IDdepto = Empleados. IDdepto

Para unir más de dos tablas se pueden enlazar varias cláusulas ON en una instrucción JOIN,
de la siguiente manera:

SELECT campos
FROM tabla1 INNER JOIN tabla2
ON tabla1.campo1 comp tabla2.campo2
INNER JOIN tabla3 ON tabla2.campo2 comp tabla3.campo3
Pueden emplearse operadores lógicos:
SELECT campos
FROM tabla1 INNER JOIN tabla2
ON (tabla1.campo1 comp tabla2.campo1 AND ON tabla1.campo2
comp tabla2.campo2)
OR ON (tabla1.campo3 comp tabla2.campo3)
Otra manera de instrucciones JOIN utiliza la siguiente sintaxis:
SELECT campos
FROM tabla1 INNER JOIN
( tabla2 INNER JOIN
[ ( ] tabla3 [INNER JOIN [( ]tablaN [INNER JOIN ...)]
ON tabla3.campo3 comp [Link])
]
ON tabla2.campo2 comp tabla3.campo3
)
ON tabla1.campo1 comp tabla2.campo2

Un LEFT JOIN o un RIGHT JOIN puede anidarse dentro de un INNER JOIN, pero un INNER
JOIN no puede anidarse dentro de un LEFT JOIN o un RIGHT JOIN.

La sintaxis puede variar ligeramente de un sistema gestor de bases de datos a otro. En SQL-
SERVER se debería añadir la palabra reservada OUTER: LEFT OUTER JOIN y RIGHT OUTER JOIN,
aunque en la práctica funciona correctamente de una u otra forma.

Existe una sintaxis en formato ANSI para los INNER JOIN que funciona en todos los sistemas.
SELECT tabla1.*, tabla2.*
FROM tabla1 INNER JOIN tabla2 ON tabla1.campo1 = tabla2. campo2

La transformación de esta sentencia a formato ANSI sería la siguiente:


SELECT tabla1.*, tabla2.*
FROM tabla1, tabla2
WHERE tabla1.campo1 = tabla2. campo2

Todas las tablas que intervienen en la consulta se especifican en la cláusula FROM.

Las condiciones que vinculan a las tablas se especifican en la cláusula WHERE y en caso de
que haya más de una condición, se vinculan mediante el operador lógico AND.
Figura 19: Left y Right Join

Auto-combinación: Se utiliza para unir una tabla consigo misma, comparando valores de
dos columnas con el mismo tipo de datos.

SELECT [Link], [Link], ...


FROM tabla1 as alias1, tabla1 as alias2
WHERE [Link] = [Link]
AND otras condiciones

Ejemplo:
La tabla Empleados contiene los datos de cada empleado, su puesto, su supervisor...

Este ejemplo mostraría el número, nombre y puesto de cada empleado, junto con el
número, nombre y puesto del supervisor de cada uno de ellos:

SELECT t.numero_empleado, [Link], [Link], t.numero_


superior,
[Link], [Link]
FROM Empleados AS t, Empleados AS s
WHERE t.numero_superior = s.numero_empleado
Figura 20: Autocombinación

Combinaciones no Comunes: En general las combinaciones están basadas en la igualdad


de valores de las columnas que son el criterio de la combinación. Las no comunes se basan en
otros operadores de combinación, tales como NOT, BETWEEN, <>, etc.

Se ejecutaría una sentencia con una sintaxis parecida a la siguiente:

SELECT tabla1.*, tabla2.*


FROM tabla1, tabla2
WHERE tabla1.campo1 BETWEEN tabla2. campo2 AND tabla2. campo3

4.1.2. Externas

Para crear una consulta de unión se utiliza la operación UNION, combinando los resultados
de dos o más consultas o tablas independientes.

[TABLE] consulta1 UNION [ALL] [TABLE]


consulta2 [UNION [ALL] [TABLE]
consultaN [ ... ]]

consulta 1,consulta 2 ... consulta n:

Instrucciones SELECT, el nombre de una consulta almacenada o el nombre de una tabla


almacenada precedido por la palabra clave TABLE.
Es posible combinar los resultados de dos o más consultas, tablas e instrucciones SELECT,
en cualquier orden, en una única operación UNION.

No se devuelven registros duplicados cuando se utiliza la operación UNION, no obstante


puede incluir el predicado ALL para asegurar que se devuelven todos los registros. De esta
forma la ejecución de la consulta es más rápida.

En una operación UNION todas las consultas deben pedir el mismo número de campos,
aunque los campos no tienen porqué tener el mismo tamaño o el mismo tipo de datos.

Ejemplo:
TABLE Cuentas
UNION ALL
SELECT * FROM Reservas
WHERE PrecioTotal > 300

Figura 21: Union, sentencia SQL

4.2. Subconsultas

Las subconsultas son instrucciones SELECT anidadas dentro de una instrucción SELECT,
SELECT...INTO, INSERT...INTO, DELETE, o UPDATE, o incluso dentro de otra subconsulta.

Hay sintaxis diferentes para crear una subconsulta:


• comparación [ANY | ALL | SOME] (instrucción sql)
Comparación: Es una expresión y un operador de comparación que compara la expresión
con el resultado de la subconsulta.
• expresión [NOT] IN (instrucción sql)
Expresión: Es una expresión por la que se busca el conjunto resultante de la subconsulta.
• [NOT] EXISTS (instrucción sql)
Instrucción SQL: Es una instrucción SELECT, que sigue el mismo formato y reglas que
cualquier otra instrucción SELECT. Debe ir entre paréntesis.

Una subconsulta puede utilizarse en lugar de una expresión en la lista de campos de una
instrucción SELECT o en una cláusula WHERE o HAVING (una instrucción SELECT proporciona
un conjunto de uno o más valores especificados para evaluar en la expresión de la cláusula
WHERE o HAVING).

Es posible utilizar los predicados ANY o SOME para recuperar registros de la consulta principal
que satisfagan la comparación con cualquier otro registro recuperado en la subconsulta.

Ejemplo:
SELECT *
FROM Habitaciones
WHERE Precio ANY ( SELECT Precio
FROM Reservas
WHERE Descuento = 0 .25
)

Esta consulta devuelve todas las habitaciones cuyo precio es mayor que el de cualquier
habitación reservada con un descuento igual o mayor al 25 por ciento.

El predicado ALL se utiliza para recuperar aquellos registros de la consulta principal que
satisfacen la comparación con todos los registros recuperados en la subconsulta.

Ejemplo:
SELECT *
FROM Habitaciones
WHERE Precio ALL ( SELECT Precio
FROM Reservas
WHERE Descuento = 0 .25
)
Si se cambia ANY por ALL en el ejemplo anterior, la consulta devolverá únicamente aquellas
habitaciones cuyo precio sea mayor que el de todas las habitaciones reservadas con un
descuento igual o mayor al 25 por ciento. Esto es mucho más restrictivo.

Figura 22: Ejemplo del uso de la sentencia ALL

Utilizamos el predicado IN para recuperar únicamente aquellos registros de la consulta


principal para los que algunos registros de la subconsulta contienen un valor igual.

Ejemplo:
SELECT *
FROM Habitaciones
WHERE Precio IN ( SELECT Precio
FROM Reservas
WHERE Descuento = 0 .25
)
Esta consulta devuelve todas las habitaciones reservadas con un descuento igual o mayor
al 25 por ciento.

Puede utilizarse NOT IN para recuperar únicamente aquellos registros de la consulta


principal para los que no hay ningún registro de la subconsulta que contenga un valor igual.

Se utiliza el predicado EXISTS (con la palabra reservada NOT opcional) en comparaciones de


verdadero – falso, para determinar si la subconsulta devuelve algún registro.

Ejemplo:
Deseamos recuperar todos aquellos clientes que hayan realizado al menos una reserva:
SELECT [Link], [Link]éfono
FROM Clientes
WHERE EXISTS ( SELECT *
FROM Reservas
WHERE [Link] = [Link]
)

Esta consulta es equivalente a esta otra:


SELECT [Link], [Link]éfono
FROM Clientes
WHERE IdClientes IN ( SELECT [Link]
FROM Reservas
)

Se puede utilizar también alias del nombre de la tabla en una subconsulta para referirse a
tablas listadas en la cláusula FROM fuera de la subconsulta.
Ejemplo:
SELECT *
FROM Empleados AS T1
WHERE Salario = (SELECT Avg(Salario)
FROM Empleados
WHERE [Link] = [Link]
)
ORDER BY Titulacion
Devuelve los datos de los empleados cuyo salario es igual o mayor que el salario medio de
todos los empleados con la misma titulación.

Ejemplo:
SELECT *
FROM Empleados
WHERE Puesto LIKE ‘*Comercial’
AND Salario ALL ( SELECT Salario FROM Empleados
WHERE Puesto LIKE ‘*Jefe*’ OR Puesto LIKE ‘*Director*’
)

Devuelve una lista con el nombre, cargo y salario de todos los comerciales cuyo salario es
mayor que el de todos los jefes y directores.

4.3. Consultas con Parámetros

Las consultas con parámetros son aquellas cuyas condiciones de búsqueda se definen
mediante parámetros, de la siguiente forma.

PARAMETERS nombre1 tipo1, nombre2 tipo2, ... , nombreN tipoN


Consulta

nombre: Nombre del parámetro


tipo: Tipo de datos del parámetro
consulta: Una consulta SQL
Figura 23: Ejemplo del uso de parámetros en SQL Server

Si se ejecutan directamente desde la base de datos donde han sido definidas aparecerá un
mensaje solicitando el valor de cada uno de los parámetros.

Si deseamos ejecutarlas desde una aplicación hay que asignar primero el valor de los
parámetros y después ejecutarlas.

Se pueden utilizar nombres pero no tipos de datos en una cláusula WHERE o HAVING.

Ejemplo:
PARAMETERS PrecioMinimo Currency, FechaInicio DateTime;
SELECT IdReserva
FROM Reservas
WHERE Precio = PrecioMinimo AND FechaPedido = FechaInicio
4.4. Referencias Cruzadas

Una consulta de referencias cruzadas es aquella que nos permite visualizar los datos en filas
y en columnas, en forma de tabla.

La sintaxis utilizada es la siguiente:


TRANSFORM función_agregada instrucción_select PIVOT campo_
pivot
[IN (valor1[, valor2[, ...]])]

función_agregada: Es una función SQL agregada que opera sobre los datos seleccionados.
Instrucción_select: Es una instrucción SELECT.
Campo_pivot: Es el campo o expresión que desea utilizar para crear las cabeceras de la
columna en el resultado de la consulta.
valor1, valor2: Son valores fijos utilizados para crear las cabeceras de la columna.

Ejemplo:

Producto / Año 2007 2008

Jarrones 1.150 3.060

Ceniceros 3.103 1.754

Posavasos 4.380 2.500

Partiendo de una tabla de productos y otra tabla de pedidos, podemos visualizar en total
de productos pedidos por año para un artículo determinado, tal y como se muestra en la tabla
anterior.

Para resumir datos utilizando una consulta de referencia cruzada, se seleccionan los valores
de los campos o expresiones especificadas como cabeceras de columnas de tal forma que
pueden verse los datos en un formato más compacto que con una consulta de selección.

La palabra clave TRANSFORM es opcional pero si se incluye, es la primera instrucción de


una cadena SQL. Precede a la instrucción SELECT que especifica los campos utilizados como
encabezados de fila y una cláusula GROUP BY que especifica el agrupamiento de las filas.
De manera opcional se puede incluir otras cláusulas, como por ejemplo WHERE, que
especifica una selección adicional o un criterio de ordenación.

Aquellos valores que son devueltos en campo pivot se utilizan como encabezados de
columna en el resultado de la consulta.

Es posible restringir el campo pivot para crear encabezados a partir de los valores fijos
(valor1, valor2) listados en la cláusula opcional IN, o también puede incluir valores fijos, para
los que no existen datos, para crear columnas adicionales.

Ejemplo:
TRANSFORM Sum(Total) AS Reservas
SELECT Numero, TipoHabitacion FROM Habitaciones
WHERE FechaReserva Between #01-01-2009# And #12-31-2009#
GROUP BY Numero
ORDER BY Numero
PIVOT DatePart(“m”, FechaReserva)

Figura 24: Ejemplo con la sentencia pivot

Muestra las reservas por mes para un año específico. Los meses aparecen de izquierda a
derecha como columnas y los nombres de los productos aparecen de arriba hacia abajo como
filas.

Otras posibilidades de fecha de la cláusula PIVOT son las siguientes:


• Para agrupamiento por años: PIVOT Year(Fecha)
• Para agrupamiento por Trimestres: PIVOT “Tri “ & DatePart(“q”,[Fecha]);
• Para agrupamiento por meses (sin tener en cuenta el año): PIVOT
Format([Fecha],”mmm”) In (“Ene”, “Feb”, “Mar”, “Abr”, “May”, “Jun”, “Jul”, “Ago”, “Sep”,
“Oct”, “Nov”, “Dic”);
• Para agrupar por días: PIVOT Format([Fecha],”Short Date”);

4.5. Bases de Datos Externas

Para acceder a bases de datos externas se utiliza la cláusula IN. Se puede acceder a base de
datos dBase, Paradox o Btrieve.

Esta cláusula sólo permite la conexión de una base de datos externa a la vez. Una base de
datos externa es una base de datos que no sea la activa.

Para especificar una base de datos que no pertenece a Access Basic, se agrega un punto y
coma (;) al nombre y se encierra entre comillas simples.

También puede utilizar la palabra reservada DATABASE para especificar la base de datos
externa.

Ejemplo:
FROM Tabla IN ‘[dBASE IV; DATABASE=C:\DBASE\DATOS\REGISTROS;]’;

FROM Tabla IN ‘C:\DBASE\DATOS\ REGISTROS’ ‘dBASE IV;’

Estas dos líneas especifican la misma tabla.

• Acceso a una base de datos externa de Microsoft Access:


SELECT IDCliente
FROM Clientes IN [Link]
WHERE IDCliente Like ‘A*’;

• Acceso a una base de datos externa de dBASE III o IV:


SELECT IDCliente
FROM Clientes IN ‘C:\DBASE\DATOS\REGISTROS’ ‘dBASE IV’;
WHERE IDCliente Like ‘A*’;
Para recuperar datos de una tabla de dBASE III+ hay que utilizar ‘dBASE III+;’ en lugar de
‘dBASE IV;’.

• Acceso a una base de datos de Paradox 3.x o 4.x:


SELECT IDCliente
FROM Clientes IN ‘C:\PARADOX\DATOS\REGISTROS’ ‘Paradox 4.x;’
WHERE IDCliente Like ‘A*’;

Para recuperar datos de una tabla de Paradox versión 3.x, hay que sustituir ‘Paradox 4.x;’
por ‘Paradox 3.x;’.

• Acceso a una base de datos de Btrieve:


SELECT IDCliente
FROM Clientes IN ‘C:\BTRIEVE\DATOS\REGISTROS\[Link]’
‘Btrieve;’
WHERE IDCliente Like ‘A*’;
UNIDAD 5
5.1. Categorías de funciones
5.2. Funciones integradas
5.3. Funciones de cadena
5.4. Funciones de fecha y hora
5.5. Funciones numéricas
5.1. Categorías de funciones

Las funciones de SQL se clasifican en distintas categorías de acuerdo a diferentes criterios,


según gene­ren o no siempre el mismo resultado sobre los mismos datos, actúen sobre
conjuntos de datos o datos individuales, operen en un tipo u otro de información, etc.

Podemos dividirlas en dos grandes grupos:


1. Funciones deterministas
Estas se caracterizan por devolver siempre el mismo resultado a par­tir de los mismos datos
de entrada. Por ejemplo la función SUBSTRING es determinista, ya que siempre que le
entreguemos como entrada los mismos argu­mentos generarán el mismo resultado.
2. Funciones no deterministas
Estas funciones no pueden devol­ver valores diferentes al usarlas varias veces, a pesar de
que los datos que les entreguemos sean los mismos. Como por ejemplo ciertas funciones
informativas que devuelven la fecha y hora actual, el nombre del usuario que está
trabajando en la base de datos, etc.

Es importante conocer el uso de las funciones deterministas o no deterministas por ejemplo,


al definir la clave principal de una tabla a partir de una expresión en la que se usan funciones,
en lugar de una columna individual, o al generar un índice. Algunos RDBMS permiten esas
operaciones únicamente si el resultado de la expresión va a ser siempre el mismo, es decir, se
trata de una expresión determinista, ya que de lo contrario sería imposible asignar un valor
único a cada fila.

Existe otra clasificación que divide las funciones en dos grupos según operen sobre un dato
individual o un grupo de datos.
1. Funciones que operan sobre un dato individual.
Son conocidas como funciones escalares y llevan a cabo algún tipo de operación sobre
un dato indi­vidual, por ejemplo una secuencia de caracteres, un número o una fecha.
substring es una función escalar.
2. Funcio­nes que actúan sobre un conjunto de datos
Son conocidas como funciones de agregado. Suelen actuar normalmente sobre una
columna de una serie de filas. SUM, por ejemplo, va sumando todos los valores de una
cierta columna en las distintas filas resultantes de una consulta.
Finalmente, podemos clasificar las funciones según el tipo de información sobre la que
actúan, teniendo:
1. Funciones de cadenas de caracteres como SUBSTRING.
2. Fun­ciones numéricas como ABS
3. Funciones de fecha tal como EXTRACT.

Además tenemos otra categoría separada, conocida normalmente como funciones built-in
o integradas, constituida por funciones que nos devuelven información facili­tada por el propio
RDBMS: la fecha y hora actual, el nombre del usuario, etc.

5.2. Funciones integradas

Se limitan a devolver un valor sin precisar ningu­na información sobre la que operar.

En la siguiente tabla se muestran las funciones integradas:

NOMBRE DESCRIPCION
CURRENT_DATE Devuelve la fecha actual
CURRENT_TIME Devuelve la hora actual

CURRENT _TIMESTAMP Devuelve la fecha y la hora actual

CURRENT_USER y USER Identifica al usuario que está operando sobre la base de datos.

Facilita el identificador del usuario si es diferente de CURRENT_


SESSION_USER
USER

SYSTEM_USER Identifica al usuario según la cuenta del sistema operativo.

Hay que tener en cuenta que, a pesar de que estas funciones forman parte del estándar
SQL, no todos los RDBMS las contemplan incluso en algunos casos les dan otros nombres. Tam­
bién hay que considerar si el usuario usa una cuenta para ini­ciar sesión en el sistema operativo
y es éste el que se encarga de personificarlo ante el RDBMS o, por el contrario, el usuario tiene
una cuenta específica para acceder a la base de datos. La inclusión de los datos devueltos por
estas funciones en una consulta se efectúa como si se tratase de columnas, aunque en realidad
no están almacenados en tabla alguna.
Por ejemplo el RDBMS de Microsoft no cuenta con las dos funciones CURRENT_DATE y
CURRENT_TIME, pero sí las demás citadas en la anterior tabla. Vamos a ver un ejemplo, en el
que mostramos todas las funciones que se pueden usar en el RDMS de Microsoft

5.3. Funciones cadena

Con este nombre se conocen las funciones que permiten operar sobre secuencias o cadenas
de caracteres, el estándar SQL cuenta con otra serie de funcio­nes de cadena entre las cuales
están las siguientes:

substring (cadena,inicio,longitud): devuelve una parte de la cadena especificada como


primer argumento, empezando desde la posición especificada por el segundo argumento y de
tantos caracteres de longitud como indica el tercer argumento.

Ejemplo:
str(numero,longitud,cantidaddecimales): convierte números a caracteres; el primer
parámetro indica el valor numérico a convertir, el segundo la longitud del resultado (debe ser
mayor o igual a la parte entera del número más el signo si lo tuviese) y el tercero, la cantidad
de decimales. El segundo y tercer argumento son opcionales y deben ser positivos.

Ejemplo: Convertimos el valor numérico “123.456” a cadena, especificando 7 de longitud y


3 decimales y el valor numérico “-123.456” a cadena, especificando 7 de longitud y 3 decimales

Si no se colocan el segundo y tercer argumento, la longitud predeterminada es 10 y la


cantidad de decimales 0 y se redondea a entero.

Ejemplo: se convierte el valor numérico “123.456” a cadena:


Si el segundo parámetro es menor a la parte entera del número, devuelve asteriscos (*).

Ejemplo:

- stuff(cadena1,inicio,cantidad,cadena2): inserta la cadena enviada como cuarto argumento,


en la posición indicada en el segundo argumento, reemplazando la cantidad de caracteres
indicada por el tercer argumento en la cadena que es primer parámetro.

Ejemplo:

Devuelve “abopqrse”. Coloca en la posición 2 la cadena “opqrs” y reemplaza 2 caracteres


de la primera cadena.

Los argumentos numéricos deben ser positivos y menor o igual a la longitud de la primera
cadena, caso contrario, retorna “null”.

Si el tercer argumento es mayor que la primera cadena, se elimina hasta el primer carácter.
len(cadena): retorna la longitud de la cadena enviada como argumento. “len” viene de
length.

Ejemplo:

char(x): retorna un caracter en código ASCII del entero enviado como argumento.

Ejemplo:

- left(cadena,longitud): retorna la cantidad (longitud) de caracteres de la cadena


comenzando desde la izquierda, primer carácter.
Ejemplo:

right(cadena,longitud): retorna la cantidad (longitud) de caracteres de la cadena


comenzando desde la derecha, último carácter.

Ejemplo:

lower(cadena): retornan la cadena con todos los caracteres en minúsculas..


Ejemplo:
upper(cadena): retornan la cadena con todos los caracteres en mayúsculas. Ejemplo:

ltrim(cadena): retorna la cadena con los espacios de la izquierda eliminados. Ejemplo:

- rtrim(cadena): retorna la cadena con los espacios de la derecha eliminados.

Ejemplo:
replace(cadena,cadenareemplazo,cadenareemplazar): retorna la cadena con todas las
ocurrencias de la subcadena reemplazo por la subcadena a reemplazar. Ejemplo:

reverse(cadena): devuelve la cadena invirtiendo el orden de los caracteres. Ejemplo:

patindex(patron,cadena): devuelve la posición de comienzo (de la primera ocurrencia)


del patrón especificado en la cadena enviada como segundo argumento. Si no la encuentra
retorna 0.
Ejemplo:
- ch

arindex(subcadena,cadena,inicio): devuelve la posición donde comienza la subcadena


en la cadena, comenzando la búsqueda desde la posición indicada por “inicio”. Si el tercer
argumento no se coloca, la búsqueda se inicia desde 0. Si no la encuentra, retorna 0.
Ejemplo:

replicate(cadena,cantidad): repite una cadena la cantidad de veces especificada.

Ejemplo:
space(cantidad): retorna una cadena de espacios de longitud indicada por “cantidad”, que
debe ser un valor positivo.

Ejemplo:

Todas estas funciones se pueden utilizar enviando como argumento el nombre de un campo
de tipo carácter.

En el siguiente ejemplo mostramos el primer carácter del campo signatura de la tabla libros
de una base de datos:
5.4. Funciones fecha y hora

Además de las funciones integradas que hemos visto SQL ofrece algunas funciones para
trabajar con fechas y horas. Vamos a estudiar algunas de ellas:

getdate(): retorna la fecha y hora actuales.

Ejemplo:

datepart(partedefecha,fecha): retorna la parte específica de una fecha, el año, trimestre,


día, hora, etc.

Los valores para “partedefecha” pueden ser: year, quarter, month, day, week, hour, minute,
second y millisecond.

Ejemplos:
datename(partedefecha,fecha): retorna el nombre de una parte específica de una fecha.
Los valores para “partedefecha” pueden ser los mismos que para datepart

Ejemplos:
dateadd(partedelafecha,numero,fecha): agrega un intervalo a la fecha especificada, es
decir, retorna una fecha adicionando a la fecha enviada como tercer argumento, el intervalo de
tiempo indicado por el primer parámetro, tantas veces como lo indica el segundo parámetro.
Los valores para “partedefecha” pueden ser los mismos que para datepart

Ejemplo:

day(fecha): retorna el día de la fecha especificada.

Ejemplo:
month(fecha): retorna el mes de la fecha especificada.

Ejemplo:

year(fecha): retorna el año de la fecha especificada.

Ejemplo:

Se pueden emplear estas funciones enviando como argumento el nombre de un campo de


tipo datetime o smalldatetime

5.5. Funciones numéricas

Ya hemos visto algunos operadores, conocidos como operadores aritméticos, que nos
permiten llevar a cabo las operaciones más básicas sobre los números: adición, sustracción,
producto y división. Estos operadores se complementan con una serie de funcio­nes que
permiten operaciones más complejas.

El conjunto de funciones numéricas del lenguaje SQL están­dar, no es muy extenso, además
cada RDBMS aporta funciones exclusivas, diferentes en cada producto, que puede usar para
obtener los resultados que con las funciones estándar no se puedan realizar.

Las funciones numéricas realizan operaciones con expresiones numéricas y retornan un


resultado, operan con tipos de datos numéricos.

Vamos a ver algunas de ellas:


abs(x): retorna el valor absoluto del argumento.

Ejemplo:

ceiling(x): redondea hacia arriba el valor pasado como argumento.

Ejemplo:
floor(x): redondea hacia abajo el argumento “x”.

Ejemplo:

%: devuelve el resto de una división.

Ejemplo:

power(x,y): retorna el valor de “x” elevado a la “y” potencia.


Ejemplo:

round(numero,longitud): retorna un número redondeado a la longitud especificada.


“longitud” debe ser tinyint, smallint o int. Si “longitud” es positivo, el número de decimales es
redondeado según “longitud”; si es negativo, el número es redondeado desde la parte entera
según el valor de “longitud”.

Ejemplos:
sign(x): si el argumento es un valor positivo devuelve 1;-1 si es negativo y si es 0, 0.
Ejemplo:

square(x): retorna el cuadrado del argumento.

Ejemplo:
srqt(x): devuelve la raíz cuadrada del valor enviado como argumento.
Ejemplo:
UNIDAD 6
6.1. Crear y eliminar vistas
6.2. Filtrado de filas
6.3. Vistas con columnas derivadas
6.4. Actualización de datos a través de una vista
6.1. Crear y eliminar vistas

Una base de datos puede contener, aparte de las tablas donde se aloja la información
propiamente dicha, otros obje­tos que facilitan el trabajo con ella o mejoran su rendimiento.
Entre esos objetos se encuentran las vistas.

Las vistas son un recurso muy útil para facilitar el acceso a la información a aquellos usuarios
que no tienen un gran conocimiento del lenguaje SQL, así como un elemento de se­guridad al
ocultar a dichos usuarios la estructura real de las tablas y ofrecerles únicamente aquellos datos
que precisan.

Una vista, es una consulta SQL almacena­da en la propia base de datos. También conocidas
como tablas virtuales, las vistas tienen el objetivo de ofrecer a los usuarios de una base de
datos vistas diferentes de la misma informa­ción. Es decir, una vista no genera nuevos datos,
salvo datos derivados mediante el uso de funciones SQL, sino que a tra­vés de filtros, uniones,
agrupaciones y ordenaciones permiten obtener una visión diferente de esos mismos datos.

Una vista almacena una consulta como un objeto para utilizarse posteriormente. Las tablas
consultadas en una vista se llaman tablas base. En general, se puede dar un nombre a cualquier
consulta y almacenarla como una vista.

Las vistas permiten:


• ocultar información: permitiendo el acceso a algunos datos y manteniendo oculto el
resto de la información que no se incluye en la vista. El usuario opera con los datos de una
vista como si se tratara de una tabla, pudiendo modificar tales datos.
• simplificar la administración de los permisos de usuario: se pueden dar al usuario permisos para
que solamente pueda acceder a los datos a través de vistas, en lugar de concederle permisos para
acceder a ciertos campos, así se protegen las tablas base de cambios en su estructura.
• mejorar el rendimiento: se puede evitar tipear instrucciones repetidamente almacenando en una
vista el resultado de una consulta compleja que incluya información de varias tablas.

Podemos crear vistas con: un subconjunto de registros y campos de una tabla; una unión de varias
tablas; una combinación de varias tablas; un resumen estadístico de una tabla; un subconjunto de otra
vista, combinación de vistas y tablas.

Una vista se define usando un “select”.


La sintaxis básica parcial para crear una vista es la siguiente:
create view NOMBREVISTA as
SENTENCIAS SELECT
from TABLA;

El contenido de una vista se muestra con un “select”:


select *from NOMBREVISTA;

Vamos a realizar un ejemplo que crea una vista llamada vista_socios de las tablas socios y
prestamos de la base de datos biblioteca.

Cuando se ejecuta la vista nos dice que los comandos se han completado correctamente,
ahora tenemos que mostrar los datos de la vista.
También podemos realizar consultas a una vista como si se tratara de una tabla:

Los nombres para vistas deben seguir las mismas reglas que cualquier identificador. Para
distinguir una tabla de una vista podemos fijar una convención para darle nombres, por
ejemplo, colocar el sufijo “vista” y luego el nombre de las tablas consultadas en ellas.

Los campos y expresiones de la consulta que define una vista deben tener un nombre. Se
debe colocar nombre de campo cuando es un campo calculado o si hay 2 campos con el mismo
nombre. En el ejemplo, al concatenar los campos “apellido” y “nombre” colocamos un alias; si
no lo hubiésemos hecho aparecería un mensaje de error porque dicha expresión debe tener
un encabezado, SQL Server no lo coloca por defecto.

Los nombres de los campos y expresiones de la consulta que define una vista deben ser
únicos (no puede haber dos campos o encabezados con igual nombre).

La eliminación de una vista, como la de cualquier otro ob­jeto existente en la base de datos,
se lleva a cabo con la senten­cia DROP, e

La sintaxis básica para eliminar una vista es la siguiente:


DROP VIEW nombrevista

En el ejemplo se muestra como eliminar la vista socios que hemos creado:

6.2. Filtrado de filas

En el ejemplo anterior hemos visto que podemos filtrar las columnas de una vista pero
más útil que el filtrado de columnas, en la medida de que no es posible aplicar privilegios que
limiten las filas a las que puede accederse y la composición de la consulta resulta algo más
compleja al incluir la cláusula WHERE con su respectivo condicional de búsqueda, resulta la
creación de vistas que se encarguen del filtrado de filas.

Por ejemplo en una biblioteca si un operador necesita conocer los libros que hay dispo­nibles,
que pueden prestarse, para atender la consulta de un socio, trabajando directamente sobre la
tabla libros se vería forzado a ir examinando la columna disponible fila a fila, para saber si está
o no disponible. También podría, supo­niendo que contase con los conocimientos necesarios,
efectuar una consulta que incluyese la cláusula WHERE con la condi­ción disponible=’ S’.

Pero sin duda le sería mucho más fácil, sin duda, utilizar una vista. Vamos a verlo con un
ejemplo:

Creamos la vista que nos permita obtener todos los libros disponibles.

Después ejecutamos la consulta para ver los libros disponibles, de este modo el operador
no tiene que recorrer todos los datos de la tabla libros
Aunque la vista esté definida como una consulta con un filtro de filas, para el usuario final
aparece como si fuese una tabla y, por tanto, como tal puede ejecutar cualquier consulta sobre
ella siempre que sus privilegios se lo permitan.

Por ejemplo un operador puede buscar en los libros disponibles aquel que tenga el código
4.

6.3. Vistas con columnas derivadas

Las vistas de los ejemplos anteriores ofrecen siempre como resultado columnas tomadas
de tablas existentes en la base de datos, ya sean de una única tabla o de varias de ellas en
caso de que se efectúe algún tipo de unión o combinación. Las vistas pueden también generar
información propia a par­tir de columnas calculadas o derivadas, usando para ello los operadores
aritméticos y funciones que hemos ido conocien­do en las unidades anteriores.

Cuando una vista va a usar en la consulta expresiones que generan columnas adicionales,
derivadas de las ya existentes, es necesario que en la cabecera, tras el nombre que va a asignase
a la vista, facilitemos entre paréntesis los nombres de las columnas.

Esto nos permite dar cualquier nombre a las columnas ge­neradas por la vista, nombre que
no tiene necesariamente que coincidir con el que tienen originalmente las columnas en la
tabla. Otra opción, para asignar nombre a las columnas deri­vadas, es usar la cláusula AS tras
ese tipo de columnas y el nombre que ponemos a la columna:

Vamos a realizar un ejemplo que define una vista que fa­cilita el nombre de cada autor y el
número de libros suyos que tenemos registrados de una tabla libros, empleando para ello la
función COUNT y la cláusula GROUP BY.
Ejecutamos una consulta sobre la vista para ver los datos:

Podemos observar que la columna numtitulos aparece como una columna más y no hay
referencia alguna a que sea resultado de un cálculo.

Una columna derivada no tiene necesariamente que agrupar los datos, como en este
ejemplo, pudiendo limitarse a añadir alguna columna.
6.4. Actualización de datos a través de una vista

El estándar SQL indica que una vista debe ser actualizable siempre que la operación a
ejecutar tenga sentido, si bien cada RDBMS añade sus propias restricciones al respecto.
Actuali­zable significa, en este contexto, que permite la inserción de filas, la modificación del
contenido de las columnas o bien la eliminación de filas. Obviamente esas operaciones no
afectan a la vista en sí, sino a las tablas de las que ésta toma los datos.

Las operaciones de actualización sobre una vista no pueden en ningún caso infringir las
restricciones definidas en las tablas de origen.

Vamos a crear una vista DatosSocios que nos permita introducir datos en un tabla socios.

Ahora vamos a introducir un socio en la tabla socios utilizando la tabla creada.


La nueva fila se añade sin ningún problema, por supues­to siempre que el usuario tenga los
privilegios necesarios pa­ra ejecutar una sentencia INSERT sobre la vista. De la misma manera
podría eliminar una de las filas de la vista, en reali­dad la fila completa de la tabla de la que
procede, o modifi­car las columnas.

Evitar que los usuarios puedan modificar ciertas columnas resulta muy fácil a través de una
vista. El operador que tiene acceso a DatosSocios, y el privilegio para efectuar modifi­caciones,
no podrá, por ejemplo, alterar la dirección, el código postal o fecha de alta, sencillamente
porque esas columnas no forman parte de la vista.
Lenguaje SQL 111

También podría gustarte