Sunteți pe pagina 1din 96

SQL Lic.

Gustavo Rei

A N AL I S T AS D E S I S T E M AS

S ISTEMAS DE P RO CESAMI ENTO DE D ATOS 3


L ENGUAJES 2

MATERIAS:
Sistemas de Procesamiento de Datos 3
Lenguajes 2

DADO POR: Licenciado en Informática Gustavo Víctor Rei

APUNTE GENERAL DE LA MATERIA (SQL)

Versión : 01

SQL

Nota del Autor


La presente edición representa una revisión mayor de los apuntes anteriores como así también de sus auxiliares didáctico rela-
cionados.

Este apunte esta diseñado como material auxiliar de la cátedra, no debe ser tomado como único material de estudio, sino simple-
mente como base de guía de los temas expuestos en clase.

Todo lo trascripto en este apunte es recopilación de varios libros, más apuntes personales del autor y otros colaboradores.

Todos los libros utilizados son mencionados en Bibliografía a la cual el alumno deberá remitirse para ampliar los temas aquí trata-
dos.

AÑO 2003 Página 1 de 96


SQL Lic. Gustavo Rei

Base De Datos Y Modelos De Datos:


Una base de datos está generalmente definida como un conjunto integrado de datos que modelizan un universo dado. Este uni-
verso está compuesto por objetos interrelacionados, los objetos de un mismo tipo constituyen una entidad y el lazo habido entre entidades
se le denomina asociación.
El proceso de descripción de asociaciones y entidades se llama modelización y se hace con la ayuda de un modelo de datos,
existen actualmente cuatro modelos de datos diferentes:

• Modelo jerárquico.
• Modelo en red
• Modelo objeto
• Modelo relacional: el principio básico de este modelo consiste en representar tanto las entidades como las asociaciones con la
ayuda de relaciones denominadas también tablas. Una tabla está compuesta por líneas y columnas, cada línea representa un ob-
jeto (proveedor-articulo) las columnas representan los atributos de dicho objeto. Una tabla es una estructura.

OBJETIVOS DE LOS SISTEMAS DE GESTIÓN DE BASE DE DATOS:


Las funciones de los S.G.B.D. son:
• Debe permitir la definición de todos los datos
• Debe permitir manipular datos
• Debe establecer controles para la seguridad de estos datos
• Debe permitir los accesos concurrentes.

SUBLENGUAJES DEL SQL.:


L.D.D. Lenguaje de descripción de datos.
L.M.D. Lenguaje de manipulación de datos
L.C.M. Lenguaje de control de datos.

OBJETIVOS S.G.B.D.:
• Definición de datos: (modifica la estructura o añade campos). La misión del L.D.D. es describir y definir todos los esquemas que
participen en la base de datos. Esto consiste en la descripción de los objetos que vamos a representar. La descripción de todas
las estructuras que formen nuestra base de datos. Definición de vista: es una visión parcial de la tabla. “cuando en una tabla algu-
na parte de esta no quiero que tenga derecho a manipularla nadie”

• Manipulación de datos: L.M.D. recoge todas las operaciones de intercambio de datos entre las tablas, estas operaciones pueden
ser de consulta o de puesta al día (inserción, modificación, supresión) estas operaciones se realizan con la ayuda del denominado
L.M.D.
• Seguridad de los datos: consiste en garantizar que sólo los usuarios autorizados puedan efectuar operaciones correctas sobre la
Base de Datos para ello se dispone de 2 tipos.

o Control sobre la base de datos


o Control sobre las tablas

GESTIÓN DE LOS ACCESOS CONCURRENTES:


El principal objetivo de la implantación de una base de datos es poner a disposición de un gran número de usuarios en conjunto
integrado de datos, estos datos podrán ser manipulados por los diferentes usuarios y es ahora cuando se debe garantizar la coherencia de
los datos después de las diversas manipulaciones. Esto se garantiza con la ayuda del concepto de transacción “se define como transacción
a una unidad lógica de tratamiento que aplicada a un estado coherente de una base de datos restituye un nuevo estado coherente de la
base de datos pero con estos modificados, únicamente puede ser modificada completamente anulado”.

Concepción de una base de datos:


El ciclo de vida de una base de datos puede descomponerse en 3 etapas:
• Concepción: la fase de concepción consiste en reproducir en el mundo real con ayuda de uno de los modelos de datos conocidos
(relacional). El resultado de esta fase en un esquema escrito según un formalismo cualquiera no interpretable por el S.G.B.D.
• Creación de la B.D. vacía: La 2ª fase consiste en traducir este esquema en órdenes comprensibles para el S.G.B.D. como resulta-
do se obtiene la estructura de la base de datos desprovista de cualquier tipo de información.
• Explotación: Es en esta fase donde los registros serán manipulados con la ayuda de los lenguajes de programación. Es ahora
cuando los usuarios pueden consultar los datos y ponerlos a punto durante el resto de la vida de la base de datos.

Problemas adquiridos por una mala concepción de una base de datos:

AÑO 2003 Página 2 de 96


SQL Lic. Gustavo Rei

En las tablas hay que procurar que no haya duplicidad de datos:


• Redundancia de datos: si un cliente ha realizado más de un pedido todos los datos de este cliente estarán repetidos tantas veces
como pedidos haya, lo mismo sucede para los artículos esto es opuesto al principal objetivo de una base de datos que consiste en
evitar la repetición de los mismos.
• Puestas al día múltiple: Para poder asegurar la coherencia de los datos es necesario efectuar puestas a día múltiples. ”Cuando un
cliente cambia de dirección”
• Incoherencia de los datos: Sí una operación de puesta al día múltiple no se ha realizado completamente el estado de la base de
datos queda incoherente y puede producir errores importantes.
• Pérdida de datos: La supresión de una línea en la tabla de pedidos entraña la pérdida de todos los datos relativos a un cliente si
no ha efectuado ningún otro pedido. Esto es cierto también para un artículo que no ha sido pedido por ningún otro cliente. Estas
anormalidades constituyen lo que se ha convenido en llamar “comportamiento anormal de las tablas”, para evitar esto existe un
proceso llamado “normalización” que entre otras cosas intenta esclarecer los conceptos de “dependencia funcional y estado de las
tablas”.
• Dependencia funcional: Este concepto se aplica a las columnas y consiste en hacer corresponder un único valor a aquella colum-
na o columnas que consideremos más significativas.
• Estado de la tabla: Se dice que una tabla esta en estado de 1ª forma normal si toda columna de esta tabla no puede tener más
que valores atómicos, un valor es atómica si él no es divisible.

Estructura básica del lenguaje de programación SQL.:


• Base de datos: Esta compuesta de un conjunto de tablas del sistema creadas implícitamente por él y por un conjunto de tablas y
vistas creadas por el usuario.
• Tablas: En informix, SQL server, Oracle, DB2, etc. el universo está descrito con la ayuda de tablas, cada una representa a una en-
tidad o a una asociación entre entidades. Las tablas están compuestas de columnas o de líneas o filas llamadas convencional-
mente campos y registros. Una columna representa un atributo de la entidad y para describirla es necesario especificar un nombre
y un tipo de datos, una particularidad de las columnas es que pueden permitir o no valores nulos.
o Fila: Es una combinación de los diferentes atributos del objeto (registro).
o Vistas: Es una tabla virtual definida sobre las tablas bases descritas por el usuario su objeto es permitir a los usuarios
manipular un subconjunto de datos.
o Usuarios: uno de los objetivos de un sistema de gestión de base de datos es el de afianzar la seguridad de los datos,
para hacer esto el lenguaje de programación genera todos los usuarios y sus permisos de acceso para acceder a una
base de datos, cada usuario debe disponer de su autorización correspondiente y es el propietario de la base de datos el
que debe dar y retirar permisos de acceso.
o Índices: Se utilizan para aumentar el rendimiento del sistema y asegurar la integridad de los datos. A cada tabla que se
crea se la asocia automáticamente una tabla índice que contiene la posición del registro según la columna especificada
como índice.

¿Qué es el SQL?
Antes de empezar debes tener unas nociones básicas de bases de datos relacionales, si quieres repasarlas recurrí a tus apuntes
de clases de bases de datos
El SQL (Structured query language), lenguaje de consulta estructurado, es un lenguaje surgido de un proyecto de investigación
de IBM para el acceso a bases de datos relacionales. Actualmente se ha convertido en un estándar de lenguaje de bases de datos, y la
mayoría de los sistemas de bases de datos lo soportan, desde sistemas para ordenadores personales, hasta grandes ordenadores.
Como su nombre indica, el SQL nos permite realizar consultas a la base de datos. Pero el nombre se queda corto ya que SQL
además realiza funciones de definición, control y gestión de la base de datos. Las sentencias SQL se clasifican según su finalidad
dando origen a tres ‘lenguajes’ o mejor dicho sublenguajes:
• El DDL (Data Description Language), lenguaje de definición de datos, incluye órdenes para definir, modificar o borrar las tablas en
las que se almacenan los datos y de las relaciones entre estas. (Es el que más varia de un sistema a otro)
• El DCL (Data Control Language), lenguaje de control de datos, contiene elementos útiles para trabajar en un entorno multiusuario,
en el que es importante la protección de los datos, la seguridad de las tablas y el establecimiento de restricciones en el acceso, así como
elementos para coordinar la compartición de datos por parte de usuarios concurrentes, asegurando que no interfieren unos con otros.
• El DML (Data Manipulation Language), lenguaje de manipulación de datos, nos permite recuperar los datos almacenados en la
base de datos y también incluye órdenes para permitir al usuario actualizar la base de datos añadiendo nuevos datos, suprimiendo datos
antiguos o modificando datos previamente almacenados.

Características del lenguaje


Una sentencia SQL es como una frase (escrita en inglés) con la que decimos lo que queremos obtener y de donde obtenerlo.
Todas las sentencias empiezan con un verbo (palabra reservada que indica la acción a realizar), seguido del resto de cláusulas,
algunas obligatorias y otras opcionales que completan la frase. Todas las sentencias siguen una sintaxis para que se puedan ejecutar co-
rrectamente, para describir esa sintaxis utilizaremos un diagrama sintáctico como el que se muestra a continuación.

¿Existe un solo SQL?

AÑO 2003 Página 3 de 96


SQL Lic. Gustavo Rei

Es muy común creer que existe un único SQL, pero debemos tener en cuenta que existen tantos SQL como DBMS lo utilicen, da-
do que cada fabricante le realiza agregados o le brinda distintos potenciales según las características propias de cada Soft.
Ante estas circunstancias, se deberá tener en claro, que es imposible dar en el transcurso de la presente cátedra la totalidad de
las variantes de SQL que existen, pese a que todos se basan en SQL 92, un Standard del mercado.
Para clarificar lo presente podemos dar como ejemplos las variaciones de SQL más conocidas del mercado:
• SQL86 - Estándar inicial de SQL. Conjunto limitado de características. Apenas con alguna restricción de integridad.
• SQL89 - Revisión mínima del estándar del 86. Añade cierta integridad referencial.
• SQL92 (SQL2)- Revisión completa del lenguaje (súper conjunto del SQL89). Sobre todo se añade más potencia semántica en la
definición de datos (restricciones de integridad, dominios, más tipos de datos). Mejora el lenguaje de consulta (Ej. productos natu-
ral y externo) y elimina problemas de ortogonalidad. Estandariza el SQL inmerso.
• SQL3 – Siguiente revisión del SQL en proceso de estandarización.
• SQL propio de ORACLE1
• SQL de INFORMIX (sobre UNÍX)
• SQL de SQL Server (MS)2
• SQL de Access (y sus diferentes versiones)

Ante esta posiblididad y a los efectos de clarificar el contenido de la materia nos ajustaremos al SQL propio del SQL Server, y
SQL de Access. (El primero por ser el que obra en los laboratorios del Instituto y el segundo por pertenecer a un software apto para todos
los usuarios.

Composición del Lenguaje


El lenguaje SQL está compuesto por comandos, cláusulas, operadores y funciones de agregado. Estos elementos se combinan
en las instrucciones para crear, actualizar y manipular las bases de datos.

1
Oracle 7 Manual de Referencia, Koch, George., Osborne/McGraw-Hill, 1994
2
http://www.microsoft.com/sql/
AÑO 2003 Página 4 de 96
SQL Lic. Gustavo Rei

Una sentencia SQL es como una frase (escrita en inglés) con la que decimos lo que queremos obtener y de donde obtenerlo.
Todas las sentencias empiezan con un verbo (palabra reservada que indica la acción a realizar), seguido del resto de cláusulas,
algunas obligatorias y otras opcionales que completan la frase. Todas las sentencias siguen una sintaxis para que se puedan ejecutar
correctamente, para describir esa sintaxis utilizaremos un diagrama sintáctico como el que se muestra a continuación.

Primeros comandos
Consultas Simples
SELECT
Empezaremos por estudiar la sentencia SELECT, que permite recuperar datos de una o varias tablas. La sentencia SELECT es
con mucho la más compleja y potente de las sentencias SQL. Empezaremos por ver las consultas más simples, basadas en una sola tabla.
Esta sentencia forma parte del DML (lenguaje de manipulación de datos), en este tema veremos cómo seleccionar columnas de
una tabla, cómo seleccionar filas y cómo obtener las filas ordenadas por el criterio que queramos.
El resultado de la consulta es una tabla lógica, porque no se guarda en el disco sino que está en memoria y cada vez que ejecu-
tamos la consulta se vuelve a calcular.
Cuando ejecutamos la consulta se visualiza el resultado en forma de tabla con columnas y filas, pues en la SELECT tenemos que
indicar qué columnas queremos que tenga el resultado y qué filas queremos seleccionar de la tabla origen.

FROM
Con la cláusula FROM indicamos en qué tabla tiene que buscar la información. En este capítulo de consultas simples el resul-
tado se obtiene de una única tabla. La sintaxis de la cláusula es:

FROM ESPECIFICACIÓN DE TABLA


Una especificación de tabla puede ser el nombre de una consulta guardada (las que aparecen en la ventana de base de datos), o

el nombre de una tabla que a su vez puede tener el siguiente formato:

ALIAS DE TABLA
Aliastabla es un nombre de alias, es como un segundo nombre que asignamos a la tabla, si en una consulta definimos un alias
para la tabla, esta se deberá nombrar utilizando ese nombre y no su nombre real, además ese nombre sólo es válido en la consulta
donde se define. El alias se suele emplear en consultas basadas en más de una tabla que veremos en el tema siguiente. La palabra AS que
se puede poner delante del nombre de alias es opcional y es el valor por defecto por lo que no tienen ningún efecto.
Ejemplo: SELECT ......FROM oficinas ofi ; equivalente a SELECT ......FROM oficinas AS ofi esta sentencia me indica que se
van a buscar los datos en la tabla oficinas que queda renombrada en esta consulta con ofi.

AÑO 2003 Página 5 de 96


SQL Lic. Gustavo Rei

IN
En una SELECT podemos utilizar tablas que no están definidas en la base de datos (siempre que tengamos los permisos ade-
cuados claro), si la tabla no está en la base de datos activa, debemos indicar en qué base de datos se encuentra con la cláusula IN.
En la cláusula IN el nombre de la base de datos debe incluir el camino completo, la extensión (.mdb)3, y estar entre comillas
simples.
Supongamos que la tabla empleados estuviese en otra base de datos llamada otra en la carpeta c:\mis documentos\, habría que
indicarlo así:
SELECT * FROM empleados IN 'c:\mis documentos\otra.mdb'4
Generalmente tenemos las tablas en la misma base de datos y no hay que utilizar la cláusula IN.

COLUMNAS (CAMPOS)
La lista de columnas que queremos que aparezcan en el resultado es lo que llamamos lista de selección y se especifica delante
de la cláusula FROM.

ASTERISCO

Se utiliza el asterisco * en la lista de selección para indicar 'todas las columnas de la tabla'.
Tiene dos ventajas:
Evitar nombrar las columnas una a una (es más corto).
Si añadimos una columna nueva en la tabla, esta nueva columna saldrá sin tener que modificar la consulta.
Se puede combinar el * con el nombre de una tabla (Ej. oficinas.*), pero esto se utiliza más cuando el origen de la consulta son
dos tablas.

ALIAS DE COLUMNA.
Cuando se visualiza el resultado de la consulta, normalmente las columnas toman el nombre que tiene la columna en la tabla, si
queremos cambiar ese nombre lo podemos hacer definiendo un alias de columna mediante la cláusula AS será el nombre que aparecerá
como título de la columna.

COLUMNAS CALCULADAS.
Además de las columnas que provienen directamente de la tabla origen, una consulta SQL puede incluir columnas calculadas
cuyos valores se calculan a partir de los valores de los datos almacenados.
Para solicitar una columna calculada, se especifica en la lista de selección una expresión en vez de un nombre de columna. La
expresión puede contener sumas, restas, multiplicaciones y divisiones, concatenación &5 , paréntesis y también funciones predefinidas).

FORMAR EXPRESIONES.
Una expresión se forma combinando un operador con uno o generalmente dos operandos.

OPERADORES.
ACCESS
operador +, se utiliza para sumar dos números.
operador -, se utiliza para hallar la diferencia entre dos números.
operador *, se utiliza para multiplicar dos números.
operador ^, se utiliza para elevar un número a la potencia del exponente ( número ^ exponente )
operador / , se utiliza para dividir dos números y obtener un resultado de signo flotante.
operador \, se utiliza para dividir dos números y obtener un resultado entero.
operador Mod, divide dos números y devuelve sólo el resto.
El operador &, se utiliza para concatenar dos expresiones de tipo texto.

3
Este comando se refiere a MS Acces, varía según el DBMS
4
Este comando se refiere a MS Access.
5
El carácter de concatenación varía según el DBMS, &: acces, % sql92, etc.

AÑO 2003 Página 6 de 96


SQL Lic. Gustavo Rei

También se puede utilizar el operador de suma + cuando los dos operandos son de tipo texto, para concatenarlos.
Un operando puede ser un nombre de columna, una expresión, un valor concreto o una función predefinida.

SQL SERVER
Operadores aritméticos

Operador Significado
+ (suma) Suma.
- (resta) Resta.
* (multiplicación) Multiplicación.
/ (división) División.
% (módulo) Devuelve el resto entero de una división. Por ejemplo, 12 % 5 = 2 porque el resto de 12 dividido
entre 5 es 2.

Operadores BIT a BIT


Los operadores BIT a BIT realizan tratamientos de bits entre dos expresiones de cualquiera de los tipos de datos de la categoría
del tipo de datos enteros.
Operador Significado
& (operador bit a bit AND) Operador bit a bit AND (dos operandos).
| (operador bit a bit OR) Operador bit a bit OR (dos operandos).
^ (operador bit a bit OR exclu- Operador bit a bit OR-exclusivo (dos operan-
sivo) dos).

Los operandos para los operadores BIT a BIT pueden ser de cualquiera de los tipos de datos de las categorías entero o cadena
binaria (excepto el tipo de datos image), con la excepción de que ambos operandos no pueden ser de cualquiera de los tipos de datos de la
categoría cadena binaria. La siguiente tabla muestra los tipos de datos de operando admitidos.
Operando izquier- Operando derecho
do
binary int, smallint o tinyint
bit int, smallint, tinyint o bit
int int, smallint, tinyint, binary o varbi-
nary
smallint int, smallint, tinyint, binary o varbi-
nary
tinyint int, smallint, tinyint, binary o varbi-
nary
varbinary int, smallint o tinyint

Operadores de comparación
Los operadores de comparación comprueban si dos expresiones son iguales o no. Se pueden utilizar en todas las expresiones
excepto en las de los tipos de datos text, ntext o image.
Operador Significado
= (igual al) Igual a
> (mayor que) Mayor que
< (menor que) Menor que
>= (mayor que o igual Mayor que o igual a
que)
<= (menor que o igual Menor que o igual a
que)
<> (no es igual a) No es igual a

AÑO 2003 Página 7 de 96


SQL Lic. Gustavo Rei

Operador Significado
!= (no es igual a) No es igual a (no es del estándar SQL-92)
!< (no es menor que) No es menor que (no es del estándar
SQL-92)
!> (no es mayor que) No es mayor que (no es del estándar
SQL-92)

Operadores lógicos
Los operadores lógicos comprueban la veracidad de alguna condición. Éstos, como los operadores de comparación, devuelven el
tipo de datos Boolean con valor TRUE o FALSE.
Operador Significado
ALL TRUE si el conjunto completo de comparaciones es TRUE.
AND TRUE si ambas expresiones booleanas son TRUE.
ANY TRUE si una cualquier miembro del conjunto de comparaciones es
TRUE.
BETWEEN TRUE si el operando está dentro de un intervalo.
EXISTS TRUE si una subconsulta contiene a cualquiera de las filas.
IN TRUE si el operando es igual a uno de la lista de expresiones.
LIKE TRUE si el operando coincide con un patrón.
NOT Invierte el valor de cualquier otro operador booleano.
OR TRUE si cualquiera de las dos expresiones booleanas es TRUE.
SOME TRUE si alguna de las comparaciones de un conjunto es TRUE.

FUNCIONES
Access
DATE () devuelve el día en que estamos
NOW () devuelve el día y la hora actual
YEAR (fecha) devuelve el año de la fecha
MONTH (fecha) devuelve el mes de la fecha
DATEVALUE (literal) convierte el literal en un valor de fecha.

SQL Server

Funciones de agregado
El lenguaje de programación Transact-SQL proporciona estas funciones de agregado:
AVG MAX
BINARY_CHECKSUM MIN
CHECKSUM SUM
CHECKSUM_AGG STDEV
COUNT STDEVP
COUNT_BIG VAR
GROUPING VARP

Funciones de fecha y hora


Estas funciones escalares realizan una operación sobre un valor de fecha y hora de entrada, y devuelven un valor de cadena,
numérico o de fecha y hora.
Esta tabla presenta las funciones de fecha y hora y su propiedad determinista. Para obtener más información acerca del determi-
nismo de funciones.

AÑO 2003 Página 8 de 96


SQL Lic. Gustavo Rei

Función Determinismo
DATEADD Determinista
DATEDIFF Determinista
DATENAME No determinista
DATEPART Determinista excepto cuando se utiliza como DATEPART (dw, date). La parte de la fecha correspondiente al día de la semana
(dw) depende del valor establecido por SET DATEFIRST, que indica el primer día de la semana.
DAY Determinista
GETDATE No determinista
GETUTCDATE No determinista
MONTH Determinista
YEAR Determinista

Funciones matemáticas
Estas funciones escalares realizan un cálculo, normalmente basado en valores de entrada proporcionados como argumentos, y
devuelven un valor numérico.
ABS DEGREES RAND
ACOS EXP ROUND
ASIN FLOOR SIGN
ATAN LOG SIN
ATN2 LOG10 SQUARE
CEILING PI SQRT
COS POWER TAN
COT RADIANS

Funciones de cadena
Estas funciones escalares realizan una operación sobre una cadena de entrada y devuelven un valor de cadena o un valor numé-
rico.
ASCII NCHAR SOUNDEX
CHAR PATINDEX SPACE
CHARINDEX REPLACE STR
DIFFERENCE QUOTENAME STUFF
LEFT REPLICATE SUBSTRING
LEN REVERSE UNICODE
LOWER RIGHT UPPER
LTRIM RTRIM

Observaciones:
Se aclara que se ampliarán las funciones y operaciones en el transcurso de la clase.

Ordenación de las filas - ORDER by


Para ordenar las filas del resultado de la consulta, tenemos la cláusula ORDER by.
Con esta cláusula se altera el orden de visualización de las filas de la tabla pero en ningún caso se modifica el orden de las filas
dentro de la tabla. La tabla no se modifica.

Ejemplos de Select:
Todos estos ejemplos son en base a los conceptos adquiridos en el presente capítulo:

SELECT * FROM empleados IN 'c:\mis documentos\otra.mdb' Seleccionar datos en una base de datos externa (Ac-
AÑO 2003 Página 9 de 96
SQL Lic. Gustavo Rei

cess)
SELECT * FROM oficinas Lista todos los datos de las oficinas
o bien
SELECT oficinas.* FROM oficinas
SELECT nombre, oficina, contrato FROM ofiventas Lista el nombre, oficina, y fecha de contrato de todos los
empleados
SELECT idfab, idproducto, descripcion, precio Lista una tarifa de productos
FROM productos
SELECT idfab AS fabricante, idproducto, descripcion Como título de la primera columna aparecerá fabricante
FROM productos en vez de idfab
SELECT ciudad, región, (ventas-objetivo) AS superavit Lista la ciudad, región y el superavit de cada oficina.
FROM oficinas
SELECT idfab, idproducto, descripcion, (existencias * precio) AS De cada producto obtiene su fabricante, idproducto, su
valoración FROM productos descripción y el valor del inventario
SELECT nombre, MONTH(contrato), YEAR(contrato) Lista el nombre, mes y año del contrato de cada vende-
FROM repventas dor.
La función MONTH() devuelve el mes de una fecha
La función YEAR() devuelve el año de una fecha
SELECT nombre, numemp, oficinarep Obtiene un listado alfabético de los empleados
FROM empleados
ORDER BY nombre
SELECT nombre, numemp, contrato Obtiene un listado de los empleados por orden de anti-
FROM empleados güedad en la empresa empezando por los más recien-
ORDER BY contrato DESC temente incorporados.

Selección de filas Las cláusulas DISTINCT / ALL


Al incluir la cláusula DISTINCT en la SELECT, se eliminan del resultado las repeticiones de filas. Si por el contrario queremos
que aparezcan todas las filas incluidas las duplicadas, podemos incluir la cláusula ALL o nada, ya que ALL es el valor que SQL asume
por defecto.
Por ejemplo queremos saber los códigos de los directores de oficina.

SELECT dir FROM oficinas


Ó
SELECT ALL dir FROM oficinas

SELECT DISTINCT dir FROM oficinas

La cláusula TOP
La cláusula TOP permite sacar las n primeras filas de la tabla origen. No elige entre valores iguales, si pido los 25 primeros valo-
res pero el que hace 26 es el mismo valor que el 25, entonces devolverá 26 registros en vez de 25 (o los que sean). Siempre se guía por la
columna de ordenación, la que aparece en la cláusula ORDER BY o en su defecto la clave principal de la tabla.
Por ejemplo queremos saber los dos empleados más antiguos de la empresa.
SELECT TOP 2 numemp, nombre
Lista el código y nombre de los empleados ordenándolos por fecha de con-
FROM empleado
trato, sacando únicamente los dos primeros (serán los dos más antiguos).
ORDER BY contrato

En este caso tiene que sacar los tres primeros, pero si nos fijamos en las
SELECT TOP 3 numemp, nombre fechas de contrato tenemos 20/10/86, 10/12/86, 01/03/87, 01/03/87, la terce-
FROM empleado ra fecha es igual que la cuarta, en este caso sacará estas cuatro filas en vez
ORDER BY contrato de tres, y sacaría todas las filas que tuviesen el mismo valor que la tercera
fecha de contrato.
El número de filas que queremos visualizar se puede expresar con un número entero o como un porcentaje sobre el número to-
tal de filas que se recuperarían sin la cláusula TOP. En este último caso utilizaremos la cláusula TOP n PERCENT (porcentaje en inglés).
SELECT TOP 20 PERCENT nombre Lista el nombre de los empleados ordenándolos por fecha de contrato, sacando únicamente un
FROM empleado 20% del total de empleados. Como tenemos 10 empleados, sacará los dos primeros, si tuviésemos
ORDER BY contrato 100 empleados sacaría los 20 primeros.

La cláusula WHERE
La cláusula WHERE selecciona únicamente las filas que cumplan la condición de selección especificada.
En la consulta sólo aparecerán las filas para las cuales la condición es verdadera (TRUE), los valores nulos (NULL) no se incluyen por lo
tanto en las filas del resultado. La condición de selección puede ser cualquier condición válida o combinación de condiciones utilizan-

AÑO 2003 Página 10 de 96


SQL Lic. Gustavo Rei

do los operadores NOT (no) AND (y) y OR (ó). En ACCESS2000 una cláusula WHERE puede contener hasta 40 expresiones vinculadas
por operadores lógicos AND y OR.
Los operadores lógicos sirven para combinar condiciones. En Access2000 una condición puede tomar tres valores TRUE (verda-
dero), FALSE (falso) o NULL (nulo), por lo tanto el resultado de los operadores lógicos también será true, false o null.
Para ver cómo funcionan los operadores lógicos utilizaremos las tablas de verdad de estos operadores.

OPERADOR AND
Para que el resultado sea verdadero las dos condiciones deben ser verdaderas.
AND TRUE FALSE NULL
TRUE TRUE FALSE NULL
FALSE FALSE FALSE FALSE
NULL NULL FALSE NULL

OPERADOR OR.
El resultado es verdadero si al menos una de las dos condiciones es verdadera.
OR TRUE FALSE NULL
TRUE TRUE TRUE TRUE
FALSE TRUE FALSE NULL
NULL TRUE NULL NULL

OPERADOR NOT.
El resultado es invertido.
NOT TRUE FALSE NULL
FALSE TRUE NULL

Condiciones de selección
En SQL tenemos cinco condiciones básicas:
El test de comparación
El test de rango
El test de pertenencia a un conjunto
El test de valor nulo
El test de correspondencia con patrón.

EL TEST DE COMPARACIÓN.
Compara el valor de una expresión con el valor de otra.
La sintaxis es la siguiente:
= igual que
<> distinto de
< menor que
<= menor o
igual
> mayor que
>= mayor o
igual

TEST DE RANGO (BETWEEN).


Examina si el valor de la expresión está comprendido entre los dos valores definidos por exp1 y exp2.
Tiene la siguiente sintaxis:

TEST DE PERTENENCIA A CONJUNTO (IN)


Examina si el valor de la expresión es uno de los valores incluidos en la lista de valores.

TEST DE VALOR NULO (IS NULL)


Una condición de selección puede dar como resultado el valor verdadero TRUE, falso FALSE o nulo NULL.

AÑO 2003 Página 11 de 96


SQL Lic. Gustavo Rei

Cuando una columna que interviene en una condición de selección contiene el valor nulo, el resultado de la condición no es ver-
dadero ni falso, sino nulo, sea cual sea el test que se haya utilizado. Por eso si queremos listar las filas que tienen valor en una determinada
columna, no podemos utilizar el test de comparación, la condición oficina = null devuelve el valor nulo sea cual sea el valor contenido en
oficina. Si queremos preguntar si una columna contiene el valor nulo debemos utilizar un test especial, el test de valor nulo.

TEST DE CORRESPONDENCIA CON PATRÓN (LIKE)


Se utiliza cuando queremos utilizar caracteres comodines para formar el valor con el comparar.
Tiene la siguiente sintaxis:

Los comodines más usados son los siguientes:

? Representa un carácter cualquiera (Access)


* representa cero o más caracteres (Access)
# representa un dígito cualquiera (0-9) (Access)
% Cualquier cadena de cero o más caracteres. (SQL Server)
_ Cualquier carácter individual (SQL Server)
[ ] Cualquier carácter individual del intervalo (por ejemplo, [a-f]) o conjunto (por ejemplo, [abcdef]) especificado. (SQL Server)
[^] Cualquier carácter individual fuera del intervalo (por ejemplo, [^a - f]) o conjunto (por ejemplo, [^abcdef]) especificado. (SQL Server)

Ejemplos

SELECT numemp, nombre SELECT numemp, nombre


FROM empleados FROM empleados
WHERE nombre LIKE 'Luis*' WHERE nombre LIKE '??a*'

SELECT numemp, nombre SELECT phone


FROM empleados FROM pubs.dbo.authors
WHERE nombre LIKE '*Luis*' WHERE phone LIKE '415%'

Select * From clientes Where poblacion Like 'madrid' And Not nombre Like 'Pepe'

RESUMEN OPERADORES

Operador Propósito Ejemplo


= Igualdad. SELECT *
FROM emp
WHERE sal = 1500;
!=, ^=, <>, ¬= Desigualdad. SELECT *
FROM emp
WHERE sal != 1500;
<, > Mayor, menor. SELECT * FROM emp
WHERE sal > 1500;
SELECT * FROM emp
WHERE sal < 1500;
<=, >= Mayor, menor o igual. SELECT * FROM emp
WHERE sal >= 1500;
SELECT * FROM emp
WHERE sal <= 1500;
IN Igual a cualquier miembro a probar, igual SELECT * FROM emp
a =ANY. WHERE job IN
(’CLERK’,’ANALYST’);
SELECT * FROM emp
WHERE sal IN
(SELECT sal FROM emp
AÑO 2003 Página 12 de 96
SQL Lic. Gustavo Rei

Operador Propósito Ejemplo


WHERE deptno = 30);
NOT IN Igual a !=ANY. SELECT * FROM emp
WHERE sal NOT IN
(SELECT sal FROM emp
WHERE deptno = 30);
SELECT * FROM emp
WHERE job NOT IN
(’CLERK’, ANALYST’);
ANY SOME Compara un valor a cada valor en una SELECT * FROM emp
lista, precedido por =, !=, >, <, <=, >=. WHERE sal = ANY
(SELECT sal FROM emp
WHERE deptno = 30);
ALL Similar al anterior. SELECT * FROM emp
WHERE sal >=
ALL ( 1400, 3000);
[NOT] BETWEEN X AND Y Entre X e Y. SELECT * FROM emp
WHERE sal
BETWEEN 2000 AND
3000;
EXISTS Verdadero si una subquery entrega al SELECT ename, deptno
menos una fila. FROM dept
WHERE EXISTS
(SELECT * FROM emp
WHERE dept.deptno
= emp.deptno);
X [NOT] LIKE Y [ESCAPE Verdadero si x está en un patrón y. SELECT * FROM tab1
’z’] Dentro de y el carácter “%” calza con WHERE col1 LIKE
cualquier carácter menos NULL. “_” calza
con cualquier carácter simple. ’A_C/%E%’ ESCAPE
’/’;
IS [NOT] NULL Prueba si hay [o no] NULL SELECT ename, deptno
FROM emp
WHERE comm IS NULL;
NOT IN Igual a != SELECT ’TRUE’
FROM emp
WHERE deptno NOT IN
(5,15,null);
Igual a:
deptno != 5 AND
deptno != 15 AND
deptno != null

AÑO 2003 Página 13 de 96


SQL Lic. Gustavo Rei

En este tema vamos a estudiar las consultas multitabla llamadas así porque están basadas en más de una tabla. Por ello estudia-
remos básicamente:
- la unión de tablas
- la composición de tablas

Conceptos Generales
LA UNIÓN DE TABLAS

Esta operación se utiliza cuando tenemos dos tablas con las mismas columnas y queremos obtener una nueva tabla con las filas
de la primera y las filas de la segunda. En este caso la tabla resultante tiene las mismas columnas que la primera tabla (que son las mismas
que las de la segunda tabla).
Por ejemplo tenemos una tabla de libros nuevos y una tabla de libros antiguos y queremos una lista con todos los libros que te-
nemos. En este caso las dos tablas tienen las mismas columnas, lo único que varía son las filas, además queremos obtener una lista de
libros (las columnas de una de las tablas) con las filas que están tanto en libros nuevos como las que están en libros antiguos, en este caso
utilizaremos este tipo de operación.
Cuando hablamos de tablas pueden ser tablas reales almacenadas en la base de datos o tablas lógicas (resultados de una con-
sulta), esto nos permite utilizar la operación con más frecuencia ya que pocas veces tenemos en una base de datos tablas idénticas en
cuanto a columnas. El resultado es siempre una tabla lógica.
Por ejemplo queremos en un sólo listado los productos cuyas existencias sean iguales a cero y también los productos que apare-
cen en pedidos del año 90. En este caso tenemos unos productos en la tabla de productos y los otros en la tabla de pedidos, las tablas no
tienen las mismas columnas no se puede hacer una unión de ellas pero lo que interesa realmente es el identificador del producto (idfab,
idproducto), luego por una parte sacamos los códigos de los productos con existencias cero (con una consulta), por otra parte los códigos
de los productos que aparecen en pedidos del año 90 (con otra consulta), y luego unimos estas dos tablas lógicas.
El operador que permite realizar esta operación es el operador UNION.

Ejemplo:
SELECT * FROM TableA
UNION
SELECT * FROM TableB
UNION
SELECT * FROM TableC
UNION
SELECT * FROM TableD

LA COMPOSICIÓN DE TABLAS

La composición de tablas consiste en concatenar filas de una tabla con filas de otra. En este caso obtenemos una tabla con las
columnas de la primera tabla unidas a las columnas de la segunda tabla, y las filas de la tabla resultante son concatenaciones de filas de la
primera tabla con filas de la segunda tabla.

AÑO 2003 Página 14 de 96


SQL Lic. Gustavo Rei

El ejemplo anterior quedaría de la siguiente forma con la composición:

A diferencia de la unión la composición permite obtener una fila con datos de las dos tablas, esto es muy útil cuando queremos vi-
sualizar filas cuyos datos se encuentran en dos tablas.
Por ejemplo queremos listar los pedidos con el nombre del representante que ha hecho el pedido, pues los datos del pedido los
tenemos en la tabla de pedidos pero el nombre del representante está en la tabla de empleados y además queremos que aparezcan en la
misma línea; en este caso necesitamos componer las dos tablas (Nota: en el ejemplo expuesto a continuación, hemos seleccionado las filas
que nos interesan).

Existen distintos tipos de composición, aprenderemos a utilizarlos todos y a elegir el tipo más apropiado a cada caso.
Los tipos de composición de tablas son:
El producto cartesiano
El INNER JOIN
El LEFT / RIGHT JOIN

Aplicación de los conceptos Generales


EL OPERADOR UNION
Como ya hemos visto en la página anterior, el operador UNION sirve para obtener a partir de dos tablas con las mismas colum-
nas, una nueva tabla con las filas de la primera y las filas de la segunda.
La sintaxis es la siguiente:

Consulta puede ser un nombre de tabla, un nombre de consulta (en estos dos casos el nombre debe estar precedido de la pala-
bra TABLE6), o una sentencia SELECT completa (en este caso no se puede poner TABLE). La sentencia SELECT puede ser cualquier
sentencia SELECT con la única restricción de que no puede contener la cláusula ORDER BY.
Después de la primera consulta viene la palabra UNION y a continuación la segunda consulta. La segunda consulta sigue las
mismas reglas que la primera consulta.

6
Table no lo reconoce SQL Server

AÑO 2003 Página 15 de 96


SQL Lic. Gustavo Rei

Las dos consultas deben tener el mismo número de columnas pero las columnas pueden llamarse de diferente forma y ser de ti-
pos de datos distintos.
Las columnas del resultado se llaman como las de la primera consulta.
Por defecto la unión no incluye filas repetidas, si alguna fila está en las dos tablas, sólo aparece una vez en el resultado.
Si queremos que aparezcan todas las filas incluso las repeticiones de filas, incluimos la palabra ALL (todo en inglés).
El empleo de ALL tienen una ventaja, la consulta se ejecutará más rápidamente. Puede que la diferencia no se note con tablas
pequeñas, pero si tenemos tablas con muchos registros (filas) la diferencia puede ser notable.
Se puede unir más de dos tablas, para ello después de la segunda consulta repetimos la palabra UNION... y así sucesivamente.
También podemos indicar que queremos el resultado ordenado por algún criterio, en este caso se incluye la cláusula ORDER BY
que ya vimos en el tema anterior. La cláusula ORDER BY se escribe después de la última consulta, al final de la sentencia; para indicar las
columnas de ordenación podemos utilizar su número de orden o el nombre de la columna, en este último caso se deben de utilizar los
nombres de columna de la primera consulta ya que son los que se van a utilizar para nombrar las columnas del resultado.
Para ilustrar la operación vamos a realizar el ejercicio visto en la página anterior, vamos a obtener los códigos de los productos
que tienen existencias iguales a cero o que aparezcan en pedidos del año 90.

SELECT idfab, idproducto


FROM productos
WHERE existencias = 0
UNION ALL
SELECT fab,producto
FROM pedidos
WHERE year(fechapedido) = 1990
ORDER BY idproducto

O bien

TABLE [existencias cero]


UNION ALL
TABLE [pedidos 90]
ORDER BY idproducto

Se ha incluido la cláusula ALL porque no nos importa que salgan filas repetidas.
Se ha incluido ORDER BY para que el resultado salga ordenado por idproducto, observar que hemos utilizado el nombre de la co-
lumna de la primera SELECT, también podíamos haber puesto ORDER BY 2 pero no ORDER BY producto (es el nombre de la columna de
la segunda tabla).
Para el 2º caso hemos creado una consulta llamada existencias cero con la primera SELECT, y una consulta llamada pedidos 90
con la segunda SELECT. Observar que los nombres de las consultas están entre corchetes porque contienen espacios en blanco, y que en
este caso hay que utilizar TABLE7.

EL PRODUCTO CARTESIANO

El producto cartesiano es un tipo de composición de tablas, aplicando el producto cartesiano a dos tablas se obtiene una tabla
con las columnas de la primera tabla unidas a las columnas de la segunda tabla, y las filas de la tabla resultante son todas las posibles
concatenaciones de filas de la primera tabla con filas de la segunda tabla.
La sintaxis es la siguiente:
El producto cartesiano se indica poniendo en la FROM las tablas que queremos componer separadas por comas, podemos obte-
ner así el producto cartesiano de dos, tres, o más tablas.
Nbtabla puede ser un nombre de tabla o un nombre de consulta. Si todas las tablas están en una base de datos externa, añadi-
remos la cláusula IN basedatosexterna después de la última tabla. Pero para mejorar el rendimiento y facilitar el uso, se recomienda utilizar
una tabla vinculada en lugar de la cláusula IN.

7
Table no lo reconoce SQL Server

AÑO 2003 Página 16 de 96


SQL Lic. Gustavo Rei

Hay que tener en cuenta que el producto cartesiano obtiene todas las posibles combinaciones de filas por lo tanto si tenemos dos
tablas de 100 registros cada una, el resultado tendrá 100x100 filas, si el producto lo hacemos de estas dos tablas con una tercera de 20
filas, el resultado tendrá 200.000 filas (100x100x20) y estamos hablando de tablas pequeñas. Se ve claramente que el producto cartesiano
es una operación costosa sobre todo si operamos con más de dos tablas o con tablas voluminosas.
Se puede componer una tabla consigo misma, en este caso es obligatorio utilizar un nombre de alias por lo menos para una de
las dos.
Por ejemplo: SELECT * FROM empleados, empleados emp
En este ejemplo obtenemos el producto cartesiano de la tabla de empleados con ella misma. Todas las posibles combinaciones
de empleados con empleados.
Para ver cómo funciona el producto cartesiano cogemos las consultas [existencias cero] y [pedidos 90] creadas en la página ante-
rior, y creamos una consulta que halle el producto cartesiano de las dos.

SELECT *
FROM [existencias cero], [pedidos 90]
Obtenemos la siguiente tabla

Se observa que tenemos las dos filas de la primera consulta combinadas con las dos filas de la segunda.
Esta operación no es de las más utilizadas, normalmente cuando queremos componer dos tablas es para añadir a las filas de
una tabla, una fila de la otra tabla, por ejemplo añadir a los pedidos los datos del cliente correspondiente, o los datos del representante, esto
equivaldría a un producto cartesiano con una selección de filas:
SELECT *
FROM pedidos, clientes
WHERE pedidos.clie =clientes.numclie
Combinamos todos los pedidos con todos los clientes pero luego seleccionamos los que cumplan que el código de cliente de la
tabla de pedidos sea igual al código de cliente de la tabla de clientes, por lo tanto nos quedamos con los pedidos combinados con los datos
del cliente correspondiente.
Las columnas que aparecen en la cláusula WHERE de nuestra consulta anterior se denominan columnas de emparejamiento ya
que permiten emparejar las filas de las dos tablas. Las columnas de emparejamiento no tienen por qué estar incluidas en la lista de selec-
ción.
Normalmente emparejamos tablas que están relacionadas entre sí y una de las columnas de emparejamiento es clave principal,
pues en este caso, cuando una de las columnas de emparejamiento tienen un índice definido es más eficiente utilizar otro tipo de composi-
ción, el INNER JOIN.

AÑO 2003 Página 17 de 96


SQL Lic. Gustavo Rei

El INNER JOIN
El INNER JOIN es otro tipo de composición de tablas, permite emparejar filas de distintas tablas de forma más eficiente que con
el producto cartesiano cuando una de las columnas de emparejamiento está indexada. Ya que en vez de hacer el producto cartesiano
completo y luego seleccionar la filas que cumplen la condición de emparejamiento, para cada fila de una de las tablas busca directamente
en la otra tabla las filas que cumplen la condición, con lo cual se emparejan sólo las filas que luego aparecen en el resultado.

La sintaxis es la siguiente:

Ejemplo:
SELECT *
FROM pedidos INNER JOIN clientes ON pedidos. clie = clientes.numclie

Tabla1 y tabla2 son especificaciones de tabla (nombre de tabla con alias o no, nombre de consulta guardada), de las tablas cuyos
registros se van a combinar.
Pueden ser las dos la misma tabla, en este caso es obligatorio definir al menos un alias de tabla.
col1, col2 son las columnas de emparejamiento.
Observar que dentro de la cláusula ON los nombres de columna deben ser nombres cualificados (Llevan delante el nombre de la
tabla y un punto).
Las columnas de emparejamiento deben contener la misma clase de datos, las dos de tipo texto, de tipo fecha etc. los campos
numéricos deben ser de tipos similares. Por ejemplo, se puede combinar campos Auto Numéricos y Long puesto que son tipos similares, sin
embargo, no se puede combinar campos de tipo Simple y Doble. Además las columnas no pueden ser de tipo Memo ni OLE.
Comp representa cualquier operador de comparación (=, <, >, <=, >=, o <>) y se utiliza para establecer la condición de empare-
jamiento.
Se pueden definir varias condiciones de emparejamiento unidas por los operadores AND y OR poniendo cada condición entre pa-
réntesis. Ejemplo:

SELECT *
FROM pedidos INNER JOIN productos ON (pedidos.fab = productos.idfab) AND (pedidos.producto = productos.idproducto)
Se pueden combinar más de dos tablas. En este caso hay que sustituir en la sintaxis una tabla por un INNER JOIN completo.

Por ejemplo:
SELECT *
FROM (pedidos INNER JOIN clientes ON pedidos.clie = clientes.numclie) INNER JOIN empleados ON pedidos.rep = emplea-
dos.numemp
En vez de tabla1 hemos escrito un INNER JOIN completo, también podemos escribir:

SELECT *
FROM clientes INNER JOIN (pedidos INNER JOIN empleados ON pedidos.rep = empleados.numemp) ON pedidos.clie = clien-
tes.numclie
En este caso hemos sustituido tabla2 por un INNER JOIN completo

El LEFT JOIN y RIGHT JOIN


El LEFT JOIN y RIGHT JOIN son otro tipo de composición de tablas, también denominada composición externa. Son una exten-
sión del INNER JOIN.
Las composiciones vistas hasta ahora (el producto cartesiano y el INNER JOIN) son composiciones internas ya que todos los va-
lores de las filas del resultado son valores que están en las tablas que se combinan.

AÑO 2003 Página 18 de 96


SQL Lic. Gustavo Rei

Con una composición interna sólo se obtienen las filas que tienen al menos una fila de la otra tabla que cumpla la condición, vea-
mos un ejemplo:
Queremos combinar los empleados con las oficinas para saber la ciudad de la oficina donde trabaja cada empleado, si utilizamos
un producto cartesiano tenemos:

SELECT empleados.*, ciudad


FROM empleados, oficinas
WHERE empleados.oficina = oficinas.oficina

Observar que hemos cualificado el nombre de columna oficina ya que ese nombre aparece en las dos tablas de la FROM.
Con esta sentencia los empleados que no tienen una oficina asignada (un valor nulo en el campo oficina de la tabla empleados)
no aparecen en el resultado ya que la condición empleados.oficina = oficinas.oficina será siempre nula para esos empleados.

Si utilizamos el INNER JOIN:


SELECT empleados.*, ciudad
FROM empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina

Nos pasa lo mismo, el empleado 110 tiene un valor nulo en el campo oficina y no aparecerá en el resultado.
Pues en los casos en que queremos que también aparezcan las filas que no tienen una fila coincidente en la otra tabla, utilizare-
mos el LEFT o RIGHT JOIN.
La sintaxis del LEFT JOIN es la siguiente:

La descripción de la sintaxis es la misma que la del INNER JOIN (ver anterior), lo único que cambia es la palabra INNER por
LEFT (izquierda en inglés).
Esta operación consiste en añadir al resultado del INNER JOIN las filas de la tabla de la izquierda que no tienen correspondencia
en la otra tabla, y rellenar en esas filas los campos de la tabla de la derecha con valores nulos.
Ejemplo:
SELECT *
FROM empleados LEFT JOIN oficinas ON empleados.oficina = oficinas.oficina

Con el ejemplo anterior obtenemos una lista de los empleados con los datos de su oficina, y el empleado 110 que no tiene oficina
aparece con sus datos normales y los datos de su oficina a nulos.
La sintaxis del Right JOIN es la siguiente:

La sintaxis es la misma que la del INNER JOIN (ver anterior), lo único que cambia es la palabra INNER por RIGHT (derecha en
inglés).

Esta operación consiste en añadir al resultado del INNER JOIN las filas de la tabla de la derecha que no tienen correspondencia
en la otra tabla, y rellenar en esas filas los campos de la tabla de la izquierda con valores nulos.
Ejemplo:
SELECT *
FROM empleados RIGHT JOIN oficinas ON empleados.oficina = oficinas.oficina
Con el ejemplo anterior obtenemos una lista de los empleados con los datos de su oficina, y además aparece una fila por cada
oficina que no está asignada a ningún empleado con los datos del empleado a nulos.
Una operación LEFT JOIN o RIGHT JOIN se puede anidar dentro de una operación INNER JOIN, pero una operación INNER
JOIN no se puede anidar dentro de LEFT JOIN o RIGHT JOIN. Los anidamientos de JOIN de distinta naturaleza no funcionan siempre, a
veces depende del orden en que colocamos las tablas, en estos casos lo mejor es probar y si no permite el anudamiento, cambiar el orden
de las tablas (y por tanto de los JOINs) dentro de la cláusula FROM.
Por ejemplo podemos tener:
SELECT *
FROM clientes INNER JOIN (empleados LEFT JOIN oficinas ON empleados.oficina = oficinas.oficina) ON clientes.repclie = em-
pleados.numclie

AÑO 2003 Página 19 de 96


SQL Lic. Gustavo Rei

Combinamos empleados con oficinas para obtener los datos de la oficina de cada empleado, y luego añadimos los clientes de ca-
da representante, así obtenemos los clientes que tienen un representante asignado y los datos de la oficina del representante asignado.

Si hubiéramos puesto INNER en vez de LEFT no saldrían los clientes que tienen el empleado 110 (porque no tiene oficina y por
tanto no aparece en el resultado del LEFT JOIN y por tanto no entrará en el cálculo del INNER JOIN con clientes).
Para saber en cada caso qué tipo de operación se debe utilizar, a continuación tienes un gráfico que indica qué preguntas se tie-
nen que hacer y según la respuesta, qué operación utilizar.
Para resumir hemos llamado T1 y T2 las tablas de las que queremos sacar los datos y R la tabla lógica que representa el resulta-
do de consulta. T1 y T2 podrían ser tablas guardadas o consultas.
En la última parte cuando se pregunta "En T1 hay filas que no tienen pareja en T2", la pregunta se debe de interpretar como "en
alguna de las tablas hay filas que no tienen pareja".

Explicación de SQL Server ®

COLUMNAS DE COMBINACIÓN
El operador JOIN hace coincidir filas mediante la comparación de valores de una tabla con valores de otra tabla. El usuario decide
las columnas de cada tabla que deben hacerse coincidir. Hay varias opciones:

COLUMNAS RELACIONADAS
Normalmente, se combinan tablas haciendo coincidir valores en columnas para las que existe una relación de clave externa. Por
ejemplo, puede combinar descuentos (discounts) y almacenes (stores) haciendo coincidir los valores de id_alma (stor_id) en las tablas
respectivas. El código SQL resultante sería parecido a este:

SELECT *
FROM discounts INNER JOIN stores ON stores.stor_id = discounts.stor_id

AÑO 2003 Página 20 de 96


SQL Lic. Gustavo Rei

COLUMNAS NO RELACIONADAS
También puede combinar tablas haciendo coincidir valores en columnas para las que no existe una relación de clave externa. Por
ejemplo, puede combinar editores y autores haciendo coincidir los valores de estado (state) en las tablas respectivas. Una combinación de
este tipo proporciona un conjunto de resultados en el que cada fila describe un par autor-editor ubicado en el mismo estado.

SELECT au_lname, au_fname, pub_name, authors.state


FROM authors INNER JOIN publishers ON authors.state = publishers.state

También conviene observar que puede utilizar varias columnas para hacer coincidir filas de las tablas combinadas. Por ejemplo,
para buscar los pares autor-editor en los que el autor y el editor están ubicados en la misma ciudad, puede utilizar una operación de combi-
nación que haga coincidir las columnas respectivas de estado y las columnas respectivas de ciudad de las dos tablas. Es necesario hacer
coincidir tanto la ciudad como el estado porque puede que estados diferentes tengan ciudades con el mismo nombre (por ejemplo, Spring-
field en Illinois y Springfield en Massachusetts).

TIPOS DE COMBINACIONES
Cuando se combinan tablas, el tipo de combinación que se crea determina las filas que aparecen en el conjunto de resultados.
Puede crear los siguientes tipos de combinaciones:
COMBINACIÓN INTERNA
Combinación que sólo muestra las filas que tienen un elemento coincidente en las dos tablas combinadas. Éste es el tipo de com-
binación predeterminado en el Diseñador de consultas. Por ejemplo, puede combinar las tablas titles y publishers para crear un conjunto de
resultados que muestre el nombre del editor para cada título. En una combinación interna, los títulos para los que no existe información del
editor no se incluyen en el conjunto de resultados, ni tampoco los editores sin títulos. La instrucción SQL resultante para una combinación
de este tipo sería parecida a esta8:

SELECT title, pub_name


FROM titles INNER JOIN
publishers ON titles.pub_id = publishers.pub_id

Para obtener más información sobre cómo crear una combinación interna, consulte Combinar tablas automáticamente.

COMBINACIÓN EXTERNA
Combinación que incluye filas aunque éstas no tengan filas relacionadas en la tabla combinada. Puede crear tres variaciones de
una combinación externa para especificar las filas no coincidentes que desea incluir:

Combinación externa izquierda


Se incluyen todas las filas de la tabla nombrada en primer lugar (la tabla "izquierda", que aparece totalmente a la izquierda en la
cláusula JOIN). Las filas que no coinciden de la tabla derecha no aparecen. Por ejemplo, la siguiente instrucción SQL ilustra una combina-
ción exterior izquierda entre las tablas titles y publishers para incluir todos los títulos, incluso los que no tienen información de editor:
SELECT titles.title_id, titles.title, publishers.pub_name
FROM titles LEFT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id

Combinación externa derecha


Se incluyen todas las filas de la tabla nombrada en segundo lugar (la tabla "derecha", que aparece totalmente a la derecha en la
cláusula JOIN). No se incluyen las filas que no coinciden de la tabla de la izquierda. Por ejemplo, una combinación externa derecha entre
las tablas titles y publishers incluirán todos los editores, incluso los que no tengan títulos en la tabla titles. El código SQL resultante sería
parecido a este:

SELECT titles.title_id, titles.title, publishers.pub_name


FROM titles RIGHT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id

8
Las columnas que contienen NULL no coinciden con ningún valor cuando se crea una combinación interna y, por tanto, se excluyen del conjunto de resultados. Los valores

nulos no coinciden con otros valores nulos.

AÑO 2003 Página 21 de 96


SQL Lic. Gustavo Rei

Combinación externa completa


Se incluyen todas las filas de todas las tablas combinadas, tanto si tienen elementos coincidentes como si no. Por ejemplo, una
combinación externa completa entre titles y publishers muestra todos los títulos y todos los editores, incluso los que no coincidan en la otra
tabla.
SELECT titles.title_id, titles.title, publishers.pub_name
FROM titles FULL OUTER JOIN publishers ON titles.pub_id = publishers.pub_id

Combinación cruzada
Combinación cuyo conjunto de resultados incluye una fila para cada posible emparejamiento de filas de las dos tablas. Por ejem-
plo, la sentencia CROSS JOIN aplicada a autores y editores proporciona un conjunto de resultados con una fila para cada posible combina-
ción de autores y editores. El código SQL resultante sería parecido a este:
SELECT *
FROM authors CROSS JOIN publishers

OPERADORES DE COMPARACIÓN JOIN

El operador JOIN hace coincidir filas mediante la comparación de valores de una tabla con valores de otra tabla. Puede decidir
exactamente qué elemento constituye una coincidencia. Las posibles opciones se engloban en dos amplias categorías:

Coincidencia en igualdad
Normalmente, se hacen coincidir filas cuando los valores de las respectivas columnas son iguales. Por ejemplo, para crear un
conjunto de resultados en el que cada fila contenga una descripción completa de cada editor, (es decir, con columnas de la tabla publishers
y de la tabla pub_info), utilice una combinación que haga coincidir filas en las que los valores de pub_id de las tablas respectivas sean
iguales. El código SQL resultante sería parecido a este:
SELECT *
FROM publishers INNER JOIN pub_info ON publishers.pub_id = pub_info.pub_id

Otros
Puede hacer coincidir filas utilizando una condición distinta de la de igualdad. Por ejemplo, para buscar los empleados y los pues-
tos de trabajo para los que no tienen la calificación apropiada, puede combinar empleados con puestos, haciendo coincidir filas en las que el
nivel mínimo requerido del puesto de trabajo supere el nivel del puesto de trabajo del empleado. El código SQL resultante sería parecido a
este:
SELECT fname, minit, lname, job_desc, job_lvl, min_lvl
FROM employee INNER JOIN jobs ON employee.job_lvl < jobs.min_lvl

COMBINAR TRES O MÁS TABLAS


Cada operación JOIN combina dos tablas. Sin embargo, puede utilizar varias operaciones JOIN en una consulta para reunir datos
de cualquier número de tablas. Dado que el resultado de cada operación JOIN es efectivamente una tabla, puede utilizar ese resultado
como un operando en una operación JOIN posterior. Por ejemplo, para crear un conjunto de resultados en el que cada fila contenga un
título de libro, un autor y el porcentaje de derechos que recibe el autor por dicho libro, debe combinar datos de las tres tablas: authors
(autores), titles (títulos) y titleauthor (títuloautor). El código SQL resultante sería parecido a este:
SELECT title, au_fname, au_lname, royaltyper
FROM authors INNER JOIN titleauthor
ON authors.au_id = titleauthor.au_id INNER JOIN titles
ON titleauthor.title_id = titles.title_id

UTILIZAR UNA TABLA SÓLO PARA COMBINAR OTRAS TABLAS


Puede incluir una tabla en una combinación aunque no desee incluir ninguna de las columnas de dicha tabla en un conjunto de
resultados. Por ejemplo, para establecer un conjunto de resultados en el que cada fila describa un par título-almacén en el que dicho alma-
cén venda ese título, puede incluir columnas de dos tablas: titles (títulos) y stores (almacenes). Pero, para determinar los almacenes y los
títulos que estos han vendido, debe utilizar una tercera tabla, sales (ventas). El código SQL resultante sería parecido a este:

SELECT title, stor_name


FROM titles INNER JOIN sales
AÑO 2003 Página 22 de 96
SQL Lic. Gustavo Rei

ON titles.title_id = sales.title_id INNER JOIN stores


ON sales.stor_id = stores.stor_id
Conviene observar que la tabla sales (ventas) no contribuye con columnas al conjunto de resultados.

UTILIZAR UNA TABLA DOS VECES EN UNA CONSULTA


Puede utilizar la misma tabla dos o más veces en una única consulta.

UTILIZAR OTRO ELEMENTO EN LUGAR DE UNA TABLA


En lugar de una tabla, puede utilizar una consulta, una vista o una función definida por el usuario que devuelva una tabla.

AÑO 2003 Página 23 de 96


SQL Lic. Gustavo Rei

Introducción
En SQL la mayoría de los motores de bases de datos relacionales, pueden definir un tipo de consultas cuyas filas resultantes son
un resumen de las filas de la tabla origen, por eso las denominamos consultas de resumen, también se conocen como consultas sumarias.
Es importante entender que las filas del resultado de una consulta de resumen tienen una naturaleza distinta a las filas de las de-
más tablas resultantes de consultas, ya que corresponden a varias filas de la tabla origen. Para simplificar, veamos el caso de una consulta
basada en una sola tabla, una fila de una consulta 'no resumen' corresponde a una fila de la tabla origen, contiene datos que se encuentran
en una sola fila del origen, mientras que una fila de una consulta de resumen corresponde a un resumen de varias filas de la tabla origen,
esta diferencia es lo que va a originar una serie de restricciones que sufren las consultas de resumen y que veremos a lo largo del tema.
En el ejemplo que viene a continuación tienes un ejemplo de consulta normal en la que se visualizan las filas de la tabla oficinas
ordenadas por región, en este caso cada fila del resultado se corresponde con una sola fila de la tabla oficinas, mientras que la segunda
consulta es una consulta resumen, cada fila del resultado se corresponde con una o varias filas de la tabla oficinas.

Las consultas de resumen introducen dos nuevas cláusulas a la sentencia SELECT, la cláusula GROUP BY y la cláusula
HAVING, son cláusulas que sólo se pueden utilizar en una consulta de resumen, se tienen que escribir entre la cláusula WHERE y la cláu-
sula ORDER BY y tienen la siguiente sintaxis:

Las detallaremos en la página siguiente del tema, primero vamos a introducir otro concepto relacionado con las consultas de re-
sumen, las funciones de columna.

Funciones de columna
En la lista de selección de una consulta de resumen aparecen funciones de columna también denominadas funciones de dominio
agregadas. Una función de columna se aplica a una columna y obtiene un valor que resume el contenido de la columna.
Tenemos las siguientes funciones de columna:
AÑO 2003 Página 24 de 96
SQL Lic. Gustavo Rei

El argumento de la función indica con qué valores se tiene que operar, por eso expresión suele ser un nombre de columna, co-
lumna que contiene los valores a resumir, pero también puede ser cualquier expresión válida que devuelva una lista de valores.
La función SUM() calcula la suma de los valores indicados en el argumento. Los datos que se suman deben ser de tipo numérico
(entero, decimal, coma flotante o monetario...). El resultado será del mismo tipo aunque puede tener una precisión mayor

SELECT SUM(ventas) Obtiene una sola fila con el resultado de sumar todos los valores de la co-
FROM oficinas lumna ventas de la tabla oficinas

La función AVG() calcula el promedio (la media arimética) de los valores indicados en el argumento, también se aplica a datos
numéricos, y en este caso el tipo de dato del resultado puede cambiar según las necesidades del sistema para representar el valor del
resultado.
StDev() y StDevP() calculan la desviación estándar de una población o de una muestra de la población representada por los valo-
res contenidos en la columna indicada en el argumento. Si la consulta base (el origen) tiene menos de dos registros, el resultado es nulo.
Es interesante destacar que el valor nulo no equivale al valor 0, las funciones de columna no consideran los valores nulos mien-
tras que consideran el valor 0 como un valor, por lo tanto en las funciones AVG(), STDEV(), STDEVP() los resultados no serán los mismos
con valores 0 que con valores nulos. Veámoslo con un ejemplo:
Si tenemos esta tabla: La consulta En este caso los ceros entran en la
media por lo que sale igual a 4
SELECT AVG(col1) AS media devuelve: (10+5+0+3+6+0)/6 = 4
FROM tabla1

Con esta otra tabla: SELECT AVG(col1) AS media En este caso los ceros se han sustituido
FROM tabla2 por valores nulos y no entran en el cálcu-
devuelve: lo por lo que la media sale igual a 6
(10+5+3+6)/4 = 4

Las funciones MIN() y MAX() determinan los valores menores y mayores respectivamente. Los valores de la columna pueden ser
de tipo numérico, texto o fecha. El resultado de la función tendrá el mismo tipo de dato que la columna. Si la columna es de tipo numérico
MIN() devuelve el valor menor contenido en la columna, si la columna es de tipo texto MIN() devuelve el primer valor en orden alfabético, y
si la columna es de tipo fecha, MIN() devuelve la fecha más antigua y MAX() la fecha más reciente.
La función COUNT(nb columna) cuenta el número de valores que hay en la columna, los datos de la columna pueden ser de
cualquier tipo, y la función siempre devuelve un número entero. Si la columna contiene valores nulos esos valores no se cuentan, si en la
columna aparece un valor repetido, lo cuenta varias veces.
COUNT(*) permite contar filas en vez de valores. Si la columna no contiene ningún valor nulo, COUNT(nbcolumna) y COUNT(*)
devuelven el mismo resultado, mientras que si hay valores nulos en la columna, COUNT(*) cuenta también esos valores mientras que
COUNT(nb columna) no los cuenta.
Ejemplo:
¿Cuántos empleados tenemos?
AÑO 2003 Página 25 de 96
SQL Lic. Gustavo Rei

SELECT COUNT(numemp)
FROM empleados

o bien

SELECT COUNT(*)
FROM empleados

En este caso las dos sentencias devuelen el mismo resultado ya que la columna numemp no contiene valores nulos (es la clave
principal de la tabla empleados).

¿Cuántos empleados tienen una oficina asignada?

SELECT COUNT(oficina)
FROM empleados

Esta sentencia por el contrario, nos devuelve el número de valores no nulos que se encuentran en la columna oficina de la tabla
empleados, por lo tanto nos dice cuántos empleados tienen una oficina asignada.
Se pueden combinar varias funciones de columna en una expresión pero no se pueden anidar funciones de columna, es decir:

SELECT (AVG(ventas) * 3) + SUM(cuota)


FROM ...
es correcto

SELECT AVG(SUM(ventas))
FROM ...
NO es correcto, no se puede incluir una función de columna dentro de una función de columna

SELECCIÓN EN EL ORIGEN DE DATOS.

Si queremos eliminar del origen de datos algunas filas, basta incluir la cláusula WHERE que ya conocemos después de la cláusu-
la FROM.
Ejemplo: Queremos saber el acumulado de ventas de los empleados de la oficina 12.
SELECT SUM(ventas)
FROM empleados
WHERE oficina = 12

ORIGEN MÚLTIPLE.

Si los datos que necesitamos utilizar para obtener nuestro resumen se encuentran en varias tablas, formamos el origen de datos
adecuado en la cláusula FROM como si fuera una consulta multitabla normal.

Ejemplo: Queremos obtener el importe total de ventas de todos los empleados y el mayor objetivo de las oficinas asignadas a los
empleados:
SELECT SUM(empleados.ventas), MAX(objetivo)
FROM empleados LEFT JOIN oficinas ON empleados.oficina=oficinas.oficina

NOTA: combinamos empleados con oficinas por un LEFT JOIN para que aparezcan en el origen de datos todos los empleados
incluso los que no tengan una oficina asignada, así el origen de datos estará formado por una tabla con tantas filas como empleados hayan
en la tabla empleados, con los datos de cada empleado y de la oficina a la que está asignado. De esta tabla sacamos la suma del campo
ventas (importe total de ventas de todos los empleados) y el objetivo máximo. Observar que el origen de datos no incluye las oficinas que
no tienen empleados asignados, por lo que esas oficinas no entran a la hora de calcular el valor máximo del objetivo.

AÑO 2003 Página 26 de 96


SQL Lic. Gustavo Rei

La cláusula GROUP BY

Hasta ahora las consultas de resumen que hemos visto utilizan todas las filas de la tabla y producen una única fila resultado.

Se pueden obtener subtotales con la cláusula GROUP BY. Una consulta con una cláusula GROUP BY se denomina consulta
agrupada ya que agrupa los datos de la tabla origen y produce una única fila resumen por cada grupo formado. Las columnas indicadas en
el GROUP BY se llaman columnas de agrupación.

Ejemplo:

Obtiene la suma de las ventas de todos los empleados


SELECT SUM(ventas)
FROM repventas

Se forma un grupo para cada oficina, con las filas de la oficina, y la suma se calcula sobre las filas de cada grupo. El ejemplo an-
terior obtiene una lista con la suma de las ventas de los empleados de cada oficina.

SELECT SUM(ventas)
FROM repventas
GROUP BY oficina

La consulta quedaría mejor incluyendo en la lista de selección la oficina para saber a qué oficina corresponde la suma de ventas:

SELECT oficina,SUM(ventas)
FROM repventas
GROUP BY oficina

Un columna de agrupación no puede ser de tipo memo u OLE.


La columna de agrupación se puede indicar mediante un nombre de columna o cualquier expresión válida basada en una colum-
na pero no se pueden utilizar los alias de campo.
Ejemplo:

SELECT importe/cant , SUM(importe)


FROM pedidos
GROUP BY importe/cant

Está permitido, equivaldría a agrupar las líneas de pedido por precio unitario y sacar de cada precio unitario el importe total vendi-
do

SELECT importe/cant AS precio, SUM(importe)


FROM pedidos
GROUP BY precio

No está permitido, no se puede utilizar un alias campo

En la lista de selección sólo pueden aparecer :


valores constantes
funciones de columna
columnas de agrupación (columnas que aparecen en la cláusula GROUP BY)
cualquier expresión basada en las anteriores.

SELECT SUM(importe),rep*10

AÑO 2003 Página 27 de 96


SQL Lic. Gustavo Rei

FROM pedidos
GROUP BY rep*10
Está permitido

SELECT SUM(importe),rep
FROM pedidos
GROUP BY rep*10
No está permitido, rep es una columna simple que no está encerrrada en una función de columna, ni está en la lista de columnas
de agrupación.

Se pueden agrupar las filas por varias columnas, en este caso se indican las columnas separadas por una coma y en el orden de
mayor a menor agrupación. Se permite incluir en la lista de agrupación hasta 10 columnas.

Ejemplo: Queremos obtener la suma de las ventas de las oficinas agrupadas por region y ciudad:

SELECT SUM(ventas)
FROM oficinas
GROUP BY region,ciudad

Se agrupa primero por región, y dentro de cada región por ciudad.

Todas las filas que tienen valor nulo en el campo de agrupación, pasan a formar un único grupo. Es decir, considera el valor nulo
como un valor cualquiera a efectos de agrupación.

Ejemplo:

SELECT oficina,SUM(ventas) AS ventas_totales


FROM repventas
GROUP BY oficina

En el resultado aparece una fila con el campo oficina sin valor y a continuación una cantidad en el campo ventas_totales, esta
cantidad corresponde a la suma de las ventas de los empleados que no tienen oficina asignada (campo oficina igual a nulo).

La cláusula HAVING
La cláusula HAVING nos permite seleccionar filas de la tabla resultante de una consulta de resumen.
Para la condición de selección se pueden utilizar los mismos tests de comparación descritos en la cláusula WHERE, también se
pueden escribir condiciones compuestas (unidas por los operadores OR, AND, NOT), pero existe una restricción.
En la condición de selección sólo pueden aparecer :
valores constantes
funciones de columna
columnas de agrupación (columnas que aparecen en la cláusula GROUP BY)
cualquier expresión basada en las anteriores.
Ejemplo: Queremos saber las oficinas con un promedio de ventas de sus empleados mayor que 500.000 $

SELECT oficina
FROM empleados
GROUP BY oficina
HAVING AVG(ventas) > 500000

NOTA: Para obtener lo que se pide hay que calcular el promedio de ventas de los empleados de cada oficina, por lo que hay que
utilizar la tabla empleados.Tenemos que agrupar los empleados por oficina y calcular el promedio para cada oficina, por último nos queda
seleccionar del resultado las filas que tengan un promedio superior a 500.000 $.

Resumen del tema

AÑO 2003 Página 28 de 96


SQL Lic. Gustavo Rei

¿Cómo se ejecuta internamente una consulta de resumen?


Primero se forma la tabla origen de datos según la cláusula FROM,
se seleccionan del origen de datos las filas según la cláusula WHERE,
se forman los grupos de filas según la cláusula GROUP BY,
por cada grupo se obtiene una fila en la tabla resultante con los valores que aparecen en las cláusulas GROUP BY, HAVING y en
la lista de selección,
se seleccionan de la tabla resultante las filas según la cláusula HAVING,
se eliminan de la tabla resultante las columnas que no aparecen en la lista de selección,
se ordenan las filas de la tabla resultante según la cláusula ORDER BY
Una consulta se convierte en consulta de resumen en cuanto aparece GROUP BY, HAVING o una función de columna.
En una consulta de resumen, la lista de selección y la cláusula HAVING sólo pueden contener:
valores constantes
funciones de columna
columnas de agrupación (columnas que aparecen en la cláusula GROUP BY)
cualquier expresión basada en las anteriores.

AÑO 2003 Página 29 de 96


SQL Lic. Gustavo Rei

Definiciones
Una subconsulta es una sentencia SELECT que aparece dentro de otra sentencia SELECT que llamaremos consulta principal.
Se puede encontrar en la lista de selección, en la cláusula WHERE o en la cláusula HAVING de la consulta principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que aparece encerrada entre parén-
tesis, no puede contener la cláusula ORDER BY, ni puede ser la UNION de varias sentencias SELECT, además tiene algunas restricciones
en cuanto a número de columnas según el lugar donde aparece en la consulta principal. Estas restricciones las ire-mos describiendo en
cada caso.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta por cada fila de la consulta prin-cipal.
Se aconseja no utilizar campos calculados en las subconsultas, ralentizan la consulta.
Las consultas que utilizan subconsultas suelen ser más fáciles de interpretar por el usuario.

Referencias externas
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de una columna en la fila actual de la
consulta principal, ese nombre de columna se denomina referencia externa.
Una referencia externa es un nombre de columna que estando en la subconsulta, no se refiere a ninguna columna de las ta-blas
designadas en la FROM de la subconsulta sino a una columna de las tablas designadas en la FROM de la consulta prin-cipal. Como la
subconsulta se ejecuta por cada fila de la consulta principal, el valor de la referencia externa irá cambiando.

Ejemplo:

SELECT numemp, nombre, (SELECT MIN(fechapedido) FROM pedidos WHERE rep = numemp)
FROM empleados;

En este ejemplo la consulta principal es SELECT... FROM empleados.

La subconsulta es ( SELECT MIN(fechapedido) FROM pedidos WHERE rep = numemp ).


En esta subconsulta tenemos una referencia externa ( numemp ) es un campo de la tabla empleados (origen de la consulta prin-
cipal).

¿QUÉ PASA CUANDO SE EJECUTA LA CONSULTA PRINCIPAL?


se elije el primer empleado y se calcula la subconsulta sustituyendo numemp por el valor que tiene en el primer em-pleado. La
subconsulta obtiene la fecha más antigua en los pedidos del rep = 101
se elije el segundo empleado y se calcula la subconsulta con numemp = 102 (numemp del segundo empleado)... y así sucesiva-
mente hasta llegar al último empleado.
Al final obtenemos una lista con el número, nombre y fecha del primer pedido de cada empleado.

Si quitamos la cláusula WHERE de la subconsulta obtenemos la fecha del primer pedido de todos los pedidos no del empleado
correspondiente.

Anidar subconsultas
Las subconsultas pueden anidarse de forma que una subconsulta aparezca en la cláusula WHERE (por ejemplo) de otra subcon-
sulta que a su vez forma parte de otra consulta principal. En la práctica, una consulta consume mucho más tiempo y me-moria cuando se
incrementa el número de niveles de anidamiento. La consulta resulta también más difícil de leer , comprender y mantener cuando contiene
más de uno o dos niveles de subconsultas.

Ejemplo:
SELECT numemp, nombre
FROM empleados
WHERE numemp = (SELECT rep FROM pedidos WHERE clie = (SELECT numclie FROM clientes WHERE nombre = 'Julia Ante-
quera'))

AÑO 2003 Página 30 de 96


SQL Lic. Gustavo Rei

En este ejemplo, por cada linea de pedido se calcula la subconsulta de clientes, y esto se repite por cada empleado, en el caso de
tener 10 filas de empleados y 200 filas de pedidos (tablas realmente pequeñas), la subconsulta más interna se ejecutaría 2000 veces (10 x
200).

Subconsulta en la lista de selección


Cuando la subconsulta aparece en la lista de selección de la consulta principal, en este caso la subconsulta, no puede devol-ver
varias filas ni varias columnas, de lo contrario se da un mensaje de error.
Muchos SQLs no permiten que una subconsulta aparezca en la lista de selección de la consulta principal pero eso no es ningún
problema ya que normalmente se puede obtener lo mismo utilizando como origen de datos las dos tablas. El ejemplo anterior se puede
obtener de la siguiente forma:
SELECT numemp, nombre, MIN(fechapedido)
FROM empleados LEFT JOIN pedidos ON empleados.numemp = pedidos.rep
GROUP BY numemp, nombre

En la cláusula FROM
En la cláusula FROM se puede encontrar una sentencia SELECT encerrada entre paréntesis pero más que subconsulta sería una
consulta ya que no se ejecuta para cada fila de la tabla origen sino que se ejecuta una sola vez al principio, su resultado se combina con las
filas de la otra tabla para formar las filas origen de la SELECT primera y no admite referencias externas.
En la cláusula FROM vimos que se podía poner un nombre de tabla o un nombre de consulta, pues en vez de poner un nombre
de consulta se puede poner directamente la sentencia SELECT correspondiente a esa consulta encerrada entre paréntesis.

Subconsulta en las cláusulas WHERE y HAVING


Se suele utilizar subconsultas en las cláusulas WHERE o HAVING cuando los datos que queremos visualizar están en una tabla
pero para seleccionar las filas de esa tabla necesitamos un dato que está en otra tabla.

Ejemplo:

SELECT numemp, nombre


FROM empleados
WHERE contrato = (SELECT MIN(fechapedido) FROM pedidos)
En este ejemplo listamos el número y nombre de los empleados cuya fecha de contrato sea igual a la primera fecha de todos los
pedidos de la empresa.
En una cláusula WHERE / HAVING tenemos siempre una condición y la subconsulta actúa de operando dentro de esa condi-ción.
En el ejemplo anterior se compara contrato con el resultado de la subconsulta. Hasta ahora las condiciones estudiadas tenían co-
mo operandos valores simples (el valor contenido en una columna de una fila de la tabla, el resultado de una operación aritméti-ca...) ahora
la subconsulta puede devolver una columna entera por lo que es necesario definir otro tipo de condiciones especia-les para cuando se
utilizan con subconsultas.

Condiciones de selección con subconsultas


Las condiciones de selección son las condiciones que pueden aparecer en la cláusula WHERE o HAVING. La mayoría se han vis-
to en el tema 2 pero ahora incluiremos las condiciones que utilizan una subconsulta como operando.
En SQL tenemos cuatro nuevas condiciones:

el test de comparación con subconsulta


el test de comparación cuantificada
el test de pertenencia a un conjunto
el test de existencia

AÑO 2003 Página 31 de 96


SQL Lic. Gustavo Rei

En todos los tests estudiados a continuación expresion puede ser cualquier nombre de columna de la consulta principal o una ex-
presión válida como ya vimos .

EL TEST DE COMPARACIÓN CON SUBCONSULTA.


Es el equivalente al test de comparación simple. Se utiliza para comparar un valor de la fila que se está examinado con un único
valor producido por la subconsulta. La subconsulta debe devolver una única columna, sino se produce un error.
Si la subconsulta no produce ninguna fila o devuelve el valor nulo, el test devuelve el valor nulo, si la subconsulta produce va-rias
filas, SQL devuelve una condición de error.

LA SINTAXIS ES LA SIGUIENTE:

Lista las oficinas cuyo objetivo sea superior a la suma de las ventas de sus empleados.
En este caso la subconsulta devuelve una única columna y una única fila (es un consulta de resumen sin GROUP BY)

SELECT oficina, ciudad


FROM oficinas
WHERE objetivo > (SELECT SUM(ventas) FROM empleados WHERE empleados.oficina = ofici-nas.oficina)

EL TEST DE COMPARACIÓN CUANTIFICADA.


Este test es una extensión del test de comparación y del test de conjunto. Compara el valor de la expresión con cada uno de los
valores producidos por la subconsulta. La subconsulta debe devolver una única columna sino se produce un error.
Tenemos el test ANY (algún, alguno en inglés) y el test ALL (todos en inglés).

La sintaxis es la siguiente:

El test ANY.
La subconsulta debe devolver una única columna sino se produce un error.
Se evalúa la comparación con cada valor devuelto por la subconsulta.
Si alguna de las comparaciones individuales produce el resultado verdadero, el test ANY devuelve el resultado verdadero.
Si la subconsulta no devuelve ningún valor, el test ANY devuelve falso.
Si el test de comparación es falso para todos los valores de la columna, ANY devuelve falso.
Si el test de comparación no es verdadero para ningún valor de la columna, y es nulo para al menos alguno de los valores, ANY
devuelve nulo.
SELECT oficina, ciudad
FROM oficinas
WHERE objetivo > ANY (SELECT SUM(cuota) FROM empleados GROUP BY oficina)

En este caso la subconsulta devuelve una única columna con las sumas de las cuotas de los empleados de cada oficina.
Lista las oficinas cuyo objetivo sea superior a alguna de las sumas ob-tenidas.
El test ALL.
La subconsulta debe devolver una única columna sino se produce un error.
Se evalúa la comparación con cada valor devuelto por la subconsulta.

AÑO 2003 Página 32 de 96


SQL Lic. Gustavo Rei

Si todas las comparaciones individuales, producen un resultado verdadero, el test devuelve el valor verdadero.
Si la subconsulta no devuelve ningún valor el test ALL devuelve el valor verdadero. (¡Ojo con esto!)
Si el test de comparación es falso para algún valor de la columna, el resultado es falso.
Si el test de comparación no es falso para ningún valor de la columna, pero es nulo para alguno de esos valores, el test ALL de-
vuelve valor nulo.
SELECT oficina, ciudad
FROM oficinas
WHERE objetivo > ALL (SELECT SUM(cuota) FROM empleados GROUP BY oficina)
En este caso se listan las oficinas cuyo objetivo sea superior a todas las sumas.
Test de pertenencia a conjunto (IN).
Examina si el valor de la expresión es uno de los valores incluidos en la lista de valores producida por la subconsulta.
La subconsulta debe generar una única columna y las filas que sean.
Si la subconsulta no produce ninguna fila, el test da falso.
Tiene la siguiente sintaxis

SELECT numemp, nombre, oficina


FROM empleados
WHERE oficina IN (SELECT oficina FROM oficinas WHERE region = 'este')
Con la subconsulta se obtiene la lista de los números de oficina del es-te y la consulta principal obtiene los empleados cuyo nú-
mero de oficina sea uno de los números de oficina del este.
Por lo tanto lista los empleados de las oficinas del este.
El test de existencia EXISTS.
Examina si la subconsulta produce alguna fila de resultados.
Si la subconsulta contiene filas, el test adopta el valor verdadero, si la subconsulta no contiene ninguna fila, el test toma el va-lor
falso, nunca puede tomar el valor nulo.
Con este test la subconsulta puede tener varias columnas, no importa ya que el test se fija no en los valores devueltos sino en si
hay o no fila en la tabla resultado de la subconsulta.
Cuando se utiliza el test de existencia en la mayoría de los casos habrá que utilizar una referencia externa. Si no se utiliza una re-
ferencia externa la subconsulta devuelta siempre será la misma para todas las filas de la consulta principal y en este caso se se-leccionan
todas las filas de la consulta principal (si la subconsulta genera filas) o ninguna (si la subconsulta no devuelve ninguna fila)
La sintaxis es la siguiente:

SELECT numemp, nombre, oficina


FROM empleados
WHERE EXISTS (SELECT * FROM oficinas WHE-RE region = 'este' AND empleados.oficina = ofici-nas.oficina)
Este ejemplo obtiene lo mismo que el ejemplo del test IN.

Observa que delante de EXISTS no va ningún nombre de columna.


En la subconsulta se pueden poner las columnas que queramos en la lista de selección (hemos utilizado el *).
Hemos añadido una condición adicional al WHERE, la de la referencia externa para que la oficina que se compare sea la oficina
del empleado
NOTA. Cuando se trabaja con tablas muy voluminosas el test EXISTS suele dar mejor rendimiento que el test IN

RESUMEN DEL TEMA


Una subconsulta es una sentencia SELECT que aparece en la lista de selección, o en las cláusulas WHERE o HAVING de otra
sentencia SELECT.
La subconsulta se ejecuta por cada fila de la consulta principal.
Dentro de una consulta se puede utilizar una columna del origen de la consulta principal, una referencia externa.
Aunque se puedan anidar subconsultas no es aconsejado más de un nivel de anidamiento.
La subconsulta sufre una serie de restricciones según el lugar donde se encuentre.
Las condiciones asociadas a las subconsultas son las siguientes:
AÑO 2003 Página 33 de 96
SQL Lic. Gustavo Rei

el test de comparación con subconsulta


el test ANY
el test ALL
el test IN
el test EXISTS

AÑO 2003 Página 34 de 96


SQL Lic. Gustavo Rei

Introducción
Hasta ahora hemos estudiado cómo recuperar datos almacenados en las tablas de nuestra base de datos. En este tema vamos a
tratar el de la actualización de esos datos, es decir insertar nuevas filas, borrar filas o cambiar el contenido de las filas de una tabla. Estas
operaciones modifican los datos almacenados en las tablas pero no su estructura, ni su definición.

Para Access
INSERTAR UNA FILA INSERT INTO...VALUES
La inserción de nuevos datos en una tabla se realiza añadiendo filas enteras a la tabla, la sentencia SQL que lo permite es la or-
den INSERT INTO.
La inserción se puede realizar de una fila o de varias filas de golpe, veremos las dos opciones por separado y empezaremos por
la inserción de una fila.
La sintaxis es la siguiente:

Esta sintaxis se utiliza para insertar una sola fila cuyos valores indicamos después de la palabra reservada VALUES. En castella-
no la sentencia se leería: INSERTA EN destino...VALORES ....
Los registros se agregan siempre al final de la tabla.
Destino es el nombre de la tabla donde vamos a insertar la fila también se puede utilizar un nombre de consulta, consulta que
tenga como origen de datos una única tabla. Al nombre de la tabla se le puede añadir la cláusula IN si la tabla se encuentra en otra base de
datos (en una base de datos externa).
La palabra reservada VALUES se puede sustituir por la palabra SELECT ( en otros SQLs se emplea únicamente VALUES).
A continuación de la palabra VALUES, entre paréntesis se escriben los valores que queremos añadir. Estos valores se tienen que
escribir de acuerdo al tipo de dato de la columna donde se van a insertar (encerrados entre comillas simples ' ' para valores de tipo texto,
entre # # para valores de fecha...) la asignación de valores se realiza por posición, el primer valor lo asigna a la primera columna, el segun-
do valor a la segunda columna, así sucesivamente...
Cuando la tabla tiene una columna de tipo contador (AutoNumber9 ó identity10), lo normal es no asignar valor a esa columna para
que el sistema le asigne el valor que le toque según el contador, si por el contrario queremos que la columna tenga un valor concreto, lo
indicamos en la lista de valores.
Cuando no se indica ninguna lista de columnas después del destino, se asume por defecto todas las columnas de la ta-bla, en es-
te caso, los valores se tienen que especificar en el mismo orden en que aparecen las columnas en la ventana de diseño de dicha tabla, y se
tiene que utilizar el valor NULL para rellenar las columnas de las cuales no tenemos valores.
Ejemplo (Para Access):
INSERT INTO empleados VALUES (200, 'Juan López', 30, NULL, 'rep ventas', #06/23/01#, NULL, 350000, 0)
Observar en el ejemplo que los valores de tipo texto se encierran entre comillas simples ' ' (también se pueden emplear las comi-
llas dobles " ") y que la fecha de contrato se encierra entre almohadillas # # con el formato mes/día/año. Como no tenemos valor para los
campos oficina y director (a este nuevo empleado todavía no se le ha asignado director ni oficina) utilizamos la palabra reservada NULL.
Los valores numéricos se escriben tal cual, para separar la parte entera de la parte decimal hay que utilizar siempre el punto independien-
temente de la configuración que tengamos.
Cuando indicamos nombres de columnas, estos corresponden a nombres de columna de la tabla, pero no tienen por qué estar en
el orden en que aparecen en la ventana diseño de la tabla, también se pueden omitir algunas columnas, la columnas que no se nombran
tendrán por defecto el valor NULL o el valor predeterminado indicado en la ventana de diseño de tabla.
El ejemplo anterior se podría escribir de la siguiente forma:

INSERT INTO empleados (numemp,oficina, nombre, titulo,cuota, contrato, ventas)


VALUES (200, 30, 'Juan López', 'rep ventas',350000, #06/23/01#,0)

9
Para Access
10
Para SQL Server

AÑO 2003 Página 35 de 96


SQL Lic. Gustavo Rei

Observar que ahora hemos variado el orden de los valores y los nombres de columna no siguen el mismo orden que en la tabla
origen, no importa, lo importante es poner los valores en el mismo orden que las columnas que enunciamos. Como no enunciamos las
columnas oficina y director se rellenarán con el valor nulo (porque es el valor que tienen esas columnas como valor predeterminado).
El utilizar la opción de poner una lista de columnas podría parecer peor ya que se tiene que escribir más pero realmente tiene
ventajas sobre todo cuando la sentencia la vamos a almacenar y reutilizar:
la sentencia queda más fácil de interpretar leyéndola vemos qué valor asignamos a qué columna,
de paso nos aseguramos que el valor lo asignamos a la columna que queremos,
si por lo que sea cambia el orden de las columnas en la tabla en el diseño, no pasaría nada mientras que de la otra forma intenta-
ría asignar los valores a otra columna, esto produciría errores de 'tipo no corresponde' y lo que es peor podría asignar valores erróneos sin
que nos demos cuenta,
otra ventaja es que si se añade una nueva columna a la tabla en el diseño, la primera sentencia INSERT daría error ya que el
número de valores no corresponde con el número de columnas de la tabla, mientras que la segunda INSERT no daría error y en la nueva
columna se insertaría el valor predeterminado.

ERRORES QUE SE PUEDEN PRODUCIR CUANDO SE EJECUTA LA SENTENCIA INSERT INTO(CON ACCESS):

Si la tabla de destino tiene clave principal y en ese campo intentamos no asignar valor, asignar el valor nulo o un valor que ya
existe en la tabla, el motor de base de datos Microsoft Jet no añade la fila y da un mensaje de error de 'infracciones de clave'.
Si tenemos definido un índice único (sin duplicados) e intentamos asignar un valor que ya existe en la tabla también devuelve el
mismo error.
Si la tabla está relacionada con otra, se seguirán las reglas de integridad referencial. Aquí puedes repasar las reglas de integridad
referencial

Para SQL Server

AGREGAR FILAS CON INSERT


La instrucción INSERT agrega una o más filas nuevas a una tabla. Tratada de forma simplificada, INSERT tiene la siguiente for-
ma:

INSERT [INTO] table_or_view [(column_list)] data_values

La instrucción hace que data_values se inserte como una o más filas en la tabla o vista que se nombra. El argumento column_list
es una lista separada por comas de los nombres de tablas que se pueden utilizar para especificar las columnas para las que se suministran
datos. Si no se especifica column_list, todas las columnas de la tabla o vista reciben datos.
Cuando una column_list no enumera todas las columnas de la tabla o vista, se inserta un valor de NULL (o el valor predetermina-
do si se ha definido alguno para la columna) en aquellas columnas que no se hayan enumerado en la lista. Todas las columnas no especifi-
cadas en la lista de columnas deben permitir valores NULL o tener un valor predeterminado asignado.
Las instrucciones INSERT no especifican valores para los siguientes tipos de columna porque Microsoft® SQL Server™ genera
los valores de las columnas de estos tipos:
Columnas con una propiedad IDENTITY que genera los valores para la columna.
Columnas que tengan un valor predeterminado que utilice la función NEWID para generar un valor GUID exclusivo.
Columnas calculadas.
Se trata de columnas virtuales que se definieron como una expresión calculada a partir de una o varias columnas en la instrucción
CREATE TABLE, como:

CREATE TABLE TestTable


(ColA INT PRIMARY KEY,
ColB INT NOT NULL,
ColC AS (ColA + ColB) * 2)

Los valores de datos suministrados deben coincidir con la lista de columnas. El número de valores de datos debe ser el mismo
que el número de columnas y el tipo de datos, precisión y escala de cada valor de datos debe coincidir con los de la columna correspon-
diente. Hay dos maneras de especificar los valores de datos:

Utilizar una cláusula VALUES para especificar los valores de datos para una fila:
INSERT INTO MyTable (PriKey, Description)
AÑO 2003 Página 36 de 96
SQL Lic. Gustavo Rei

VALUES (123, 'A description of part 123.')

Utilizar una subconsulta SELECT para especificar los valores de datos para una o más filas.
INSERT INTO MyTable (PriKey, Description)
SELECT ForeignKey, Description
FROM SomeView

Insertar varias filas INSERT INTO...SELECT


Podemos insertar en una tabla varias filas con una sola sentencia SELECT INTO si los valores a insertar se pueden obtener como
resultado de una consulta, en este caso sustituimos la cláusula VALUES lista de valores por una sentencia SELECT como las que hemos
visto hasta ahora. Cada fila resultado de la SELECT forma una lista de valores que son los que se insertan en una nueva fila de la tabla
destino. Es como si tuviesemos una INSERT...VALUES por cada fila resultado de la sentencia SELECT.
La sintaxis es la siguiente:

El origen de la SELECT puede ser el nombre de una consulta guardada, un nombre de tabla o una composición de va-rias tablas (
mediante INNER JOIN, LEFT JOIN, RIGHT JOIN o producto cartesiano).
Cada fila devuelta por la SELECT actúa como la lista de valores que vimos con la INSERT...VALUES por lo que tiene las mismas
restricciones en cuanto a tipo de dato, etc. La asignación de valores se realiza por posición por lo que la SELECT debe devolver el mismo
número de columnas que las de la tabla destino y en el mismo orden, o el mismo número de columnas que indicamos en la lista de colum-
nas después de destino.
Las columnas de la SELECT no tienen porque llamarse igual que en la tabla destino ya que el sistema sólo se fija en los valores
devueltos por la SELECT.
Si no queremos asignar valores a todas las columnas entonces tenemos que indicar entre paréntesis la lista de columnas a relle-
nar después del nombre del destino.
El estándar ANSI/ISO especifica varias restricciones sobre la consulta que aparece dentro de la sentencia INSERT:
la consulta no puede tener una cláusula ORDER BY,
la tabla destino de la sentencia INSERT no puede aparecer en la cláusula FROM de la consulta o de ninguna subconsulta que és-
ta tenga. Esto prohibe insertar parte de una tabla en sí misma,
la consulta no puede ser la UNION de varias sentencias SELECT diferentes,
el resultado de la consulta debe contener el mismo número de columnas que las indicadas para insertar y los tipos de datos de-
ben ser compatibles columna a columna.
Sin embargo en SQL de Microsoft Jet,
se puede incluir la cláusula ORDER BY aunque no tiene mucho sentido.
se puede poner en la cláusula FROM de la consulta, la tabla en la que vamos a insertar,
pero no podemos utilizar una UNION.

Ejemplo: Supongamos que tenemos una tabla llamada repres con la misma estructura que la tabla empleados, y queremos in-
sertar en esa tabla los empleados que tengan como titulo rep ventas

INSERT INTO repres SELECT * FROM empleados WHERE titulo = 'rep ventas'

Con SELECT obtenemos las filas correspondientes a los empleados con título rep ventas,y las insertamos en la tabla repres. Co-
mo las tablas tienen la misma estructura no hace falta poner la lista de columnas y podemos emplear * en la lista de selección de la SE-
LECT.
Ejemplo: Supongamos ahora que la tabla repres tuviese las siguientes columnas numemp, oficinarep, nombrerep. En este caso
no podríamos utilizar el asterisco, tendríamos que poner:

INSERT INTO repres SELECT numemp, oficina, nombre FROM empleados WHERE titulo = 'rep ventas'
O bien:

AÑO 2003 Página 37 de 96


SQL Lic. Gustavo Rei

INSERT INTO repres (numemp, oficinarep, nombrerep)


SELECT numemp, oficina, nombre FROM empleados WHERE titulo = 'rep ventas'

Insertar filas en una nueva tabla SELECT ... INTO


Esta sentencia inserta filas creando en ese momento la tabla donde se insertan las filas. Se suele utilizar para guardar en una ta-
bla el resultado de una SELECT.
La sintaxis es la siguiente:

Las columnas de la nueva tabla tendrán el mismo tipo y tamaño que las columnas origen, y se llamarán con el nombre de alias de
la columna origen o en su defecto con el nombre de la columna origen, pero no se transfiere ninguna otra propiedad del campo o de la tabla
como por ejemplo las claves e índices.
La sentencia SELECT puede ser cualquier sentencia SELECT sin ninguna restricción, puede ser una consulta multitabla, una
consulta de resumen, una UNION ...

Ejemplo:
SELECT * INTO t2 FROM t1

Esta sentencia genera una nueva tabla t2 con todas las filas de la tabla t1. Las columnas se llamarán igual que en t1 pero t2 no
será una copia exacta de t1 ya no tendrá clave principal ni relaciones con las otras tablas, ni índices si los tuviese t1 etc...

Si en la base de datos hay ya una tabla del mismo nombre, el sistema nos avisa y nos pregunta si la queremos borrar. Si le con-
testamos que no, la SELECT no se ejecuta.
Para formar una sentencia SELECT INTO lo mejor es escribir la SELECT que permite generar los datos que queremos guardar
en la nueva tabla, y después añadir delante de la cláusula FROM la cláusula INTO nuevatabla.
La sentencia SELECT INTO se suele utilizar para crear tablas de trabajo, o tablas intermedias, las creamos para una de-
terminada tarea y cuando hemos terminado esa tarea las borramos. También puede ser útil para sacar datos en una tabla para enviarlos a
alguien.
Por ejemplo: Queremos enviarle a un representante una tabla con todos los datos personales de sus clientes para que les pueda
enviar cartas etc...

SELECT numclie AS codigo, nombre, direccion, telefono INTO susclientes FROM clientes WHERE repclie = '103';

Vamos a suponer que hemos añadido a nuestra tabla de clientes los campos direccion y telefono. En el ejemplo anterior la nue-va
tabla tendrá cuatro columnas llamadas codigo, nombre, direccion, telefono y contendrá las filas correspondientes a los clientes del represen-
tante 103

Modificar el contenido de las filas ( UPDATE )


La sentencia UPDATE modifica los valores de una o más columnas en las filas seleccionadas de una o varias tablas.
La sintaxis es la siguiente:

Origen puede ser un nombre de tabla, un nombre de consulta o una composición de tablas, también puede incluir la cláusula IN si
la tabla a modificar se encuentra en una base de datos externa.

AÑO 2003 Página 38 de 96


SQL Lic. Gustavo Rei

La cláusula SET especifica qué columnas van a modificarse y qué valores asignar a esas columnas.
nbcolumna, es el nombre de la columna a la cual queremos asignar un nuevo valor por lo tanto debe ser una columna de la tabla
origen. El SQL estándar exige nombres sin cualificar pero algunas implementaciones (como por ejemplo el SQL de Microsoft Jet que esta-
mos estudiando) sí lo permiten.
La expresión en cada asignación debe generar un valor del tipo de dato apropiado para la columna indicada. La expresión debe
ser calculable a partir de los valores de la fila que se está actualizando. Expresión no puede ser una subconsulta.
Ejemplo:
UPDATE oficinas INNER JOIN empleados
ON oficinas.oficina = empleados.oficina
SET cuota=objetivo*0.01;

En este ejemplo queremos actualizar las cuotas de nuestros empleados de tal forma que la cuota de un empleado sea el 1% del
objetivo de su oficina. La columna a actualizar es la cuota del empleado y el valor a asignar es el 1% del objetivo de la oficina del empleado,
luego la cláusula SET será SET cuota = objetivo*0.01 o SET cuota = objetivo/100. El origen debe contener la cuota del empleado y el objeti-
vo de su oficina, luego el origen será el INNER JOIN de empleados con oficinas.
La cláusula WHERE indica qué filas van a ser modificadas. Si se omite la cláusula WHERE se actualizan todas las filas.
En la condición del WHERE se puede incluir una subconsulta. En SQL standard la tabla que aparece en la FROM de la subcon-
sulta no puede ser la misma que la tabla que aparece como origen, pero en el SQL de Microsoft Jet sí se puede.
Ejemplo: Queremos poner a cero las ventas de los empleados de la oficina 12
UPDATE empleados SET ventas = 0 WHERE oficina = 12;
Ejemplo: Queremos poner a cero el limite de credito de los clientes asignados a empleados de la oficina 12.
UPDATE clientes SET limitecredito = 0
WHERE repclie IN (SELECT numemp FROM empleados WHERE oficina = 12);
Si para el cálculo de expresion se utiliza una columna que también se modifica, el valor que se utiliza es el antes de la modifi-
cación, lo mismo para la condición de búsqueda.
Cuando se ejecuta una sentencia UPDATE primero se genera el origen y se seleccionan las filas según la cláusula WHERE. A
continuación se coge una fila de la selección y se le aplica la cláusula SET, se actualizan todas las columnas in-cluidas en la cláusula SET a
la vez por lo que los nombres de columna pueden especificarse en cualquier orden. Después se coge la siguiente fila de la selección y se le
aplica del mismo modo la cláusula SET, así sucesivamente con todas las filas de la selec-ción.
Ejemplo:
UPDATE oficinas SET ventas=0, objetivo=ventas;
O bien:
UPDATE oficinas SET objetivo=ventas, ventas=0;
Los dos ejemplos anteriores son equivalentes ya que el valor de ventas que se asigna a objetivo es el valor antes de la actuali-
zación, se deja como objetivo las ventas que ha tenido la oficina hasta el momento y se pone a cero la columna ventas.
Si actualizamos una columna definida como clave foránea, esta columna se podrá actualizar o no siguiendo las reglas de integri-
dad referencial. El valor que se le asigna debe existir en la tabla de referencia.
Si actualizamos una columna definida como columna principal de una relación entre dos tablas, esta columna se podrá actualizar
o no siguiendo las reglas de integridad referencial. Aquí puedes repasar las reglas de integridad referencial

LA INSTRUCCIÓN UPDATE TIENE ESTAS CLÁUSULAS PRINCIPALES:

SET
Contiene una lista separada por comas de las columnas que deben actualizarse y el nuevo valor de cada columna, con el formato
column_name = expression. El valor suministrado por las expresiones incluye elementos tales como constantes, valores seleccionados de
una columna de otra tabla o vista, o valores calculados por una expresión compleja.

FROM
Identifica las tablas o vistas que suministran los valores de las expresiones de la cláusula SET, y las condiciones de combinación
opcional entre las tablas o vistas de origen.

WHERE
Especifica la condición de búsqueda que define las filas de las tablas y vistas de origen que están calificadas para proporcionar
valores para las expresiones de la cláusula SET.

AÑO 2003 Página 39 de 96


SQL Lic. Gustavo Rei

Esta instrucción de actualización aumenta el precio de todos los productos de Northwind de la categoría 2 en un 10 por ciento:

UPDATE Northwind.dbo.Products
SET UnitPrice = UnitPrice * 1.1
WHERE CategoryID = 2

Nota UPDATE se registra; si está cambiando grandes bloques de datos text o image, considere la posibilidad de utilizar la ins-
trucción UPDATETEXT o WRITETEXT que, de forma predeterminada, no se registra.

UTILIZAR UNA INSTRUCCIÓN UPDATE SIMPLE


En estos ejemplos se muestra cómo se pueden ver afectadas todas las filas si se elimina una cláusula WHERE de una instrucción
UPDATE.

En este ejemplo se muestra cómo se puede actualizar la tabla publishers si todas las editoriales de la tabla trasladan su sede cen-
tral a Atlanta, Georgia.

UPDATE publishers
SET city = 'Atlanta', state = 'GA'

En este ejemplo se cambian los nombres de todas las editoriales a NULL.

UPDATE publishers
SET pub_name = NULL

También se pueden utilizar valores calculados en una actualización. En este ejemplo se duplican todos los precios de la tabla ti-
tles.

UPDATE titles
SET price = price * 2

La cláusula WHERE especifica las filas que se van a actualizar. Por ejemplo, imaginemos que el norte de California cambiara su
nombre por el de Pacifica (abreviado como PC) y los ciudadanos de Oakland decidieran cambiar el nombre de la localidad por el de Bay
City. En este ejemplo se muestra cómo actualizar la tabla authors para todos los residentes de la antigua Oakland, cuyas direcciones han
quedado desfasadas.

UPDATE authors
SET state = 'PC', city = 'Bay City'
WHERE state = 'CA' AND city = 'Oakland'

UTILIZAR LA INSTRUCCIÓN UPDATE CON INFORMACIÓN DE OTRA TABLA


En este ejemplo, se modifica la columna ytd_sales de la tabla titles para reflejar las ventas más recientes registradas en la tabla
sales.

UPDATE titles
SET ytd_sales = titles.ytd_sales + sales.qty
FROM titles, sales
WHERE titles.title_id = sales.title_id
AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

En este ejemplo se asume que sólo se registra un conjunto de ventas para un determinado título en una fecha determinada y que
las actualizaciones son recientes. Si no es así (si se puede registrar más de una venta de un título determinado en el mismo día), el ejemplo
que se muestra aquí no funcionará correctamente. Se ejecuta sin errores, pero cada título se actualiza con una sola venta, independiente-
mente de cuántas ventas reales se realicen en el día. Esto es debido a que una sola instrucción UPDATE nunca actualiza dos veces la
misma fila.

AÑO 2003 Página 40 de 96


SQL Lic. Gustavo Rei

En una situación en la que pueda haber más de una venta de un título en el mismo día, todas las ventas para cada título se debe-
rán agregar dentro de la instrucción UPDATE, tal como se muestra en este ejemplo:

UPDATE titles
SET ytd_sales =
(SELECT SUM(qty)
FROM sales
WHERE sales.title_id = titles.title_id
AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
FROM titles, sales

UTILIZAR UPDATE CON LA CLÁUSULA TOP EN UNA INSTRUCCIÓN SELECT


En este ejemplo se actualiza la columna state para los 10 primeros autores de la tabla authors.

UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id

Borrar filas (DELETE)


La sentencia DELETE elimina filas de una tabla.
La sintaxis es la siguiente:

Origen es el nombre de la tabla de donde vamos a borrar, podemos indicar un nombre de tabla, incluir la cláusula IN si la tabla se
encuentra en una base de datos externa, también podemos escribir una composición de tablas.
La opción tabla.* se utiliza cuando el origen está basado en varias tablas, y sirve para indicar en qué tabla vamos a borrar.
La opción * es opcional y es la que se asume por defecto y se puede poner unicamente cuando el origen es una sola tabla.
La cláusula WHERE sirve para especificar qué filas queremos borrar. Se eliminaran de la tabla todas las filas que cumplan la con-
dición. Si no se indica la cláusula WHERE, se borran TODAS las filas de la tabla.
En la condición de búsqueda de la sentencia DELETE, se puede utilizar una subconsulta. En SQL standard la tabla que aparece
en la FROM de la subconsulta no puede ser la misma que la tabla que aparece en la FROM de la DELETE pero en el SQL de Microsoft Jet
sí se puede hacer.
Una vez borrados, los registros no se pueden recuperar.

Si la tabla donde borramos está relacionada con otras tablas se podrán borrar o no los registros siguiendo las reglas de integridad
referencial definidas en las relaciones.
Ejemplo:
DELETE * FROM pedidos WHERE clie IN (SELECT numclie FROM clientes WHERE nombre = 'Julian López');
O bien:
DELETE pedidos.* FROM pedidos INNER JOIN clientes ON pedidos.clie = clientes.numclie WHERE nombre = 'Julian López';
Las dos sentencias borran los pedidos del cliente Julian López. En la segunda estamos obligados a poner pedidos.* porque el ori-
gen está basado en varias tablas.

DELETE * FROM pedidos; o DELETE FROM pedidos; Borra todas las filas de pedidos.

RESUMEN DEL TEMA


Si queremos añadir en una tabla una fila con valores conocidos utilizamos la sentencia INSERT INTO tabla VALUES (lista de va-
lores).
Si los valores a insertar se encuentran en una o varias tablas utilizamos INSERT INTO tabla SELECT ...

AÑO 2003 Página 41 de 96


SQL Lic. Gustavo Rei

Para crear una nueva tabla con el resultado de una consulta con la sentencia SELECT...INTO tabla FROM...
Para cambiar los datos contenidos en una tabla, tenemos que actualizar las filas de dicha tabla con la sentencia UPDATE tabla
SET asignación de nuevos valores.
Para eliminar filas de una tabla se utiliza la sentencia DELETE FROM tabla.
Con la cláusula WHERE podemos indicar a qué filas afecta la actualización o el borrado.

EJEMPLOS DE SQL SERVER


Eliminar filas con DELETE
La instrucción DELETE quita una o varias filas de una tabla o vista. Una forma simplificada de la sintaxis de DELETE es:

DELETE table_or_view FROM table_sources WHERE search_condition

table_or_view nombra la tabla o vista de la que se van a eliminar las filas. Se eliminan todas las filas de table_or_view que reúnan
los requisitos de la condición de búsqueda de la cláusula WHERE. Si no se especifica una cláusula WHERE, se eliminan todas las filas de
table_or_view. La cláusula FROM especifica tablas o vistas adicionales y condiciones de combinación que pueden ser utilizadas por los
predicados de la condición de búsqueda de la cláusula WHERE para calificar las filas que deben ser eliminadas de table_or_view. Las filas
no se eliminan de las tablas mencionadas en la cláusula FROM, sólo de la tabla mencionada en table_or_view.
Cualquier tabla de la que se hayan quitado todas las filas sigue permaneciendo en la base de datos. La instrucción DELETE sólo
elimina filas de la tabla, y ésta se debe quitar de la base de datos mediante la instrucción DROP TABLE.
Esta secuencia de comandos muestra las tres instrucciones DELETE necesarias para eliminar las filas asociadas con los produc-
tos suministrados por la empresa llamada Lyngbysild de la base de datos Northwind. No sería una operación empresarial típica porque
conlleva la eliminación de líneas de pedidos existentes, pero muestra una serie de eliminaciones de distinta complejidad.

USE Northwind
GO
DELETE [Order Details]
FROM Suppliers, Products
WHERE Products.SupplierID = Suppliers.SupplierID
AND Suppliers.CompanyName = 'Lyngbysild'
AND [Order Details].ProductID = Products.ProductID

GO
DELETE Products
FROM Suppliers
WHERE Products.SupplierID = Suppliers.SupplierID
AND Suppliers.CompanyName = 'Lyngbysild'

GO
DELETE Suppliers
WHERE CompanyName = 'Lyngbysild'
GO

UTILIZAR DELETE SIN PARÁMETROS


Este ejemplo elimina todas las filas de la tabla authors.

USE pubs
DELETE authors

UTILIZAR DELETE EN UN CONJUNTO DE FILAS


Debido a que au_lname puede no ser único, este ejemplo elimina todas las filas en que au_lname es McBadden.

USE pubs
DELETE FROM authors
WHERE au_lname = 'McBadden'

AÑO 2003 Página 42 de 96


SQL Lic. Gustavo Rei

UTILIZAR DELETE EN LA FILA ACTUAL DE UN CURSOR


Este ejemplo muestra una eliminación realizada contra un cursor denominado complex_join_cursor. Sólo afecta a la única fila que
se recupera actualmente del cursor.

USE pubs
DELETE FROM authors
WHERE CURRENT OF complex_join_cursor

UTILIZAR LA INSTRUCCIÓN DELETE BASADA EN UNA SUBCONSULTA O UTILIZAR LA EXTENSIÓN DE TRANSACT-SQL


Este ejemplo muestra la extensión de Transact-SQL que se utiliza para eliminar registros de una tabla base que se basa en una
combinación o subconsulta correlacionada. La primera instrucción DELETE muestra la solución de subconsulta compatible con SQL-92 y la
segunda instrucción DELETE muestra la extensión de Transact-SQL. Ambas consultas quitan filas de la tabla titleauthors sobre la base de
los títulos almacenados en la tabla titles.

/* SQL-92-Standard subquery */
USE pubs
DELETE FROM titleauthor
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE title LIKE '%computers%')

/* Transact-SQL extension */
USE pubs
DELETE titleauthor
FROM titleauthor INNER JOIN titles
ON titleauthor.title_id = titles.title_id
WHERE titles.title LIKE '%computers%'

UTILIZAR DELETE Y SELECT CON LA CLÁUSULA TOP


Debido a que la instrucción SELECT se puede especificar en una instrucción DELETE, también se puede utilizar la cláusula TOP
en la instrucción SELECT. En este ejemplo se eliminan los 10 primeros autores de la tabla authors.

DELETE authors
FROM (SELECT TOP 10 * FROM authors) AS t1
WHERE authors.au_id = t1.au_id

AÑO 2003 Página 43 de 96


SQL Lic. Gustavo Rei

Hasta ahora hemos estudiado las sentencias que forman parte del DML (Data Management Language) lenguaje de manipulación
de datos, todas esas sentencias sirven para recuperar, insertar, borrar, modificar los datos almacenados en la base de datos; lo que vere-
mos en este tema son las sentencias que afectan a la estructura de los datos.
El DDL (Data Definition Language) lenguaje de definición de datos es la parte del SQL que más varía de un sistema a otro ya que
esa área tiene que ver con cómo se organizan internamente los datos y eso, cada sistema lo hace de una manera u otra.
Así como el DML de Microsoft Jet incluye todas las sentencias DML que nos podemos encontrar en otros SQLs (o casi todas), el
DDL de Microsoft Jet en cambio contiene menos instrucciones que otros sistemas.

CREATE DATABASE
Crea una nueva base de datos y los archivos que se utilizan para almacenar la base de datos o adjunta una base de datos desde
los archivos de una base de datos creada anteriormente.
Sintaxis

CREATE DATABASE database_name [ PRIMARY ]


[ ON ( [ NAME = logical_file_name , ]
[ < filespec > [ ,...n ] ] FILENAME = 'os_file_name'
[ , < filegroup > [ ,...n ] ] [ , SIZE = size ]
] [ , MAXSIZE = { max_size | UNLIMITED } ]
[ LOG ON { < filespec > [ ,...n ] } ] [ , FILEGROWTH = growth_increment ] ) [ ,...n ]
[ COLLATE collation_name ] < filegroup > ::=
[ FOR LOAD | FOR ATTACH ] FILEGROUP filegroup_name < filespec > [ ,...n ]
< filespec > ::=

Observaciones
Puede utilizar una instrucción CREATE DATABASE para crear una base de datos y los archivos que almacenan la base de datos.
SQL Server implementa la instrucción CREATE DATABASE en dos pasos:
SQL Server utiliza una copia de la base de datos model para inicializar la base de datos y sus metadatos.
SQL Server rellena el resto de la base de datos con páginas vacías, excepto las páginas que tengan datos internos que registren
cómo se emplea el espacio en la base de datos.
Cuando se especifica una instrucción individual CREATE DATABASE database_name sin parámetros adicionales, la base de da-
tos se crea con el mismo tamaño que la base de datos model.

Todas las bases de datos tienen al menos un grupo de archivos principal. Todas las tablas del sistema se encuentran en el grupo
de archivos principal. Una base de datos puede tener también grupos de archivos definidos por el usuario. Si se crea un objeto con una
cláusula ON filegroup que especifica un grupo de archivos definido por el usuario, todas las páginas del objeto se asignan desde el grupo de
archivos especificado. Las páginas de todos los objetos de usuario creados sin una cláusula ON filegroup, o con una cláusula ON DE-
FAULT, se asignan desde el grupo de archivos predeterminado. Cuando se crea una base de datos por primera vez, el grupo de archivos
principal es el grupo de archivos predeterminado. Con ALTER DATABASE, se puede especificar que un grupo de archivos definido por el
usuario sea el grupo de archivos predeterminado:

ALTER DATABASE database_name MODIFY FILEGROUP filegroup_name DEFAULT

Cada base de datos tiene un propietario con capacidad para realizar actividades especiales en la base de datos. El propietario es
el usuario que crea la base de datos. El propietario de la base de datos se puede cambiar mediante sp_changedbowner.

Para mostrar un informe de una base de datos o de todas las bases de datos de una instancia de SQL Server, ejecute sp_helpdb.
Para obtener un informe acerca del espacio utilizado en una base de datos, emplee sp_spaceused. Para obtener un informe de los grupos
de archivos de una base de datos, utilice sp_helpfilegroup, y utilice sp_helpfile para obtener el informe de los archivos de la base de datos.

Las versiones anteriores de SQL Server utilizaban las instrucciones DISK INIT para crear los archivos de la base de datos antes
de que se ejecutara la instrucción CREATE DATABASE. Por motivos de compatibilidad con versiones anteriores de SQL Server, la instruc-
ción CREATE DATABASE puede crear también una base de datos nueva con los archivos o dispositivos creados con la instrucción DISK
INIT. Para obtener más información, consulte Detalles de compatibilidad con versiones anteriores de SQL Server.

AÑO 2003 Página 44 de 96


SQL Lic. Gustavo Rei

Ejemplos
Crear una base de datos que especifica los archivos de datos y de registro de transacciones
Este ejemplo crea una base de datos llamada Sales. Debido a que no se utiliza la palabra clave PRIMARY, el primer archivo (Sa-
les_dat) se convierte en el archivo principal. Como no se especifican MB ni KB en el parámetro SIZE del archivo Sales_dat, de forma prede-
terminada utiliza MB y el tamaño se asigna en megabytes. El tamaño del archivo Sales_log se asigna en megabytes porque se ha indicado
explícitamente el sufijo MB en el parámetro SIZE.

USE master FILEGROWTH = 5 )


GO LOG ON
CREATE DATABASE Sales ( NAME = 'Sales_log',
ON FILENAME = 'c:\program files\microsoft sql
( NAME = Sales_dat, server\mssql\data\salelog.ldf',
FILENAME = 'c:\program files\microsoft sql SIZE = 5MB,
server\mssql\data\saledat.mdf', MAXSIZE = 25MB,
SIZE = 10, FILEGROWTH = 5MB )
MAXSIZE = 50, GO

Crear una base de datos mediante la especificación de múltiples archivos de datos y de registro de transacciones
Este ejemplo crea una base de datos llamada Archive con tres archivos de datos de 100 MB y dos archivos de registro de tran-
sacciones de 100 MB. El archivo principal es el primer archivo de la lista y se especifica explícitamente con la palabra clave PRIMARY. Los
archivos de registro de transacciones se especifican a continuación de las palabras clave LOG ON. Observe las extensiones que se em-
plean para los archivos de la opción FILENAME: .MDF se utiliza para los archivos de datos principales, .NDF para los archivos de datos
secundarios y .LDF para los archivos de registro de transacciones.

USE master SIZE = 100MB,


GO MAXSIZE = 200,
CREATE DATABASE Archive FILEGROWTH = 20)
ON LOG ON
PRIMARY ( NAME = Arch1, ( NAME = Archlog1,
FILENAME = 'c:\program files\microsoft sql FILENAME = 'c:\program files\microsoft sql
server\mssql\data\archdat1.mdf', server\mssql\data\archlog1.ldf',
SIZE = 100MB, SIZE = 100MB,
MAXSIZE = 200, MAXSIZE = 200,
FILEGROWTH = 20), FILEGROWTH = 20),
( NAME = Arch2, ( NAME = Archlog2,
FILENAME = 'c:\program files\microsoft sql FILENAME = 'c:\program files\microsoft sql
server\mssql\data\archdat2.ndf', server\mssql\data\archlog2.ldf',
SIZE = 100MB, SIZE = 100MB,
MAXSIZE = 200, MAXSIZE = 200,
FILEGROWTH = 20), FILEGROWTH = 20)
( NAME = Arch3, GO
FILENAME = 'c:\program files\microsoft sql
server\mssql\data\archdat3.ndf',
Crear una base de datos individual
En este ejemplo se crea una base de datos llamada Products y se especifica un único archivo. El archivo especificado se convier-
te en el archivo principal y se crea automáticamente un archivo de registro de transacciones de 1 MB. Como no se especifican MB ni KB en
el parámetro SIZE del archivo principal, se asigna en megabytes. Ya que no existe <filespec> para el archivo de registro de transacciones,
éste no tiene MAXSIZE y puede crecer hasta llenar todo el espacio disponible en el disco.

USE master FILENAME = 'c:\program files\microsoft sql


GO server\mssql\data\prods.mdf',
CREATE DATABASE Products SIZE = 4,
ON MAXSIZE = 10,
( NAME = prods_dat, FILEGROWTH = 1 )
GO
AÑO 2003 Página 45 de 96
SQL Lic. Gustavo Rei

Crear una base de datos sin especificar los archivos


Este ejemplo crea una base de datos llamada mytest y crea los archivos principal y de registro de transacciones correspondien-
tes. Debido a que la instrucción no tiene elementos <filespec>, el archivo principal de la base de datos tiene el tamaño del archivo principal
de la base de datos model. El registro de transacciones tiene el tamaño del archivo del registro de transacciones de la base de datos model.
Como no se ha especificado MAXSIZE, los archivos pueden crecer hasta llenar todo el espacio disponible en el disco.
CREATE DATABASE mytest
Crear una base de datos sin especificar SIZE
Este ejemplo crea una base de datos llamada products2. El archivo prods2_dat se convierte en el archivo principal, con un tama-
ño igual al tamaño del archivo principal de la base de datos model. El archivo de registro de transacciones se crea automáticamente y es un
25 por ciento del tamaño del archivo principal, o 512 KB, el que sea mayor. Como no se ha especificado MAXSIZE, los archivos pueden
crecer hasta llenar todo el espacio disponible en el disco.
USE master
GO
CREATE DATABASE Products2
ON
( NAME = prods2_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\prods2.mdf' )
GO
Crear una base de datos con grupos de archivos
Este ejemplo crea una base de datos llamada sales con tres grupos de archivos:

CREATE TABLE
La sentencia CREATE TABLE sirve para crear la estructura de una tabla no para rellenarla con datos, nos permite definir las co-
lumnas que tiene y ciertas restricciones que deben cumplir esas columnas.
La sintaxis es la siguiente:

nbtabla: nombre de la tabla que estamos definiendo


nbcol: nombre de la columna que estamos definiendo
tipo: tipo de dato de la columna, todos los datos almacenados en la columna deberán ser de ese tipo. Para ver qué tipos de da-tos
se pueden emplear haz clic aquí
Una restricción consiste en la definición de una característica adicional que tiene una columna o una combinación de columnas,
suelen ser características como valores no nulos (campo requerido), definición de índice sin duplicados, definición de clave principal y defi-
nición de clave foránea (clave ajena o externa, campo que sirve para relacionar dos tablas entre sí).
restricción1: una restricción de tipo 1 es una restricción que aparece dentro de la definición de la columna después del tipo de da-
to y afecta a una columna, la que se está definiendo.
restricción2: una restricción de tipo 2 es una restricción que se define después de definir todas las columnas de la tabla y afecta a
una columna o a una combinación de columnas.
Para escribir una sentencia CREATE TABLE se empieza por indicar el nombre de la tabla que queremos crear y a continuación
entre paréntesis indicamos separadas por comas las definiciones de cada columna de la tabla, la definición de una columna consta de su
nombre, el tipo de dato que tiene y podemos añadir si queremos una serie de especificaciones que deberán cumplir los datos almacenados
en la columna, después de definir cada una de las columnas que compone la tabla se pueden añadir una serie de restricciones, esas res-
tricciones son las mismas que se pueden indicar para cada columna pero ahora pueden afectar a más de una columna por eso tienen una
sintaxis ligeramente diferente.
Una restricción de tipo 1 se utiliza para indicar una característica de la columna que estamos definiendo, tiene la siguiente sin-

AÑO 2003 Página 46 de 96


SQL Lic. Gustavo Rei

taxis:

La cláusula NOT NULL indica que la columna no podrá contener un valor nulo, es decir que se deberá rellenar obligatoria-mente y
con un valor válido (equivale a la propiedad requerido Sí de las propiedades del campo).
La cláusula CONSTRAINT sirve para definir una restricción que se podrá eliminar cuando queramos sin tener que borrar la co-
lumna. A cada restricción se le asigna un nombre que se utiliza para identificarla y para poder eliminarla cuando se quiera.
Como restricciones tenemos la de clave primaria (clave principal), la de índice único (sin duplicados), la de valor no nulo, y la de
clave foránea.
La cláusula PRIMARY KEY se utiliza para definir la columna como clave principal de la tabla. Esto supone que la columna no
puede contener valores nulos ni pueden haber valores duplicados en esa columna, es decir que dos filas no pueden tener el mismo valor en
esa columna.
En una tabla no pueden haber varias claves principales, por lo que no podemos incluir la cláusula PRIMARY KEY más de una
vez, en caso contrario la sentencia da un error. No hay que confundir la definición de varias claves principales con la definición de una clave
principal compuesta por varias columnas, esto último sí está permitido y se define con una restricción de tipo 2.
La cláusula UNIQUE sirve para definir un índice único sobre la columna. Un índice único es un índice que no permite valores du-
plicados, es decir que si una columna tiene definida un restricción de UNIQUE no podrán haber dos filas con el mismo valor en esa colum-
na. Se suele emplear para que el sistema compruebe el mismo que no se añaden valores que ya existen, por ejemplo si en una tabla de
clientes queremos asegurarnos que dos clientes no puedan tener el mismo D.N.I. y la tabla tiene como clave prin-cipal un código de cliente,
definiremos la columna dni con la restricción de UNIQUE.
La cláusula NOT NULL indica que la columna no puede contener valores nulos, cuando queremos indicar que una columna no
puede contener el valor nulo lo podemos hacer sin poner la cláusula CONSTRAINT, o utilizando una cláusula CONSTRAINT.
La última restricción que podemos definir sobre una columna es la de clave foránea, una clave foránea es una columna o con-
junto de columnas que contiene un valor que hace referencia a una fila de otra tabla, en una restricción de tipo 1 se puede definir con la
cláusula REFERENCES, después de la palabra reservada indicamos a qué tabla hace referencia, opcionalmente podemos indicar entre
paréntesis el nombre de la columna donde tiene que buscar el valor de referencia, por defecto coge la clave principal de la tabla2, si el valor
que tiene que buscar se encuentra en otra columna de tabla2, entonces debemos indicar el nombre de esta columna entre paréntesis,
además sólo podemos utilizar una columna que esté definida con una restricción de UNIQUE, si la columna2 que indicamos no está defini-
da sin duplicados, la sentencia CREATE nos dará un error. Si quieres repasar conceptos de clave foránea e integridad referencial haz clic
aquí

Ejemplo:
CREATE TABLE tab1 (
col1 INTEGER CONSTRAINT pk PRIMARY KEY,
col2 CHAR(25) NOT NULL,
col3 CHAR(10) CONSTRAINT uni1 UNIQUE,
col4 INTEGER,
col5 INT CONSTRAINT fk5 REFERENCES tab2 );

Con este ejemplo estamos creando la tabla tab1 compuesta por: una columna llamada col1 de tipo entero definida como clave
principal, una columna col2 que puede almacenar hasta 25 caracteres alfanuméricos y no puede contener valores nulos, una columna col3
de hasta 10 caracteres que no podrá contener valores repetidos, una columna col4 de tipo entero sin ninguna restricción, y una columna
col5 de tipo entero clave foránea que hace referencia a valores de la clave principal de la tabla tab2.
Una restricción de tipo 2 se utiliza para definir una característica que afecta a una columna o a una combinación de columnas
de la tabla que estamos definiendo, se escribe después de haber definido todas las columnas de la tabla.
Tiene la siguiente sintaxis:

AÑO 2003 Página 47 de 96


SQL Lic. Gustavo Rei

La sintaxis de una restricción de tipo 2 es muy similar a la CONSTRAINT de una restricción 1 la diferencia es que ahora tene-mos
que indicar sobre qué columnas queremos definir la restricción. Se utilizan obligatoriamente las restricciones de tipo 2 cuando la restricción
afecta a un grupo de columnas o cuando queremos definir más de una CONSTRAINT para una columna (sólo se puede definir una restric-
ción1 en cada columna).
La cláusula PRIMARY KEY se utiliza para definir la clave principal de la tabla. Después de las palabras PRIMARY KEY se indica
entre paréntesis el nombre de la columna o las columnas que forman la clave principal. Las columnas que forman la clave principal no
pueden contener valores nulos ni pueden haber valores duplicados de la combinación de columnas, por ejemplo la ta-bla pedidos de nues-
tros ejemplos tiene una clave principal formada por idfab e idproducto, pues no pueden haber dos filas con la misma combinación de idfab
con idproducto (aci,0001 por ejemplo) pero sí pueden haber dos filas con el valor aci en la columna idfab si tienen valores diferentes en la
columna idproducto, y pueden haber dos filas con el mismo idproducto pero distinto idfab.
En una tabla no pueden haber varias claves principales, por lo que no podemos indicar la cláusula PRIMARY KEY más de una
vez, en caso contrario la sentencia da un error.
La cláusula UNIQUE sirve para definir un índice único sobre una columna o sobre una combinación de columnas. Un índice único
es un índice que no permite valores duplicados. Si el índice es sobre varias columnas no se puede repetir la misma com-binación de valores
en dos o más filas. Se suele emplear para que el sistema compruebe el mismo que no se añaden valores que ya existen.
La cláusula FOREIGN KEY sirve para definir una clave foránea sobre una columna o una combinación de columnas. Una clave
foránea es una columna o conjunto de columnas que contiene un valor que hace referencia a una fila de otra tabla, en una restricción 1 se
puede definir con la cláusula REFERENCES. Para definir una clave foránea en una restricción de tipo 2 debemos empezar por las palabras
FOREIGN KEY después indicamos entre paréntesis la/s columna/s que es clave foránea, a continuación la palabra reservada REFEREN-
CES seguida del nombre de la tabla a la que hace referencia, opcionalmente podemos indicar entre paréntesis el nombre de la/s columna/s
donde tiene que buscar el valor de referencia, por defecto coge la clave principal de la tabla2, si el valor que tiene que buscar se encuentra
en otra/s columna/s de tabla2, entonces debemos escribir el nombre de esta/s columna/s entre paréntesis, además sólo podemos utilizar
una columna (o combinación de columnas) que esté definida con una restricción de UNIQUE, de lo contrario la sentencia CREATE TABLE
nos dará un error.
Ejemplo:
CREATE TABLE tab1 (
col1 INTEGER,
col2 CHAR(25) NOT NULL,
col3 CHAR(10),
col4 INTEGER,
col5 INT,
CONSTRAINT pk PRIMARY KEY (col1),
CONSTRAINT uni1 UNIQUE (col3),
CONSTRAINT fk5 FOREIGN KEY (col5) REFERENCES tab2 );
Con este ejemplo estamos creando la misma tabla tab1 del ejemplo de la página anterior pero ahora hemos definido las restric-
ciones utilizando restricciones de tipo 2.

RESTRICCIONES PRIMARY KEY


Una tabla puede contener una sola restricción PRIMARY KEY.
El índice generado por una restricción PRIMARY KEY no puede hacer que el número de índices de la tabla exceda de 249 índices
no agrupados y 1 índice agrupado.
Si no se especifica CLUSTERED o NONCLUSTERED para una restricción PRIMARY KEY, se utiliza CLUSTERED si no hay índi-
ces agrupados especificados para las restricciones UNIQUE.
Todas las columnas definidas en una restricción PRIMARY KEY deben establecerse como NOT NULL. Si no se especifica la po-
sibilidad de aceptar NULL, todas las columnas que participan en una restricción PRIMARY KEY tienen su posibilidad de aceptar NULL
establecida en NOT NULL.

RESTRICCIONES UNIQUE
Si no se especifica CLUSTERED o NONCLUSTERED para una restricción UNIQUE, de forma predeterminada se utiliza NON-
CLUSTERED.
Cada restricción UNIQUE genera un índice. El número de restricciones UNIQUE no puede hacer que el número de índices de la
tabla exceda de 249 índices no agrupados y 1 índice agrupado.

AÑO 2003 Página 48 de 96


SQL Lic. Gustavo Rei

RESTRICCIONES FOREIGN KEY


Cuando en la columna de una restricción FOREIGN KEY se introduce un valor distinto de NULL, el valor debe existir en la colum-
na a la que se hace referencia; de lo contrario, se devuelve un mensaje de error de infracción de clave externa.
Las restricciones FOREIGN KEY se aplican a la columna anterior a menos que se especifiquen columnas de origen.
Las restricciones FOREIGN KEY sólo pueden hacer referencia a las tablas de la misma base de datos en el mismo servidor. La
integridad referencial de las bases de datos cruzadas debe implementarse a través de desencadenadores.
Las restricciones FOREIGN KEY pueden hacer referencia a otras columnas de la misma tabla (una auto-referencia).
La cláusula REFERENCES de una restricción FOREIGN KEY en el nivel de columna puede enumerar sólo una columna de refe-
rencia, que debe tener el mismo tipo de datos que la columna en la que se define la restricción.
La cláusula REFERENCES de una restricción FOREIGN KEY en el nivel de tabla debe tener el mismo número de columnas de
referencia que el número de columnas de la lista de columnas de restricción. El tipo de datos de cada columna de referencia debe ser tam-
bién el mismo que la columna correspondiente de la lista de columnas.
Es posible que no se pueda especificar CASCADE si una columna del tipo timestamp forma parte de la clave externa o de la clave
a la que se hace referencia.
Se puede combinar CASCADE y NO ACTION en tablas que tengan relaciones referenciales entre sí. Si SQL Server encuentra
NO ACTION, termina y deshace las acciones CASCADE relacionadas. Cuando una instrucción DELETE hace que se combinen acciones
CASCADE y NO ACTION, todas las acciones CASCADE se aplican antes de que SQL Server compruebe si hay cláusulas NO ACTION.
Una tabla puede contener un máximo de 253 restricciones FOREIGN KEY.
Una tabla puede hacer referencia a un máximo de 253 tablas distintas en sus restricciones FOREIGN KEY.

EJEMPLOS
UTILIZAR RESTRICCIONES PRIMARY KEY
El ejemplo siguiente muestra la definición de columna de una restricción PRIMARY KEY con un índice agrupado sobre la columna
job_id de la tabla jobs (que permite al sistema suministrar el nombre de la restricción) en la base de datos de ejemplo pubs.

job_id smallint
PRIMARY KEY CLUSTERED

Este ejemplo muestra cómo se puede suministrar un nombre para la restricción PRIMARY KEY. Esta restricción se utiliza en la
columna emp_id de la tabla employee. Esta columna se basa en un tipo de datos definido por el usuario.

emp_id empid
CONSTRAINT PK_emp_id PRIMARY KEY NONCLUSTERED

UTILIZAR RESTRICCIONES FOREIGN KEY


Una restricción FOREIGN KEY se utiliza para hacer referencia a otra tabla. Las claves externas pueden ser claves de una única
columna o de varias columnas. El ejemplo siguiente muestra una restricción FOREIGN KEY de una única columna sobre la tabla employee
que hace referencia a la tabla jobs. Sólo se requiere la cláusula REFERENCES para una restricción FOREIGN KEY de una única columna.

job_id smallint NOT NULL


DEFAULT 1
REFERENCES jobs(job_id)

También puede utilizar la cláusula FOREIGN KEY de forma explícita y volver a formular el atributo de columna. Observe que no
es necesario que el nombre de la columna sea el mismo en ambas tablas.

FOREIGN KEY (job_id) REFERENCES jobs(job_id)

Las restricciones de claves de varias columnas se crean como restricciones de tabla. En la base de datos pubs, la tabla sales in-
cluye una restricción PRIMARY KEY multicolumna. Este ejemplo muestra cómo hacer referencia a esta clave desde otra tabla; el nombre
explícito de restricción es opcional.

CONSTRAINT FK_sales_backorder FOREIGN KEY (stor_id, ord_num, title_id)


REFERENCES sales (stor_id, ord_num, title_id)

AÑO 2003 Página 49 de 96


SQL Lic. Gustavo Rei

UTILIZAR RESTRICCIONES UNIQUE


Las restricciones UNIQUE se utilizan para exigir la unicidad en las columnas de claves no principales. Una columna de restricción
PRIMARY KEY incluye automáticamente una restricción de unicidad; sin embargo, una restricción UNIQUE puede aceptar valores NULL.
Este ejemplo muestra una columna llamada pseudonym de la tabla authors. Exige la restricción de que los pseudónimos de los autores
sean únicos.
pseudonym varchar(30) NULL
UNIQUE NONCLUSTERED
El ejemplo siguiente muestra una restricción UNIQUE creada en las columnas stor_name y city de la tabla stores, donde stor_id
es actualmente la restricción PRIMARY KEY; no debe haber dos almacenes iguales en la misma ciudad.

CONSTRAINT U_store UNIQUE NONCLUSTERED (stor_name, city)

UTILIZAR RESTRICCIONES CHECK


Este ejemplo muestra las restricciones realizadas a los valores introducidos en las columnas min_lvl y max_lvl de la tabla jobs.
Estas dos restricciones no tienen nombre:

CHECK (min_lvl >= 10)


y
CHECK (max_lvl <= 250)

Este ejemplo muestra una restricción con nombre con una restricción de patrón sobre los datos de caracteres introducidos en la
columna emp_id de la tabla employee.

CONSTRAINT CK_emp_id CHECK (emp_id LIKE '[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]'


OR emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]')

Este ejemplo especifica que pub_id debe estar en una lista específica o seguir un modelo dado. Esta restricción afecta a la co-
lumna pub_id de la tabla publishers.

CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')


OR pub_id LIKE '99[0-9][0-9]')

DEFINICIONES DE TABLAS COMPLETAS


El ejemplo siguiente muestra definiciones completas de tablas con las definiciones de restricciones de tres tablas (jobs, employee
y publishers) creadas en la base de datos pubs.

/* ************************** jobs table ************************** */


CREATE TABLE jobs
(
job_id smallint
IDENTITY(1,1)
PRIMARY KEY CLUSTERED,
job_desc varchar(50) NOT NULL
DEFAULT 'New Position - title not formalized yet',
min_lvl tinyint NOT NULL
CHECK (min_lvl >= 10),
max_lvl tinyint NOT NULL
CHECK (max_lvl <= 250)
)

/* ************************* employee table ************************* */


CREATE TABLE employee
(
emp_id empid
CONSTRAINT PK_emp_id PRIMARY KEY NONCLUSTERED
AÑO 2003 Página 50 de 96
SQL Lic. Gustavo Rei

CONSTRAINT CK_emp_id CHECK (emp_id LIKE


'[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]' or
emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]'),

/* Each employee ID consists of three characters that represent the employee's initials, followed by a five digit number ranging
from 10000 through 99999 and then the employee's gender (M or F). A (hyphen) - is acceptable for the middle initial. */

fname varchar(20) NOT NULL,


minit char(1) NULL,
lname varchar(30) NOT NULL,
job_id smallint NOT NULL
DEFAULT 1
/* Entry job_id for new hires. */
REFERENCES jobs(job_id),
job_lvl tinyint
DEFAULT 10,
/* Entry job_lvl for new hires. */
pub_id char(4) NOT NULL
DEFAULT ('9952')
REFERENCES publishers(pub_id),
/* By default, the Parent Company Publisher is the company to whom each employee reports. */
hire_date datetime NOT NULL
DEFAULT (getdate())
/* By default, the current system date is entered. */
)

/* ***************** publishers table ******************** */


CREATE TABLE publishers
(
pub_id char(4) NOT NULL
CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')
OR pub_id LIKE '99[0-9][0-9]'),
pub_name varchar(40) NULL,
city varchar(20) NULL,
state char(2) NULL,
country varchar(30) NULL DEFAULT('USA')
)

UTILIZAR UNA EXPRESIÓN PARA UNA COLUMNA CALCULADA


Este ejemplo ilustra el uso de una expresión ((low + high)/2) para calcular la columna calculada myavg.

CREATE TABLE mytable


(
low int,
high int,
myavg AS (low + high)/2
)

Las restricciones FOREIGN KEY sólo pueden hacer referencia a las columnas de las restricciones PRIMARY KEY o UNIQUE de
la tabla de referencia o a las columnas en UNIQUE INDEX de la tabla de referencia.

RESTRICCIONES CHECK
Una columna puede tener cualquier número de restricciones CHECK y la condición puede incluir varias expresiones lógicas com-
binadas con AND y OR. Varias restricciones CHECK para una columna se validan en el orden en que se crean.
La condición de búsqueda debe dar como resultado una expresión booleana y no puede hacer referencia a otra tabla.
AÑO 2003 Página 51 de 96
SQL Lic. Gustavo Rei

Una restricción CHECK en el nivel de columna sólo puede hacer referencia a la columna restringida, y una restricción CHECK en
el nivel de tabla sólo puede hacer referencia a columnas de la misma tabla.
Las restricciones CHECK y las reglas sirven para la misma función de validación de los datos durante las instrucciones INSERT y
DELETE.
Cuando hay una regla y una o más restricciones CHECK para una columna o columnas, se evalúan todas las restricciones

Alter table
La sentencia ALTER TABLE sirve para modificar la estructura de una tabla que ya existe. Mediante esta instrucción pode-mos
añadir columnas nuevas, eliminar columnas. Ten cuenta que cuando eliminamos una columna se pierden todos los datos al-macenados en
ella.
También nos permite crear nuevas restricciones o borrar algunas existentes. La sintaxis puede parecer algo complicada pero sa-
biendo el significado de las palabras reservadas la sentencia se aclara bastante; ADD (añade), ALTER (modifica), DROP (elimi-na), CO-
LUMN (columna), CONSTRAINT (restricción).
La sintaxis es la siguiente:

La sintaxis de restriccion1 es idéntica a la restricción1 de la sentencia CREATE TABLE, te la describimos a continuación, si tienes
alguna duda repasa la sentencia CREATE TABLE.

La sintaxis de restriccion2 es idéntica a la restricción2 de la sentencia CREATE TABLE, te la describimos a continuación, si tienes
alguna duda repasa la sentencia CREATE TABLE.

La cláusula ADD COLUMN (la palabra COLUMN es opcional) permite añadir una columna nueva a la tabla. Como en la creación
de tabla, hay que definir la columna indicando su nombre, tipo de datos que puede contener, y si lo queremos alguna res-tricción de valor no
nulo, clave primaria, clave foránea, e índice único, restriccion1 es opcional e indica una restricción de tipo 1 que afecta a la columna que
estamos definiendo.
Ejemplo:
ALTER TABLE tab1 ADD COLUMN col3 integer NOT NULL CONSTRAINT c1 UNIQUE
AÑO 2003 Página 52 de 96
SQL Lic. Gustavo Rei

Con este ejemplo estamos añadiendo a la tabla tab1 una columna llamada col3 de tipo entero, requerida (no admite nulos) y con
un índice sin duplicados llamado c1.
Cuando añadimos una columna lo mínimo que se puede poner sería:
ALTER TABLE tab1 ADD col3 integer
En este caso la nueva columna admite valores nulos y duplicados.
Para añadir una nueva restricción en la tabla podemos utilizar la cláusula ADD restriccion2 (ADD CONSTRAINT...).
Ejemplo:
ALTER TABLE tab1 ADD CONSTRAINT c1 UNIQUE (col3)
Con este ejemplo estamos añadiendo a la tabla tab1 un índice único (sin duplicados) llamado c1 sobre la columna col3.
Para borrar una columna basta con utilizar la cláusula DROP COLUMN (COLUMN es opcional) y el nombre de la columna que
queremos borrar, se perderán todos los datos almacenados en la columna.
Ejemplo:
ALTER TABLE tab1 DROP COLUMN col3
También podemos escribir:
ALTER TABLE tab1 DROP col3
El resultado es el mismo, la columna col3 desaparece de la tabla tab1.
Para borrar una restricción basta con utilizar la cláusula DROP CONSTRAINT y el nombre de la restricción que queremos borrar,
en este caso sólo se elimina la definición de la restricción pero los datos almacenados no se modifican ni se pierden.
Ejemplo:
ALTER TABLE tab1 DROP CONSTRAINT c1
Con esta sentencia borramos el índice c1 creado anteriormente pero los datos de la columna col3 no se ven afectados por el
cambio.

DROP TABLE
La sentencia DROP TABLE sirve para eliminar una tabla. No se puede eliminar una tabla si está abierta, tampoco la podemos
eliminar si el borrado infringe las reglas de integridad referencial (si interviene como tabla padre en una relación y tiene registros relaciona-
dos).
La sintaxis es la siguiente:

Ejemplo:
DROP TABLE tab1
Elimina de la base de datos la tabla tab1.

CREATE INDEX
La sentencia CREATE INDEX sirve para crear un índice sobre una o varias columnas de una tabla.

La sintaxis es la siguiente:

nbindi: nombre del índice que estamos definiendo. En una tabla no pueden haber dos índices con el mismo nombre de lo contrario
da error.
nbtabla: nombre de la tabla donde definimos el índice. A continuación entre paréntesis se indica la composición del índice (las co-
lumnas que lo forman).
nbcol: nombre de la columna que indexamos. Después del nombre de la columna podemos indicar cómo queremos que se orde-
nen las filas según el índice mediante las cláusulas ASC/DESC.
ASC: la cláusula ASC es la que se asume por defecto e indica que el orden elegido para el índice es ascendente (en orden alfa-
bético si la columna es de tipo texto, de menor a mayor si es de tipo numérico, en orden cronológico si es de tipo fecha).
DESC: indica orden descendente, es decir el orden inverso al ascendente.

AÑO 2003 Página 53 de 96


SQL Lic. Gustavo Rei

Podemos formar un índice basado en varias columnas, en este caso después de indicar la primera columna con su orden, se es-
cribe una coma y la segunda columna también con su orden, así sucesivamente hasta indicar todas las columnas que forman el índice.
Opcionalmente se pueden indicar las cláusulas:
WITH PRIMARY indica que el índice define la clave principal de la tabla, si la tabla ya tiene una clave principal, la sentencia
CREATE INDEX dará error.
WITH DISALLOW NULL indica que no permite valores nulos en las columnas que forman el índice.
WITH IGNORE NULL indica que las filas que tengan valores nulos en las columnas que forman el índice se ignoran, no aparecen
cuando recuperamos las filas de la tabla utilizando ese índice.

Ejemplo:
CREATE UNIQUE INDEX ind1 ON clientes (provincia, poblacion ASC, fecha_nacimiento DESC)
Crea un índice llamado ind1 sobre la tabla clientes formado por las columnas provincia, población y fecha_nacimiento. Este ín-
dice permite tener ordenadas las filas de la tabla clientes de forma que aparezcan los clientes ordenados por provincia, dentro de la misma
provincia por población y dentro de la misma población por edad y del más joven al más mayor.
Al añadir la cláusula UNIQUE el índice no permitirá duplicados por lo que no podría tener dos clientes con la misma fecha de na-
cimiento en la misma población y misma provincia, para evitar el poblema sería mejor utilizar:
CREATE INDEX ind1 ON clientes (provincia, poblacion ASC, fecha_nacimiento DESC)

DROP INDEX
La sentencia DROP INDEX sirve para eliminar un índice de una tabla. Se elimina el índice pero no las columnas que lo for-man.
La sintaxis es la siguiente:

Ejemplo:
DROP INDEX ind1 ON clientes
Elimina el índice que habíamos creado en el ejemplo anterior.

AÑO 2003 Página 54 de 96


SQL Lic. Gustavo Rei

En el presente capítulo se ampliarán temas ya explicados, incorporando nuevas sentencias, bibliografías, ejemplos y ejercicios.

Clustered | nonclustered:
Son palabras clave que indican que se ha creado un índice agrupado o no agrupado para la restricción PRIMARY KEY o UNI-
QUE. De forma predeterminada, el valor de las restricciones PRIMARY KEY es CLUSTERED, y el de las restricciones UNIQUE es NON-
CLUSTERED. Sólo se puede especificar CLUSTERED para una única restricción de una instrucción CREATE TABLE. Si especifica CLUS-
TERED para una restricción UNIQUE y especifica también una restricción PRIMARY KEY, el valor predeterminado de PRIMARY KEY es
NONCLUSTERED.

Funciones11 de fecha
Las funciones de fecha se utilizan para mostrar información acerca de fechas y horas. Se usan para el tratamiento de valores da-
tetime y smalldatetime y para realizar operaciones aritméticas en los mismos. Las funciones de fecha se pueden usar en cualquier parte
donde se pueda usar una expresión.
SQL Server reconoce una amplia variedad de formatos de entrada de datos datetime. Puede usar la instrucción SET DATEFOR-
MAT para establecer el orden de las partes de la fecha (mes, día y año) para introducir datos datetime o smalldatetime. Cuando escriba
valores datetime o smalldatetime, inclúyalos entre comillas simples.
Estas funciones escalares realizan una operación sobre un valor de fecha y hora de entrada, y devuelven un valor de cadena,
numérico o de fecha y hora.
Esta tabla presenta las funciones de fecha y hora y su propiedad determinista12.
Función Determinismo
DATEADD Determinista
DATEDIFF Determinista
DATENAME No determinista
DATEPART Determinista excepto cuando se utiliza como DATEPART (dw, date). La parte de la fecha correspondiente
al día de la semana (dw) depende del valor establecido por SET DATEFIRST, que indica el primer día de
la semana.
DAY Determinista
GETDATE No determinista
GETUTCDATE No determinista
MONTH Determinista
YEAR Determinista

DATEADD
Devuelve un valor datetime nuevo que se basa en la suma de un intervalo a la fecha especificada.
Sintaxis
DATEADD ( datepart , number, date )

11
Funciones : El lenguaje de programación Transact-SQL proporciona tres tipos de funciones: Funciones de conjunto de filas Se pueden utilizar como referencias a tablas

en una instrucción SQL. Funciones de agregado Operan sobre una colección de valores y devuelven un solo valor de resumen. Funciones escalares Operan sobre un valor y después

devuelven otro valor. Las funciones escalares se pueden utilizar donde la expresión sea válida. Esta tabla clasifica las funciones escalares.
12
Funciones deterministas y no deterministas : Todas las funciones son deterministas o no deterministas: Las funciones deterministas siempre devuelven el mismo resultado

cada vez que son llamadas con un conjunto específico de valores de entrada. Las funciones no deterministas podrían devolver resultados diferentes cada vez que son llamadas con un

conjunto específico de valores de entrada. El determinismo de una función consiste en si la función es determinista o no determinista. Por ejemplo, la función integrada DATEADD es

determinista porque siempre devuelve el mismo resultado a cualquier conjunto dado de valores de argumento para sus tres parámetros. GETDATE no es determinista porque siempre se

invoca con el mismo argumento, aunque el valor que devuelve varía cada vez que se ejecuta. Las versiones anteriores de Microsoft SQL Server no tenían ninguna funcionalidad que

dependiese del determinismo de las funciones. En Microsoft SQL Server 2000, las funciones no deterministas no pueden especificarse en dos tipos de expresiones Transact-SQL: No se

puede crear un índice en una columna calculada si computed_column_expression hace referencia a alguna función no determinista. No se puede crear un índice agrupado en una vista si

ésta hace referencia a funciones no deterministas. Una de las propiedades que SQL Server registra para las funciones definidas por el usuario es si la función es determinista o no. Una

función no determinista definida por el usuario no se puede invocar mediante una vista o una columna calculada, si lo que se desea es crear un índice en la vista o en la columna calcula-

da.

AÑO 2003 Página 55 de 96


SQL Lic. Gustavo Rei

Parte de la Abreviatu-
fecha ras
Year yy, yyyy
quarter qq, q
Month mm, m
dayofyear dy, y
Day dd, d
Week wk, ww
Hour hh
minute mi, n
second ss, s
millisecond ms
Tipos devueltos
Devuelve datetime, o smalldatetime si el argumento date es smalldatetime.

Ejemplos
En este ejemplo se imprime una lista de un marco de tiempo de los títulos de la base de datos pubs. Este marco de tiempo repre-
senta la fecha de la publicación más 21 días.

SELECT DATEADD(day, 21, pubdate) AS timeframe FROM titles

El siguiente es el conjunto de resultados:

timeframe ---------------------------
Jul 3 1991 12:00AM
Jun 30 1991 12:00AM
Jul 21 1991 12:00AM
Jul 13 1991 12:00AM
Jun 30 1991 12:00AM

DATEDIFF
Devuelve el número de límites de fecha y hora que hay entre dos fechas especificadas.

Sintaxis
DATEDIFF ( datepart , startdate , enddate )

Startdate : Es la fecha de comienzo para el cálculo. startdate es una expresión que devuelve un valor datetime o smalldatetime, o
una cadena de caracteres con formato de fecha.

Enddate : Es la fecha final para el cálculo. enddate es una expresión que devuelve un valor datetime o smalldatetime, o una ca-
dena de caracteres con formato de fecha.
Tipos devueltos integer

Observaciones : startdate se resta de enddate. Si startdate es posterior a enddate, se devuelve un valor negativo.

DATEDIFF produce un error si el resultado está fuera del intervalo de valores enteros. Para los milisegundos, el número máximo
es de 24 días, 20 horas, 31 minutos y 23,647 segundos. Para los segundos, el número máximo es 68 años.
El método para contar los límites que hay, tales como minutos, segundos, y milisegundos, hace que el resultado dado por DATE-
DIFF sea coherente en todos los tipos de datos. El resultado es un valor entero con signo igual al número de límites datepart que hay entre
la primera y la segunda fecha. Por ejemplo, el número de semanas que hay entre el domingo 4 de enero y el sábado 11 de enero es 1.

Ejemplos

AÑO 2003 Página 56 de 96


SQL Lic. Gustavo Rei

En este ejemplo se determina la diferencia en días entre la fecha actual y la fecha de publicación de los títulos de la base de datos
pubs.

SELECT DATEDIFF(day, pubdate, getdate()) AS no_of_days


FROM titles

DATENAME
Devuelve una cadena de caracteres que representa la parte de la fecha especificada de la fecha especificada.

Sintaxis : DATENAME ( datepart , date )


Tipos devueltos :nvarchar
Observaciones: SQL Server convierte automáticamente entre valores carácter y datetime cuando es necesario; por ejemplo,
cuando compara un valor carácter con un valor datetime.

Ejemplos
En este ejemplo se extrae el nombre del mes de la fecha devuelta por GETDATE.

SELECT DATENAME(month, getdate()) AS 'Month Name'

El siguiente es el conjunto de resultados:


Month Name
February

DATEPART
Devuelve un entero que representa la parte de la fecha especificada de la fecha indicada.
Sintaxis : DATEPART ( datepart , date )

Observaciones : Las funciones DAY, MONTH y YEAR son sinónimos de DATEPART(dd, date), DATEPART(mm, date) y DATE-
PART(yy, date), respectivamente.

Ejemplos
La función GETDATE devuelve la fecha actual; sin embargo, la fecha completa no es siempre la información que se necesita para
la comparación (a menudo, sólo se compara una parte de la fecha). En este ejemplo se muestra la salida de GETDATE y la de DATEPART.

SELECT GETDATE() AS 'Current Date'


GO

El siguiente es el conjunto de resultados:

Current Date ---------------------------


Feb 18 1998 11:46PM

SELECT DATEPART(month, GETDATE()) AS 'Month Number'


GO

El siguiente es el conjunto de resultados:

Month Number ------------


2

En este ejemplo se supone que la fecha es el 29 de mayo.

SELECT DATEPART(month, GETDATE())


El siguiente es el conjunto de resultados:

AÑO 2003 Página 57 de 96


SQL Lic. Gustavo Rei

----------- 5

(1 row(s) affected)

En este ejemplo, la fecha se especifica como un número. Observe que SQL interpreta 0 como el 1 de enero de 1900.

SELECT DATEPART(m, 0), DATEPART(d, 0), DATEPART(yy, 0)

El siguiente es el conjunto de resultados:


----- ------ ------
1 1 1900

DAY
Devuelve un entero que representa la parte del día de la fecha especificada.

Sintaxis : DAY ( date )

Ejemplos
En este ejemplo se devuelve el número del día de la fecha 12/03/1998.

SELECT DAY('03/12/1998') AS 'Day Number'


GO

El siguiente es el conjunto de resultados:

Day Number
------------
12

En este ejemplo, la fecha se especifica como un número. Observe que Microsoft® SQL Server™ interpreta el 0 como el 1 de ene-
ro de 1900.

SELECT MONTH(0), DAY(0), YEAR(0)

Éste es el conjunto de resultados:

----- ------ ------


1 1 1900

SUBSTRING
Devuelve parte de una expresión de caracteres, binaria, de texto o de imagen.

SINTAXIS

SUBSTRING ( expression , start , length )

ARGUMENTOS
expression
Es una cadena de caracteres, cadena binaria, texto, imagen, columna o expresión que incluye una columna. No deben usarse ex-
presiones que incluyan funciones de agregado.

start
Es un entero que especifica el punto en que comienza la subcadena.

length
AÑO 2003 Página 58 de 96
SQL Lic. Gustavo Rei

Es un entero que especifica la longitud de la subcadena (el número de caracteres o bytes que se devuelven).

Nota Debido a que start y length especifican el número de bytes cuando SUBSTRING se utiliza con datos de tipo text, los datos
DBCS, por ejemplo los de Kanji, pueden causar que haya caracteres divididos al comienzo o al final del resultado. Este comportamiento es
coherente con la forma en que READTEXT controla DBCS. Sin embargo, debido al resultado poco habitual, es aconsejable utilizar ntext en
lugar de text para los caracteres DBCS.

EJEMPLOS
UTILIZAR SUBSTRING CON UNA CADENA DE CARACTERES
En el ejemplo siguiente se muestra cómo obtener parte de una cadena de caracteres. En la tabla authors, esta consulta obtiene
los apellidos en una columna y sólo la primera inicial en la segunda columna.

SELECT au_lname, SUBSTRING(au_fname, 1, 1)


FROM authors
ORDER BY au_lname

El siguiente es el conjunto de resultados:


au_lname
---------------------------------------- -
Bennet A
Blotchet-Halls R
Carson C
DeFrance M
del Castillo I
...
Yokomoto A

(23 row(s) affected)

He aquí cómo mostrar el segundo, tercer y cuarto caracteres de la constante de cadena abcdef.
SELECT x = SUBSTRING('abcdef', 2, 3)
El siguiente es el conjunto de resultados:
x
----------
bcd
(1 row(s) affected)

UTILIZAR SUBSTRING CON DATOS DE TIPO TEXT, NTEXT E IMAGE


El ejemplo siguiente muestra cómo obtener los primeros 200 caracteres a partir de cada columna de datos de tipo text e image en
la tabla publishers de la base de datos pubs. Los datos de tipo text se obtienen como varchar y los de tipo image como varbinary.

SELECT pub_id, SUBSTRING(logo, 1, 10) AS logo, SUBSTRING(pr_info, 1, 10) AS pr_info


FROM pub_info
WHERE pub_id = '1756'

El siguiente es el conjunto de resultados:

pub_id logo pr_info


------ ---------------------- ----------
1756 0x474946383961E3002500 This is sa

(1 row(s) affected)

AÑO 2003 Página 59 de 96


SQL Lic. Gustavo Rei

El ejemplo siguiente muestra el efecto de SUBSTRING en los datos de tipo text y ntext. En primer lugar se crea una nueva tabla
en la base de datos pubs con el nombre npr_info. A continuación, se crea la columna pr_info en la tabla npr_info con los 80 primeros carac-
teres de la columna pub_info.pr_info y se agrega un ü como primer carácter. Por último, INNER JOIN obtiene todos los números de identifi-
cación de las editoriales y una SUBSTRING con las columnas de tipo text y ntext con la información de la editorial.

SELECT table_name FROM INFORMATION_SCHEMA.TABLES


WHERE table_name = 'npub_info'
DROP TABLE npub_info

-- Create npub_info table in pubs database. Borrowed from instpubs.sql.


CREATE TABLE npub_info
(
pub_id char(4) NOT NULL
REFERENCES publishers(pub_id)
CONSTRAINT UPKCL_npubinfo PRIMARY KEY CLUSTERED,
pr_info ntext NULL
)

-- Fill the pr_info column in npub_info with international data.


RAISERROR('Now at the inserts to pub_info...',0,1)

INSERT npub_info VALUES('0736', N'üThis is sample text data for New Moon Books, publisher 0736 in the pubs database')
INSERT npub_info values('0877', N'üThis is sample text data for Binnet & Hardley, publisher 0877 in the pubs databa')
INSERT npub_info values('1389', N'üThis is sample text data for Algodata Infosystems, publisher 1389 in the pubs da')
INSERT npub_info values('9952', N'üThis is sample text data for Scootney Books, publisher 9952 in the pubs database')
INSERT npub_info values('1622', N'üThis is sample text data for Five Lakes Publishing, publisher 1622 in the pubs d')
INSERT npub_info values('1756', N'üThis is sample text data for Ramona Publishers, publisher 1756 in the pubs datab')
INSERT npub_info values('9901', N'üThis is sample text data for GGG&G, publisher 9901 in the pubs database. GGG&G i')
INSERT npub_info values('9999', N'üThis is sample text data for Lucerne Publishing, publisher 9999 in the pubs data')

-- Join between npub_info and pub_info on pub_id.


SELECT pr.pub_id, SUBSTRING(pr.pr_info, 1, 35) AS pr_info,
SUBSTRING(npr.pr_info, 1, 35) AS npr_info
FROM pub_info pr INNER JOIN npub_info npr
ON pr.pub_id = npr.pub_id
ORDER BY pr.pub_id ASC

Conversión de tipos de datos


En Transact-SQL, hay dos niveles posibles de conversión de tipos de datos:
Cuando los datos de un objeto se mueven a, se comparan o se combinan con los datos de otro objeto, puede que sea necesario
convertir los datos desde el tipo de datos de un objeto al tipo de datos del otro.
Cuando los datos de una columna de resultados, un código de retorno o un parámetro de salida de Transact-SQL se mueven a
una variable de programa, deben ser convertidos desde el tipo de datos de Microsoft® SQL Server™ al tipo de datos de la variable.
Hay dos categorías de conversiones de tipo de datos:
Las conversiones implícitas son invisibles para el usuario.
SQL Server convierte automáticamente los datos desde un tipo de datos al otro. Por ejemplo, si un smallint se compara con un int,
el smallint se convierte implícitamente a int antes de realizarse la comparación.

Las conversiones explícitas utilizan las funciones CAST o CONVERT.


Las funciones CAST y CONVERT convierten un valor (una variable local, una columna u otra expresión) de un tipo de datos a
otro. Por ejemplo, la siguiente función CAST convierte el valor numérico $157.27 a una cadena de caracteres '$157.27':

CAST ( $157.27 AS VARCHAR(10) )


CAST se basa en el estándar SQL-92 y se prefiere antes que CONVERT.

AÑO 2003 Página 60 de 96


SQL Lic. Gustavo Rei

Cuando se realizan conversiones desde el tipo de datos de un objeto SQL Server a otro, no se admiten algunas conversiones im-
plícitas y explícitas de tipos de datos. Por ejemplo, un valor nchar no se puede convertir de ninguna forma a un valor image. Un nchar sólo
se puede convertir a binary con una conversión explícita, mientras que la conversión implícita a binary no se admite. Un nchar puede ser
convertido a nvarchar explícita o implícitamente.
Cuando trata tipos de datos sql_variant, SQL Server admite conversiones implícitas de objetos con otros tipos de datos al tipo
sql_variant. No obstante, SQL Server no admite conversiones implícitas de datos sql_variant a un objeto con otro tipo de datos.
Para obtener más información acerca de las conversiones admitidas entre objetos de SQL Server, consulte CAST y CONVERT.
Cuando se realiza una conversión entre una variable de aplicación y una columna de conjunto de resultados, código de retorno,
parámetro o marcador de parámetro de SQL Server, la interfaz de programación de aplicaciones de base de datos define cuáles son las
conversiones de tipos de datos admitidas.

CAST Y CONVERT
Convierten explícitamente una expresión de un tipo de datos en otro. CAST y CONVERT proporcionan funciones similares.
Sintaxis
Uso de CAST:

CAST ( expression AS data_type )

Uso de CONVERT:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

Argumentos

data_type

Es el tipo de datos de destino proporcionado por el sistema, incluido bigint y sql_variant. No se pueden utilizar tipos de datos defi-
nidos por el usuario. Para obtener más información acerca de los tipos de datos disponibles, consulte Tipos de datos.

length
Es un parámetro opcional de los tipos de datos nchar, nvarchar, char, varchar, binary o varbinary.
style
Es el estilo del formato de fecha que se utiliza para convertir datos datetime o smalldatetime en datos de cadenas de caracteres
(tipos de datos nchar, nvarchar, char, varchar, nchar o nvarchar), o el formato de cadena cuando se convierten datos float, real, money o
smallmoney en datos de cadenas de caracteres (tipos de datos nchar, nvarchar, char, varchar, nchar o nvarchar).
SQL Server acepta el formato de fecha en estilo árabe, utilizando el algoritmo kuwaití.
En la siguiente tabla, las dos columnas de la izquierda representan los valores de style para la conversión de datetime o smallda-
tetime en cadenas de caracteres. Agregue 100 al valor de style para obtener el año con cuatro cifras, incluido el siglo (yyyy).

SELECT SUBSTRING(title, 1, 25) AS Title, CAST(ytd_sales AS char(2))


FROM titles
WHERE type = 'trad_cook'

El siguiente es el conjunto de resultados:


Title
------------------------- --
Onions, Leeks, and Garlic *
Fifty Years in Buckingham *
Sushi, Anyone? *

(3 row(s) affected)

Cuando se convierten tipos de datos que tienen un número diferente de posiciones decimales, el valor queda recortado hasta la
cifra de mayor precisión. Por ejemplo, el resultado de SELECT CAST(10,6496 AS int) es 10.
Cuando se realiza una conversión entre tipos de datos donde el tipo de datos destino tiene menos posiciones decimales que el ti-
po de datos origen, el valor se redondea. Por ejemplo, el resultado de CAST(10,3496847 AS money) es $10,3497.
AÑO 2003 Página 61 de 96
SQL Lic. Gustavo Rei

SQL Server devuelve un mensaje de error cuando los datos no numéricos char, nchar, varchar o nvarchar se convierten a int,
float, numeric o decimal. SQL Server también devuelve un error cuando se convierte una cadena vacía (" ") a numeric o decimal.
Usar datos de cadenas Binary
Cuando se convierten datos binary o varbinary en datos de cadena de caracteres y se especifica un número impar de valores a
continuación de la x, SQL Server agrega un 0 (cero) después de la x para tener un número par de valores.
Los datos de tipo binary se componen de los caracteres del 0 al 9 y de la A a la F (o de la a a la f), en grupos de dos caracteres
cada uno. Las cadenas de tipo binary tienen que estar precedidas por 0x. Por ejemplo, para representar FF, escriba 0xFF. El valor máximo
es un valor de tipo binary de 8000 bytes, cada uno de los cuales es FF. Los tipos de datos binary no sólo se utilizan para guardar datos
hexadecimales, sino también para almacenar patrones de bits. Puede que las conversiones y cálculos de números hexadecimales almace-
nados como datos de tipo binary no sean confiables.
Cuando se especifica la longitud de un tipo de datos binary, cada dos caracteres cuentan como uno. La longitud 10 significa que
hay 10 grupos de dos caracteres.
Las cadenas de tipo binary vacías, representadas como 0x, se pueden almacenar como datos de tipo binary.

EJEMPLOS
Utilizar CAST y CONVERT
Los dos ejemplos devuelven los títulos de aquellos libros que tienen un 3 en la primera cifra de las ventas anuales y convierten
ytd_sales en char(20).

-- Use CAST.
SELECT SUBSTRING(title, 1, 30) AS Title, ytd_sales Title ytd_sales
FROM titles ------------------------------ -----------
WHERE CAST(ytd_sales AS char(20)) LIKE '3%' Cooking with Computers: Surrep 3876
Computer Phobic AND Non-Phobic 375
-- Use CONVERT. Emotional Security: A New Algo 3336
SELECT SUBSTRING(title, 1, 30) AS Title, ytd_sales Onions, Leeks, and Garlic: Coo 375
FROM titles
WHERE CONVERT(char(20), ytd_sales) LIKE '3%' (4 row(s) affected)

Éste es el conjunto de resultados (de las consultas):


Utilizar CAST con operadores aritméticos
Este ejemplo calcula una única columna (Copies) dividiendo las ventas anuales totales (ytd_sales) por el precio individual del libro
(price). El resultado se convierte en el tipo de datos int después de redondearlo al número entero más próximo.

SELECT CAST(ROUND(ytd_sales/price, 0) AS int) AS 'Copies'


FROM titles

El siguiente es el conjunto de resultados:

Copies NULL
------ 17
205 187
324 16
6262 204
205 418
102 18
7440 1263
NULL 273
383
205 (18 row(s) affected)

Utilizar CAST para concatenar


Este ejemplo concatena expresiones que no son de texto ni tipo binary mediante la función de conversión de tipos de datos
CAST.
AÑO 2003 Página 62 de 96
SQL Lic. Gustavo Rei

SELECT 'The price is ' + CAST(price AS varchar(12))


FROM titles
WHERE price > 10.00

El siguiente es el conjunto de resultados: The price is 21.59


The price is 10.95
------------------ The price is 19.99
The price is 19.99 The price is 20.95
The price is 11.95 The price is 11.95
The price is 19.99 The price is 14.99
The price is 19.99
The price is 22.95 (12 row(s) affected)
The price is 20.00

Utilizar CAST para obtener texto más legible


Este ejemplo utiliza CAST en la lista seleccionada para convertir la columna title en una columna de tipo char(50), para que los
resultados sean más legibles.

SELECT CAST(title AS char(50)), ytd_sales


FROM titles
WHERE type = 'trad_cook'
El siguiente es el conjunto de resultados:

ytd_sales
-------------------------------------------------- ---------
Onions, Leeks, and Garlic: Cooking Secrets of the 375
Fifty Years in Buckingham Palace Kitchens 15096
Sushi, Anyone? 4095
(3 row(s) affected)

Utilizar CAST con una cláusula LIKE


Este ejemplo convierte una columna de tipo int (la columna ytd_sales) en una columna de tipo char(20) para poder utilizarla en
una cláusula LIKE.

SELECT title, ytd_sales


FROM titles
WHERE CAST(ytd_sales AS char(20)) LIKE '15%'
AND type = 'trad_cook'

El siguiente es el conjunto de resultados:

title ytd_sales
------------------------------------------------------------ -----------
Fifty Years in Buckingham Palace Kitchens 15096

(1 row(s) affected)

CASE
Evalúa una lista de condiciones y devuelve como resultado una de las distintas expresiones posibles.

CASE tiene dos formatos:

La función CASE sencilla compara una expresión con un conjunto de expresiones sencillas para determinar el resultado.
La función CASE de búsqueda evalúa un conjunto de expresiones booleanas para determinar el resultado.

AÑO 2003 Página 63 de 96


SQL Lic. Gustavo Rei

Ambos formatos aceptan el argumento ELSE opcional.

Función CASE sencilla:


Evalúa input_expression y después, en el orden especificado, evalúa input_expression = when_expression por cada cláusula
WHEN.
Devuelve el valor de la expresión result_expression de la primera comparación (input_expression = when_expression) cuyo resul-
tado sea TRUE.
Si ninguna comparación input_expression = when_expression da como resultado TRUE, SQL Server devuelve el valor de la ex-
presión else_result_expression, si es que se especificó la cláusula ELSE, o un valor NULL en caso contrario.
Función CASE de búsqueda:
Se evalúa, en el orden especificado, la expresión Boolean_expression de cada cláusula WHEN.
Devuelve el valor de la expresión result_expression de la primera expresión Boolean_expression cuya evaluación dé como resul-
tado TRUE.
Si ninguna Boolean_expression es TRUE, SQL Server devuelve else_result_expression, si se especifica la cláusula ELSE, o un
valor NULL si no se especifica la cláusula ELSE.

EJEMPLOS
Utilizar una instrucción SELECT con una función CASE sencilla
En una instrucción SELECT, una función CASE sencilla sólo permite una comprobación de igualdad; no se pueden hacer otras
comparaciones. Este ejemplo utiliza la función CASE para modificar la presentación de una clasificación de libros con el fin de hacerla más
comprensible.
SELECT Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
END,
CAST(title AS varchar(25)) AS 'Shortened Title',
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY type, price
COMPUTE AVG(price) BY type

El siguiente es el conjunto de resultados: Category Shortened Title Price


Category Shortened Title Price ------------------- ------------------------- --------------------------
------------------- ------------------------- -------------------------- Popular Computing Secrets of Silicon Valley 20.00
Business You Can Combat Computer S 2.99 Popular Computing But Is It User Friendly? 22.95
Business Cooking with Computers: S 11.95
Business The Busy Executive's Data 19.99 avg
Business Straight Talk About Compu 19.99 ==========================
avg ========================== 21.48
13.73
Category Shortened Title Price Category Shortened Title Price
------------------- ------------------------- -------------------------- ------------------- ------------------------- --------------------------
Modern Cooking The Gourmet Microwave 2.99 Psychology Life Without Fear 7.00
Modern Cooking Silicon Valley Gastronomi 19.99 Psychology Emotional Security: A New 7.99
Psychology Is Anger the Enemy? 10.95
avg Psychology Prolonged Data Deprivatio 19.99
========================== Psychology Computer Phobic AND Non-P 21.59
11.49 avg
==========================
AÑO 2003 Página 64 de 96
SQL Lic. Gustavo Rei

13.50
avg
Category Shortened Title Price ==========================
------------------- ------------------------- -------------------------- 15.96
Traditional Cooking Fifty Years in Buckingham 11.95
Traditional Cooking Sushi, Anyone? 14.99 (21 row(s) affected)
Traditional Cooking Onions, Leeks, and Garlic 20.95
Utilizar una instrucción SELECT con una función CASE sencilla y otra de búsqueda
En una instrucción SELECT, la función CASE de búsqueda permite sustituir valores en el conjunto de resultados basándose en
los valores de comparación. Este ejemplo presenta el precio (una columna money) como comentario basado en el intervalo de precios de
cada libro.

USE pubs
GO
SELECT 'Price Category' =
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
ELSE 'Expensive book!'
END,
CAST(title AS varchar(20)) AS 'Shortened Title'
FROM titles
ORDER BY price
GO

El siguiente es el conjunto de resultados:


Coffee Table Title Sushi, Anyone?
Price Category Shortened Title Coffee Table Title Prolonged Data Depri
--------------------- -------------------- Coffee Table Title Silicon Valley Gastr
Not yet priced Net Etiquette Coffee Table Title Straight Talk About
Not yet priced The Psychology of Co Coffee Table Title The Busy Executive's
Very Reasonable Title The Gourmet Microwav Expensive book! Secrets of Silicon V
Very Reasonable Title You Can Combat Compu Expensive book! Onions, Leeks, and G
Very Reasonable Title Life Without Fear Expensive book! Computer Phobic And
Very Reasonable Title Emotional Security: Expensive book! But Is It User Frien
Coffee Table Title Is Anger the Enemy?
Coffee Table Title Cooking with Compute (18 row(s) affected)
Coffee Table Title Fifty Years in Bucki

Utilizar CASE con SUBSTRING y SELECT


Este ejemplo utiliza CASE y THEN para generar una lista de autores, los números de identificación de los libros y los tipos de li-
bros que cada autor ha escrito.

USE pubs
SELECT SUBSTRING((RTRIM(a.au_fname) + ' '+
RTRIM(a.au_lname) + ' '), 1, 25) AS Name, a.au_id, ta.title_id,
Type =
CASE
WHEN SUBSTRING(ta.title_id, 1, 2) = 'BU' THEN 'Business'
WHEN SUBSTRING(ta.title_id, 1, 2) = 'MC' THEN 'Modern Cooking'
WHEN SUBSTRING(ta.title_id, 1, 2) = 'PC' THEN 'Popular Computing'
WHEN SUBSTRING(ta.title_id, 1, 2) = 'PS' THEN 'Psychology'
WHEN SUBSTRING(ta.title_id, 1, 2) = 'TC' THEN 'Traditional Cooking'
END
FROM titleauthor ta JOIN authors a ON ta.au_id = a.au_id
AÑO 2003 Página 65 de 96
SQL Lic. Gustavo Rei

El siguiente es el conjunto de resultados: Charlene Locksley 486-29-1786 PS7777 Psychology


Reginald Blotchet-Halls 648-92-1872 TC4203 Traditional
Name au_id title_id Type Cooking
------------------------- ----------- -------- ------------------- Akiko Yokomoto 672-71-3249 TC7777 Traditional Cook-
Johnson White 172-32-1176 PS3333 Psychology ing
Marjorie Green 213-46-8915 BU1032 Business Innes del Castillo 712-45-1867 MC2222 Modern Cooking
Marjorie Green 213-46-8915 BU2075 Business Michel DeFrance 722-51-5454 MC3021 Modern Cooking
Cheryl Carson 238-95-7766 PC1035 Popular Comput- Stearns MacFeather 724-80-9391 BU1111 Business
ing Stearns MacFeather 724-80-9391 PS1372 Psychology
Michael O'Leary 267-41-2394 BU1111 Business Livia Karsen 756-30-7391 PS1372 Psychology
Michael O'Leary 267-41-2394 TC7777 Traditional Cook- Sylvia Panteley 807-91-6654 TC3218 Traditional Cooking
ing Sheryl Hunter 846-92-7186 PC8888 Popular Computing
Dean Straight 274-80-9391 BU7832 Business Anne Ringer 899-46-2035 MC3021 Modern Cooking
Abraham Bennet 409-56-7008 BU1032 Business Anne Ringer 899-46-2035 PS2091 Psychology
Ann Dull 427-17-2319 PC8888 Popular Computing Albert Ringer 998-72-3567 PS2091 Psychology
Burt Gringlesby 472-27-2349 TC7777 Traditional Cooking Albert Ringer 998-72-3567 PS2106 Psychology
Charlene Locksley 486-29-1786 PC9999 Popular Comput-
ing (25 row(s) affected)

REVERSE
Devuelve invertida una expresión de carácter.
Ejemplos
En este ejemplo se devuelve el nombre de todos los autores con los caracteres invertidos.

SELECT REVERSE(au_fname)
FROM authors
ORDER BY au_fname

El siguiente es el conjunto de resultados:


--------------------
maharbA
okikA
naeD
kriD
rehtaeH
sennI
nosnhoJ

RIGHT
Devuelve la parte de una cadena de caracteres que comienza en el número de caracteres especificado en integer_expression a
partir de la derecha.

Ejemplos
En este ejemplo se devuelven los cinco caracteres que se encuentran más a la derecha del nombre de cada autor.

SELECT RIGHT(au_fname, 5)
FROM authors
ORDER BY au_fname

El siguiente es el conjunto de resultados:


------------------
raham
Akiko
lbert
AÑO 2003 Página 66 de 96
SQL Lic. Gustavo Rei

RTRIM
Devuelve una cadena de caracteres después de truncar todos los espacios en blanco a la derecha
Sintaxis
RTRIM ( character_expression )

Argumentos
character_expression

Es una expresión de datos de tipo carácter. character_expression puede ser una constante, una variable o una columna de datos
de tipo carácter o binarios.

LTRIM
Devuelve una expresión de caracteres después de quitar los espacios en blanco a la izquierda.

Sintaxis
LTRIM ( character_expression )

LOWER
Devuelve una expresión de caracteres después de convertir a minúsculas los datos de caracteres que estén en mayúsculas.

Sintaxis
LOWER ( character_expression )

LEFT
Devuelve la parte de una cadena de caracteres que comienza en un número de caracteres especificado a partir de la izquierda.

Sintaxis
LEFT ( character_expression , integer_expression )

Utilizar LEFT con una columna


Este ejemplo devuelve los cinco caracteres situados más a la izquierda de cada título de libro.

SELECT LEFT(title, 5)
FROM titles
ORDER BY title_id

El siguiente es el conjunto de resultados:


-----
The B
Cooki
You C
Strai

Utilizar LEFT con una cadena de caracteres


Este ejemplo utiliza LEFT para obtener los dos caracteres situados más a la izquierda de la cadena de caracteres abcdefg.

SELECT LEFT('abcdefg',2)

El siguiente es el conjunto de resultados:


--
ab

AÑO 2003 Página 67 de 96


SQL Lic. Gustavo Rei

ATN2
Devuelve el ángulo, en radianes, cuya tangente es un valor entre las dos expresiones float dadas (denominado también arcotan-
gente).

Sintaxis
ATN2 ( float_expression , float_expression )

UPPER
Devuelve una expresión de tipo carácter con datos de carácter en minúscula convertidos a mayúscula.

Sintaxis
UPPER ( character_expression )

REPLICATE
Repite una expresión de caracteres un número especificado de veces.

Sintaxis
REPLICATE ( character_expression , integer_expression )

Ejemplos
Utilizar REPLICATE
En este ejemplo se duplica el nombre de cada autor dos veces.

SELECT REPLICATE(au_fname, 2)
FROM authors
ORDER BY au_fname

El siguiente es el conjunto de resultados:

----------------------
AbrahamAbraham
AkikoAkiko
AlbertAlbert
AnnAnn
AnneAnne
BurtBurt

Compute / Compute by
Las cláusulas COMPUTE y COMPUTE BY se proporcionan por razones de compatibilidad con versiones anteriores. En su lugar,
utilice estos componentes:

Una cláusula COMPUTE BY permite ver las filas de detalle y de resumen con una instrucción SELECT. Puede calcular valores de
resumen para subgrupos, o un valor de resumen para el conjunto completo de resultados.

La cláusula COMPUTE toma la siguiente información:


La palabra clave opcional BY que calcula el agregado de fila especificado en función de cada columna.
Un nombre de función de agregado de fila; por ejemplo, SUM, AVG, MIN, MAX o COUNT.
Una columna en la que realizar la función de agregado de fila.

CONJUNTOS DE RESULTADOS GENERADOS POR COMPUTE


Los valores de resumen generados por COMPUTE aparecen como conjuntos separados de resultados en los resultados de la
consulta. Los resultados de una consulta que incluya una cláusula COMPUTE son como un informe de ruptura de control, que es un informe

AÑO 2003 Página 68 de 96


SQL Lic. Gustavo Rei

cuyos valores de resumen se controlan mediante las agrupaciones, o rupturas, que se especifique. Puede producir valores de resumen para
grupos, y puede calcular más de una función de agregado para el mismo grupo.

Cuando se especifica COMPUTE con la cláusula opcional BY, hay dos conjuntos de resultados por cada grupo que califica la ins-
trucción SELECT:
• El primer conjunto de resultados de cada grupo tiene el conjunto de filas de detalles que contienen la información de la
lista de selección para ese grupo.
• El segundo conjunto de resultados de cada grupo tiene una fila que contiene los subtotales de las funciones de agrega-
do especificadas en la cláusula COMPUTE para ese grupo.
Cuando se especifica COMPUTE sin la cláusula opcional BY, hay dos conjuntos de resultados para la instrucción SELECT:
• El primer conjunto de resultados de cada grupo tiene todas las filas de detalles que contienen información de la lista de
selección.
• El segundo conjunto de resultados tiene una fila que contiene los totales de las funciones de agregado especificadas en
la cláusula COMPUTE.

EJEMPLOS DE COMPUTE
La instrucción SELECT siguiente usa una cláusula COMPUTE simple para producir el total de la suma del precio y los adelantos
de la tabla titles:

SELECT type, price, advance


FROM titles
ORDER BY type
COMPUTE SUM(price), SUM(advance)

En esta consulta se agrega la palabra clave opcional BY a la cláusula COMPUTE para producir subtotales para cada grupo:

SELECT type, price, advance


FROM titles
ORDER BY type
COMPUTE SUM(price), SUM(advance) BY type

Los resultados de esta instrucción SELECT se devuelven en 12 conjuntos de resultados, 2 conjuntos de resultados por cada uno
de los 6 grupos. El primer conjunto de resultados de cada grupo tiene un conjunto de filas que contienen la información derivada de la lista
de selección. El segundo conjunto de resultados de cada grupo contiene los subtotales de las dos funciones SUM de la cláusula COMPU-
TE.

COMPARAR COMPUTE CON GROUP BY


Para resumir las diferencias entre COMPUTE y GROUP BY:

GROUP BY produce un conjunto individual de resultados. Hay una fila por cada grupo que contiene sólo las columnas de agru-
pamiento y las funciones de agregado que muestran el subagregado de ese grupo. La lista de selección sólo contiene las columnas de
agrupamiento y las funciones de agregado.
COMPUTE produce varios conjuntos de resultados. Un tipo de conjunto de resultados contiene las filas de detalle de cada grupo
que contiene las expresiones de la lista de selección. El otro tipo de conjunto de resultados contiene el subagregado de un grupo o el agre-
gado total de la instrucción SELECT. La lista de selección puede contener expresiones que no sean las columnas de agrupación o las
funciones de agregado. Las funciones de agregado se especifican en la cláusula COMPUTE, no en la lista de selección.
En esta consulta se usa GROUP BY y funciones de agregado y se devuelve un conjunto de resultados que tiene una fila por gru-
po que contiene los subtotales agregados para ese grupo:

SELECT type, SUM(price), SUM(advance)


FROM titles
GROUP BY type

Nota No puede incluir tipos de datos ntext, text o image en una cláusula COMPUTE o COMPUTE BY.

AÑO 2003 Página 69 de 96


SQL Lic. Gustavo Rei

ELSE (IF...ELSE)
Impone condiciones en la ejecución de una instrucción Transact-SQL. La instrucción Transact-SQL (sql_statement) que sigue a
Boolean_expression se ejecuta si Boolean_expression da como resultado TRUE. La palabra clave opcional ELSE es una instrucción Trans-
act-SQL alternativa que se ejecuta cuando Boolean_expression da como resultado FALSE o NULL.
Ejemplos
El ejemplo siguiente obtiene una lista de libros de cocina tradicionales, con un precio entre 10 $ y 20 $, cuando al menos un libro
cumpla las condiciones que se indican. De lo contrario, SQL Server imprime un mensaje que indica que no hay ningún libro que cumpla la
condición y genera una lista de libros de cocina que cuestan menos de 10 $.

USE pubs
GO
DECLARE @msg varchar(255)
IF (SELECT COUNT(price)
FROM titles
WHERE title_id LIKE 'TC%' AND price BETWEEN 10 AND 20) > 0

BEGIN
SET NOCOUNT ON
SET @msg = 'There are several books that are a good value between $10 and $20. These books are: '
PRINT @msg
SELECT title
FROM titles
WHERE title_id LIKE 'TC%' AND price BETWEEN 10 AND 20
END
ELSE
BEGIN
SET NOCOUNT ON
SET @msg = 'There are no books between $10 and $20. You might consider the following books that are under $10.'
PRINT @msg
SELECT title
FROM titles
WHERE title_id LIKE 'TC%' AND price < 10
END

IF...ELSE
Impone condiciones en la ejecución de una instrucción Transact-SQL. La instrucción Transact-SQL que sigue a una palabra clave
IF y a su condición se ejecuta si la condición se satisface (cuando la expresión booleana devuelve TRUE). La palabra clave opcional ELSE
introduce una instrucción Transact-SQL alternativa que se ejecuta cuando la condición IF no se satisface (cuando la expresión booleana
devuelve FALSE).
Observaciones
Se pueden utilizar construcciones IF...ELSE en lotes, en procedimientos almacenados (en los que se utilizan a menudo estas
construcciones para probar la existencia de algún parámetro) y en consultas ad hoc.

Las pruebas IF pueden estar anidadas después de otro IF o a continuación de un ELSE. No hay límite en el número de niveles
anidados.
Ejemplos

UTILIZAR UN BLOQUE IF...ELSE


En este ejemplo se muestra una condición IF con un bloque de instrucciones. Si el precio promedio del título no es menor de 15 $,
se imprime el texto: "Average title price is more than $15" (el precio promedio del título es mayor que 15 $).

USE pubs

IF (SELECT AVG(price) FROM titles WHERE type = 'mod_cook') < $15


BEGIN

AÑO 2003 Página 70 de 96


SQL Lic. Gustavo Rei

PRINT 'The following titles are excellent mod_cook books:'


PRINT ' '
SELECT SUBSTRING(title, 1, 35) AS Title
FROM titles
WHERE type = 'mod_cook'
END
ELSE
PRINT 'Average title price is more than $15.'

El siguiente es el conjunto de resultados:

The following titles are excellent mod_cook books:

Title
-----------------------------------
Silicon Valley Gastronomic Treats
The Gourmet Microwave

(2 row(s) affected)

UTILIZAR MÁS DE UN BLOQUE IF...ELSE


En este ejemplo se utilizan dos bloques IF. Si el precio promedio del título no es menor de 15 $, se imprime el texto: "El precio
promedio del título es mayor que 15 $". Si el precio promedio de los libros de cocina moderna es mayor que 15 $, se ejecuta la instrucción
que imprime el mensaje que indica que los libros de cocina moderna son caros.

USE pubs

IF (SELECT AVG(price) FROM titles WHERE type = 'mod_cook') < $15


BEGIN
PRINT 'The following titles are excellent mod_cook books:'
PRINT ' '
SELECT SUBSTRING(title, 1, 35) AS Title
FROM titles
WHERE type = 'mod_cook'
END
ELSE
IF (SELECT AVG(price) FROM titles WHERE type = 'mod_cook') > $15
BEGIN
PRINT 'The following titles are expensive mod_cook books:'
PRINT ' '
SELECT SUBSTRING(title, 1, 35) AS Title
FROM titles
WHERE type = 'mod_cook'
END

END (BEGIN...END)
Incluye un conjunto de instrucciones Transact-SQL que se ejecutarán como un grupo. Los bloques BEGIN...END pueden anidar-
se.
Ejemplos
El ejemplo siguiente genera una lista de libros de empresa con un precio inferior a 20 $ cuando al menos un libro cumpla las si-
guientes condiciones. De lo contrario, SQL Server imprime un mensaje que indica que no hay ningún libro que cumpla las condiciones y
genera una lista con todos los libros que cuesten menos de 20 $.

SET NOCOUNT OFF

AÑO 2003 Página 71 de 96


SQL Lic. Gustavo Rei

GO
USE pubs
GO
SET NOCOUNT ON
GO
DECLARE @msg varchar(255)
IF (SELECT COUNT(price)
FROM titles
WHERE title_id LIKE 'BU%' AND price < 20) > 0

BEGIN
SET @msg = 'There are several books that are a good value at under $20. These books are: '
PRINT @msg
SET NOCOUNT OFF
SELECT title
FROM titles
WHERE price < 20
END
ELSE
BEGIN
SET @msg = 'There are no books under $20. '
PRINT @msg
SELECT title
FROM titles
WHERE title_id
LIKE 'BU%'
AND
PRICE <10
END

WHILE
Establece una condición para la ejecución repetida de una instrucción o bloque de instrucciones de SQL. Las instrucciones se
ejecutan repetidamente mientras la condición especificada sea verdadera. Se puede controlar la ejecución de instrucciones en el bucle
WHILE con las palabras clave BREAK y CONTINUE.

Ejemplos

UTILIZAR BREAK Y CONTINUE CON IF...ELSE Y WHILE ANIDADOS


En este ejemplo, si el promedio de precio es menor de 30 $, el bucle WHILE dobla los precios y, a continuación, selecciona el
precio máximo. Si el precio máximo es menor o igual que 50 $, el bucle WHILE se reinicia y dobla los precios de nuevo. Este bucle continúa
la duplicación de precios hasta que el precio máximo sea mayor que 50 $ y, a continuación, sale del bucle WHILE e imprime un mensaje.

USE pubs
GO
WHILE (SELECT AVG(price) FROM titles) < $30
BEGIN
UPDATE titles
SET price = price * 2
SELECT MAX(price) FROM titles
IF (SELECT MAX(price) FROM titles) > $50
BREAK
ELSE
CONTINUE
END
PRINT 'Too much for the market to bear'

AÑO 2003 Página 72 de 96


SQL Lic. Gustavo Rei

UTILIZAR WHILE EN UN PROCEDIMIENTO CON CURSORES


La construcción WHILE siguiente es una sección de un procedimiento llamado count_all_rows. Para este ejemplo, esta construc-
ción WHILE prueba el valor devuelto de @@FETCH_STATUS, una función que se utiliza con cursores. Debido a que @@FETCH_STATUS
puede devolver -2, -1 ó 0, se deben probar los tres casos. Si se eliminó una fila de los resultados del cursor desde el momento en que se
ejecutó este procedimiento almacenado, se omite esa fila. Una recuperación correcta (0) hace que se ejecute la instrucción SELECT del
bucle BEGIN...END.

USE pubs
DECLARE tnames_cursor CURSOR
FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
OPEN tnames_cursor
DECLARE @tablename sysname
--SET @tablename = 'authors'
FETCH NEXT FROM tnames_cursor INTO @tablename
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
SELECT @tablename = RTRIM(@tablename)
EXEC ('SELECT ''' + @tablename + ''' = count(*) FROM '
+ @tablename )
PRINT ' '
END
FETCH NEXT FROM tnames_cursor INTO @tablename
END
CLOSE tnames_cursor
DEALLOCATE tnames_cursor

GROUPING
Es una función de agregado que genera una columna adicional en el resultado con el valor 1 si la fila se agrega mediante el ope-
rador CUBE o ROLLUP, ó 0 cuando la fila no es el resultado de CUBE o ROLLUP.
El agrupamiento sólo se permite en la lista de selección asociada a una cláusula GROUP BY que contenga el operador CUBE o
ROLLUP.
USE pubs
SELECT royalty, SUM(advance) 'total advance',
GROUPING(royalty) 'grp'
FROM titles
GROUP BY royalty WITH ROLLUP

ROLLUP
El operador ROLLUP resulta útil para generar informes que contienen subtotales y totales. El operador ROLLUP genera un con-
junto de resultados que es similar a los conjuntos de resultados generados por el operador CUBE
Las diferencias entre CUBE y ROLLUP son:
• CUBE genera un conjunto de resultados que muestra agregados para todas las combinaciones de valores de las co-
lumnas seleccionadas.
• ROLLUP genera un conjunto de resultados que muestra agregados para una jerarquía de valores de las columnas se-
leccionadas. Por ejemplo, una tabla simple Inventory contiene:

Item Color Quantity


-------------------- -------------------- --------------------------
Table Blue 124
AÑO 2003 Página 73 de 96
SQL Lic. Gustavo Rei

Table Red 223


Chair Blue 101
Chair Red 210

Esta consulta genera un informe de subtotales:

SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'


ELSE ISNULL(Item, 'UNKNOWN')
END AS Item,
CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
ELSE ISNULL(Color, 'UNKNOWN')
END AS Color,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP

Item Color QtySum


-------------------- -------------------- --------------------------
Chair Blue 101.00
Chair Red 210.00
Chair ALL 311.00
Table Blue 124.00
Table Red 223.00
Table ALL 347.00
ALL ALL 658.00

(7 row(s) affected)

Si la palabra clave ROLLUP de la consulta se cambia por CUBE, el conjunto de resultados de CUBE es el mismo, excepto que al
final se devuelven estas dos filas adicionales:

ALL Blue 225.00


ALL Red 433.00

La operación CUBE generó filas para las posibles combinaciones de valores de Item y Color. Por ejemplo, CUBE no sólo informa
de todas las combinaciones posibles de valores de Color combinados con el valor Chair de Item (Red, Blue y Red + Blue), sino que también
informa de todas las combinaciones posibles de los valores de Item combinados con el valor Red de Color (Chair, Table y Chair + Table).
Por cada valor de las columnas de la derecha de la cláusula GROUP BY, la operación ROLLUP no informa de todas las combina-
ciones posibles de valores de la columna (o columnas) de la izquierda. Por ejemplo, ROLLUP no informa de todas las combinaciones posi-
bles de valores de Item por cada valor de Color.
El conjunto de resultados de una operación ROLLUP tiene una funcionalidad parecida a la que devuelve COMPUTE BY; sin em-
bargo, ROLLUP tiene estas ventajas:
ROLLUP devuelve un único conjunto de resultados; COMPUTE BY devuelve varios conjuntos de resultados que aumentan la
complejidad del código de la aplicación.
ROLLUP se puede utilizar en un cursor de servidor; COMPUTE BY no se puede.
En ocasiones, el optimizador de consultas puede generar planes de ejecución más eficientes para ROLLUP que para COMPUTE
BY.

CUBE
El operador CUBE genera un conjunto de resultados que es un cubo multidimensional. Un cubo multidimensional es una expan-
sión de datos de hechos o datos que registran sucesos individuales. La expansión se basa en columnas que el usuario desea analizar.
Estas columnas se llaman dimensiones. El cubo es un conjunto de resultados que contiene una tabla cruzada de todas las combinaciones
posibles de dimensiones.

AÑO 2003 Página 74 de 96


SQL Lic. Gustavo Rei

El operador CUBE se especifica en la cláusula GROUP BY de una instrucción SELECT. La lista de selección contiene las colum-
nas de dimensión y las expresiones de funciones de agregado. GROUP BY especifica las columnas de dimensión y las palabras clave
WITH CUBE. El conjunto de resultados contiene todas las combinaciones posibles de los valores de las columnas de dimensiones, junto
con los valores de agregado de las filas subyacentes que coinciden con esa combinación de valores de dimensión.

Por ejemplo, una tabla simple Inventory contiene:

Item Color Quantity


-------------------- -------------------- --------------------------
Table Blue 124
Table Red 223
Chair Blue 101
Chair Red 210

Esta consulta devuelve un conjunto de resultados que contiene el subtotal Quantity de todas las combinaciones posibles de Item y
Color:

SELECT Item, Color, SUM(Quantity) AS QtySum


FROM Inventory
GROUP BY Item, Color WITH CUBE

El siguiente es el conjunto de resultados:

Item Color QtySum


-------------------- -------------------- --------------------------
Chair Blue 101.00
Chair Red 210.00
Chair (null) 311.00
Table Blue 124.00
Table Red 223.00
Table (null) 347.00
(null) (null) 658.00
(null) Blue 225.00
(null) Red 433.00

Las filas siguientes del conjunto de resultados tienen especial interés:

Chair (null) 311.00

Esta fila informa del subtotal de todas las filas que tengan el valor Chair en la dimensión Item. Se devuelve el valor NULL para la
dimensión Color para indicar que el agregado indicado por la fila incluye las filas con cualquier valor de la dimensión Color.

Table (null) 347.00

Esta fila es parecida, aunque indica el subtotal de todas las filas que tengan Table en la dimensión Item.

(null) (null) 658.00

Esta fila indica el total del cubo. Ambas dimensiones Item y Color tienen el valor NULL para indicar que la fila resume todos los
valores de ambas dimensiones.

(null) Blue 225.00


(null) Red 433.00

Estas dos filas indican los subtotales de la dimensión Color. Ambas tienen NULL en la dimensión Item para indicar que los datos
de agregado proceden de filas que tienen cualquier valor en esta dimensión
AÑO 2003 Página 75 de 96
SQL Lic. Gustavo Rei

CUBOS MULTIDIMENSIONALES
El operador CUBE se puede usar para generar cubos n-dimensionales, o cubos con cualquier número de dimensiones. Un cubo
de una única dimensión se puede utilizar para generar un total, por ejemplo:

SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'


ELSE ISNULL(Item, 'UNKNOWN')
END AS Item,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item WITH CUBE
GO

Esta instrucción SELECT devuelve un conjunto de resultados que muestra los subtotales de cada valor de Item y el total de todos
los valores de Item:

Item QtySum
-------------------- --------------------------
Chair 311.00
Table 347.00
ALL 658.00

Las instrucciones SELECT que contiene un operador CUBE con muchas dimensiones pueden generar conjuntos de resultados
grandes, porque estas instrucciones generan filas para todas las combinaciones de los valores de todas las dimensiones. Estos conjuntos
grandes de resultados pueden contener demasiados datos como para que resulten fáciles de leer y entender. Una solución a este problema
es colocar la instrucción SELECT en una vista:

CREATE VIEW InvCube AS


SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
ELSE ISNULL(Item, 'UNKNOWN')
END AS Item,
CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
ELSE ISNULL(Color, 'UNKNOWN')
END AS Color,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH CUBE

A continuación, la vista se puede utilizar para consultar sólo los valores de dimensión que resulten de interés:

SELECT *
FROM InvCube
WHERE Item = 'Chair'
AND Color = 'ALL'

Item Color QtySum


-------------------- -------------------- --------------------------
Chair ALL 311.00

(1 row(s) affected)

Informes de tablas de referencias cruzadas


Algunas veces es necesario hacer girar los resultados, de forma que las columnas se presenten horizontalmente y las filas se
presenten verticalmente. Esto se conoce como crear PivotTable®, crear un informe de tabla de referencia cruzada o girar datos.
Suponga que hay una tabla Pivot que tiene una fila por trimestre. Un SELECT de Pivot informa de los trimestres verticalmente:

AÑO 2003 Página 76 de 96


SQL Lic. Gustavo Rei

Year Quarter Amount


---- ------- ------
1990 1 1.1
1990 2 1.2
1990 3 1.3
1990 4 1.4
1991 1 2.1
1991 2 2.2
1991 3 2.3
1991 4 2.4

Debe crearse un informe con una tabla que contenga una fila por cada año, con los valores de cada trimestre en una columna se-
parada, como en:
Year Q1 Q2 Q3 Q4
1990 1.1 1.2 1.3 1.4
1991 2.1 2.2 2.3 2.4

Éstas son las instrucciones que se utilizan para crear la tabla Pivot y rellenarla con los datos de la primera tabla:

USE Northwind
GO

CREATE TABLE Pivot


( Year SMALLINT,
Quarter TINYINT,
Amount DECIMAL(2,1) )
GO
INSERT INTO Pivot VALUES (1990, 1, 1.1)
INSERT INTO Pivot VALUES (1990, 2, 1.2)
INSERT INTO Pivot VALUES (1990, 3, 1.3)
INSERT INTO Pivot VALUES (1990, 4, 1.4)
INSERT INTO Pivot VALUES (1991, 1, 2.1)
INSERT INTO Pivot VALUES (1991, 2, 2.2)
INSERT INTO Pivot VALUES (1991, 3, 2.3)
INSERT INTO Pivot VALUES (1991, 4, 2.4)
GO

Ésta es la instrucción SELECT que se utiliza para crear resultados girados:

SELECT Year,
SUM(CASE Quarter WHEN 1 THEN Amount ELSE 0 END) AS Q1,
SUM(CASE Quarter WHEN 2 THEN Amount ELSE 0 END) AS Q2,
SUM(CASE Quarter WHEN 3 THEN Amount ELSE 0 END) AS Q3,
SUM(CASE Quarter WHEN 4 THEN Amount ELSE 0 END) AS Q4
FROM Northwind.dbo.Pivot
GROUP BY Year
GO

Esta instrucción SELECT realiza también el tratamiento de una tabla en la que hay varias filas por cada trimestre. La cláusula
GROUP BY combina todas las filas de Pivot de un año determinado en una única fila del resultado. Cuando se realiza la operación de
agrupamiento, las funciones CASE de los agregados SUM se aplican de tal forma que los valores Amount de cada trimestre se agregan a la
columna adecuada del conjunto de resultados, y se agrega 0 a las columnas del conjunto de resultados del resto de los trimestres.

AÑO 2003 Página 77 de 96


SQL Lic. Gustavo Rei

Si los resultados de esta instrucción SELECT se usan como entrada de una hoja de cálculo, es fácil para la hoja de cálculo calcu-
lar un total para cada año. Cuando se usa SELECT desde una aplicación, puede ser más fácil mejorar la instrucción SELECT para calcular
el total anual. Por ejemplo:

SELECT P1.*, (P1.Q1 + P1.Q2 + P1.Q3 + P1.Q4) AS YearTotal


FROM (SELECT Year,
SUM(CASE P.Quarter WHEN 1 THEN P.Amount ELSE 0 END) AS Q1,
SUM(CASE P.Quarter WHEN 2 THEN P.Amount ELSE 0 END) AS Q2,
SUM(CASE P.Quarter WHEN 3 THEN P.Amount ELSE 0 END) AS Q3,
SUM(CASE P.Quarter WHEN 4 THEN P.Amount ELSE 0 END) AS Q4
FROM Pivot AS P
GROUP BY P.Year) AS P1
GO

GROUP BY con CUBE y GROUP BY con ROLLUP calculan la misma clase de información, como se muestra en el ejemplo, pero
con un formato un poco diferente.

AÑO 2003 Página 78 de 96


SQL Lic. Gustavo Rei

Observaciones de todos los tp(s) tenga en cuenta que dependiendo la versión de sql server o de acces los datos pueden variar .
Hay ejercicios muy similares. Hay ejercicios que no se pueden realizar en un solo paso

TRABAJO PRÁCTICO SQL (1)


Contenido: Base de datos neptuno (simplificada o completa) (a los efectos de la ejercitación con SQL, no se observan los errores
de diseño que tiene la BD en cuestión)

1. Listar los id de los clientes


2. Listar los id de los clientes y sus nombres completos
3. Listar los id de los clientes , sus nombres completos y direcciones
4. Listar toda la información de los empleados
5. Listar toda la información de los empleados cuyo jefe sea Fuller, Andrew
6. Listar toda la información de los empleados cuyo país sea Estados Unidos
7. Listar toda la información de los empleados que sean del sexo femenino
8. Listar toda la información de los empleados que sean nacidos antes de 8 de diciembre de 1968
9. Listar todos pedidos tomados por el empleado Leverling, Janet, ordenado por cliente y fecha de pedido
10. Listar todos los pedidos del cliente Rattlesnake Canyon Grocery tomados por empleado Davolio, Nancy ordenados por
cargo y fecha de pedido en forma descendente
11. Listar todos productos cuyo stock sea menor a 10
12. Listar todos productos que no estemos esperando ningún pedido
13. Listar todos productos que su venta este suspendida
14. Listar todos productos que su venta este no suspendida
15. Listar todos productos que su precio sea mayor a $ 20
16. Listado de los vendedores que tomaron pedidos el día 13-01-1998 y el día 31-12-1997
17. Listar las empresas con cargo superior a 5 y su País de destino sea Alemania
18. Listar el nombre de cada empleado y el de su director.
19. Listar detalles de pedidos que no hayan tenido descuento .
20. Listar detalles de pedidos que hayan tenido descuento
21. Listar detalles de pedidos cuyo monto sea superior a $ 200

TRABAJO PRÁCTICO SQL (2)


1. Listar Todos los productos utilizar un alias
2. Listar las cuatro líneas de pedido más caras (las de mayor importe).
3. De cada pedido queremos saber su número de pedido y cliente
4. De cada pedido queremos saber su número de pedido, cantidad, precio unitario e importe total sin descuento
5. Listar de cada empleado su datos, nº de días que lleva trabajando en la empresa
6. Obtener una lista de todos los productos indicando para cada uno su id, descripción, precio y precio con I.V.A. incluido
(es el precio anterior aumentado en un 21%).
7. Obtener la lista de los clientes ordenados por país
8. Obtener los pedidos ordenados por fecha de pedido.
9. Obtener los proveedores ordenados por contacto
10. Obtener las mismas columnas que en el ejercicio 4 pero sacando únicamente las 5 líneas de pedido de menor precio
unitario
11. Listar toda la información de los pedidos de marzo
12. Listar los números de los empleados que tienen región
13. Listar los empleados que no tienen jefe
14. Listar los empleados de nombre Laura
15. Listar los empleados que trabajen con alguna relación en ventas
16. Listar los productos cuyo nombre de producto contenga una “Q”
17. Listar los empleados que en su código postal tengan un 8
18. Listar la totalidad de los descuentos aplicados en pesos por detalle de pedido
19. Listar: La totalidad de los pedidos, dónde figure:
a. Pedido

AÑO 2003 Página 79 de 96


SQL Lic. Gustavo Rei

b. Producto
c. Precio unitario
d. Cantidad pedida
e. Descuento
f. Precio total a pagar sin descuento
g. Descuento
h. Neto a cobrar
i. Monto a cobrar con iva
20. Listar Todos los productos
a. Cuya venta no este suspendida
b. Que tenga unidades en existencia
c. Que la cantidad de unidades en existencia sea mayor que 20
21. Todos los productos
a. Que vengan en caja
b. Que no este suspendido
c. Que nivel de nuevo pedido no sea 0

13
TRABAJO PRÁCTICO SQL (3)
1. Necesito TODOS los clientes que tengan una a en su id y su nombre tenga una s
a. Luego a 1. agregarle que los contactos de los proveedores tengan una c en su nombre o que el cargo del
contacto tenga la palabra venta.
b. Ordenados por el tercer campo
2. Realice una unión de 3 tablas
3. Realice el producto cartesiano de una tabla consigo mismo.
4. Seleccione la tabla empleados y cree un alias de la misma tabla (tiene que seleccionar dos veces la misma tabla).
a. Muestre los campos apellido, nombre y jefe de la segunda tabla
b. Muestre los campos apellido, nombre y jefe de la primera tabla
c. Restrinja los campos mostrados, de tal forma que me muestre el jefe de cada empleado Use la opción a.
d. Restrinja los campos mostrados, de tal forma que me muestre el jefe de cada empleado Use la opción b.
e. ¿Qué pasó? ¿Dónde esta la diferencia?¿Por qué?
5. Necesito conocer todos los proveedores que me proveen productos
6. Necesito conocer todos los empleados que hayan vendido
a. Soluciónelo sin inner y con inner
b. Si cambia el = en los campos de emparejamiento, ¿qué le muestra?
c. Si cambia el orden de las tablas que le muestra
7. Listar los empleados de WA que hayan recibido pedidos y que su forma de envío sea Speedy Express
8. Listar los pedidos que fueron recibidos por Davolio, Nancy
9. Se desea tener en una única vista todos los campos de las tablas proveedores y productos
10. Realice un inner join de 3 tablas
11. Realice el producto cartesiano de una tabla consigo mismo.
12. Seleccione la tabla empleados y cree un alias de la misma tabla (tiene que seleccionar dos veces la misma tabla.
a. Muestre los campos apellido, nombre y jefe de la segunda tabla
b. Muestre los campos apellido, nombre y jefe de la primera tabla
c. Restrinja los campos mostrados, de tal forma que me muestre el jefe de cada empleado Use la opción a.
d. Restrinja los campos mostrados, de tal forma que me muestre el jefe de cada empleado Use la opción b.
e. ¿Qué pasó? ¿Dónde esta la diferencia?¿Por qué?
13. Necesito conocer todos los proveedores que me proveen productos
14. Necesito conocer todos los empleados que hayan vendido
a. Soluciónelo sin inner y con inner
b. Si cambia el = en los campos de emparejamiento, ¿qué le muestra?
c. Si cambia el orden de las tablas que le muestra, ¿qué le muestra?
d. Si cambia inner por rigth y left que pasa
15. Listar los empleados de WA que hayan recibido pedidos y que su forma de envío sea Speedy Express

13
Los Ejercicos de Table, solamente los puede realizar si Utiliza Access

AÑO 2003 Página 80 de 96


SQL Lic. Gustavo Rei

16. Listar los pedidos que fueron recibidos por Davolio, Nancy ¿De cuantas formas puede hacerlo?
17. Listar los pedidos superiores a 400 , incluyendo el nombre del empleado que tomó el pedido y el nombre del cliente que
lo solicitó.
18. Hallar los empleados que realizaron su primer pedido el mismo día en que fueron contratados.
19. Todos los productos que fueron pedidos y que hayan sido provistos por algún proveedor y que las unidades en exis-
tencia sean mayores que 30
20. Se necesita listar el nombre de cliente, la fecha de pedido, los productos y la cantidad adquirida de productos, dónde los
pedidos sean posteriores al año 1997 y los productos adquiridos sean superiores a 20, ordenados por fecha de pedido

TRABAJO PRÁCTICO SQL (4) COMPENDIO CON PROBLEMAS


Para completar el presente debe realizar:
Intentar hacer los ejercicios con la base de datos sin corregir, de no poder obtener resultados
Corregir (de ser necesaria) la base de datos lógicamente
Crear la Base de datos en SQL server en forma automática
Carga de datos
Realizar las consultas

Ejercicio 1.- Sea la siguiente BD:

PROVEEDORES (nro_p, nom_p, categoria, ciud_p)


ITEMS (nro_i, descripcion_i, ciud_i)
PEDIDOS (nro_p, nro_c, nro_i, cantidad, precio)
CLIENTES (nro_c, nom_c, ciud_c)

1. Listar los proveedores de Córdoba


2. Listar los proveedores que proveen el ítem 1
3. Listar los clientes que solicitan ítems provistos por el proveedor 1
4. Listar los clientes que solicitan algún ítem provistos por proveedores con categoría mayor que 4
5. Listar los ítems pedidos por clientes de Rosario.
6. Listar los pedidos en los cuales un cliente de rosarios solicita artículos fabricados en Mendoza.
7. Listar los pedidos en los que el cliente 23 solicita ítems no solicitados por el cliente 30
8. Listar las ciudades en la forma (ciudad1, ciudad2) tales que un proveedor en la ciudad1 provea ítems solicitados por
clientes en ciudad2
9. Listar los números de proveedores cuya categoría sea mayor que la de todos los proveedores que proveen el ítem
"cuaderno"
10. Listar los clientes que han pedido dos o más ítems distintos.
11. Listar los proveedores que proveen a todos los clientes de Córdoba una cantidad mayor que el promedio de las canti-
dades pedidas por los clientes de Rosario.

Ejercicio 2.- Una oficina gubernamental desea construir un complejo habitacional, para lo cual elaboro la siguiente Base de Datos:

TRAMO (c_ciudadA, c_ciudadB, Distancia)


CIUDADES (c_ciudad, nombre, cant_escuelas, cant_fabricas)

Para decidir donde instalarlo, desea conocer los siguientes datos:

1. Las ciudades alcanzables desde la ciudad con mayor cantidad de fabricas, recorriendo no más de dos tramos, c/u de
los cuales no puede tener mas de 10km de longitud.
2. Las ciudades con mas de 10 fabricas que estén conectadas con todas las demás en forma directa, siempre que ningún
tramo supere los 50km.
3. Los pares de ciudades, de la forma (ciudad1, ciudad2), que son alcanzables a través de, a lo sumo, otra ciudad, lláme-
se a esta, ciudad3 (esto es, encontrar los caminos ciudad1-ciudad3-ciudad2).

Ejercicio 3.- Dada la BD:

AÑO 2003 Página 81 de 96


SQL Lic. Gustavo Rei

FRECUENTA (nombre-pers, nombre-bar)


SIRVE (nombre-bar, nombre-cerveza)
GUSTA (nombre-pers, nombre-cerveza)

1. Encontrar las personas que frecuentan un bar que sirven una cerveza que les gusta.
2. Encontrar a las personas que beben en el mismo bar que las personas a las que les gusta la cerveza “Quilmes”
3. Encontrar las personas que beben en el mismo bar que aquellas a las que le gusta una marca de cerveza que sirva di-
cho bar y que le guste a Juan Pérez.
4. Encontrar las personas que frecuentan solamente bares que sirven alguna cerveza que les gusta (asumir que cada per-
sona frecuenta al menos un bar y le gusta al menos una cerveza)
5. Encontrar las personas que no frecuentan ningún bar que sirven cerveza que les gusta.

Ejercicio 4.- Sea la BD:

PERSONAS (tipo_doc, num_doc, nomyap, dir, tel, fnac, sexo)


PROGENITOR (tipo_doc, num_doc, tipo_doc_hijo, num_doc_hijo)

1. Listar para cada Juan Pérez los tipo y numero de documento, nombre y apellido y teléfono de todos sus hijos.
2. Idem a, de:
3. Todos sus hermanos (los hijos de su madre y/o su padre)
4. su madre
5. su abuelo materno
6. todos sus nietos

TRABAJO PRÁCTICO SQL (5)


1. Cuántos empleados tengo
2. Cuantos clientes tengo.
3. Cuántos pedidos tengo
4. Cuantos productos Té Dharamsala fueron pedidos . Use primero un select simple a una única tabla. Use luego un Inner
, ¿hay diferencia?
5. Cuantos (registros)detalles de pedido del ejercicio anterior tengo
6. Cuál es el promedio de ventas en general
7. Cuál es el promedio de cantidades de todos los productos vendidos
8. Se necesita saber, el total de productos vendidos, la cantidad de productos vendidos y la media de productos vendidos
9. Se necesita saber el total de dinero ingresado de los productos provistos por la empresa exotic liquids (piense este ejer-
cicio tiene que usar tres tablas para resolverlo en forma correcta)
10. Como calcula lo mismo de todos los otros proveedores.
11. Se necesita saber todo lo que pagó el cliente Ana Trujillo Emparedados y helados
12. Se necesita saber la cantidad total de dinero facturado y el total del cargo por envío de todos los clientes
13. Se necesita saber la cantidad total de dinero facturado y el total del cargo por envío de los clientes Ana Trujillo Empare-
dados y helados y Alfreds Futterkiste
14. Se necesita conocer cual fue el monto de la venta máxima realizada
15. Se necesita conocer cual fue el monto de la venta mínima realizada

TRABAJO PRÁCTICO SQL (6)

1. Hallar en qué fecha se realizó el primer pedido (suponiendo que en la tabla de pedidos tenemos todos los pedidos reali-
zados hasta la fecha).
2. Se necesita tener un listado de todos los productos provistos por cada proveedor, debiendo verse el nombre del produc-
to y el nombre de la compañía proveedora.
3. Agrupe: Todos los pedidos por Empleados, se debe ver el empleado y la cantidad de pedidos que recibió.
4. Se necesitan saber todos los pedidos que hicieron cada cliente
5. Se necesitan saber todos los pedidos realizados a cada producto
6. Se necesita saber cual es el producto más pedido y el producto menos pedido
7. Se necesitan saber los pedidos recibidos por mes.
AÑO 2003 Página 82 de 96
SQL Lic. Gustavo Rei

8. Se necesitan saber los pedidos realizados por año


9. Se necesita saber cual es el producto más caro, cual el más barato y cual e promedio de costo
10. Se necesita saber la cantidad total de dinero facturado por envío de todos los clientes (Ojo con el cálculo tiene que in-
cluir el descuento de tenerlo)
11. Listar cuántos empleados están asignados a cada cada Jefe.
a. Para hacerlo, en primer término use un producto cartesiano
b. Luego un Inner join
c. ¿Qué pasó?, ¿Porqué?
12. Agrupar todos los pedidos realizados por los clientes a todos los empleados, definiendo la cantidad total que cada em-
pleado le cobró a cada cliente., ordenados por nombre de cliente, se tiene que ver el nombre del cliente, el apellido del
empleado y el monto cobrado .
13. Se necesita conocer el promedio de venta de cada empleado que haya tenido una venta mayor a 1000 por cliente. Se
debe mostrar: apellido del empleado, promedio del empleado por cliente, total del empleado por cliente.

TRABAJO PRÁCTICO SQL (7)


1. Crear la tabla empleados y definir su clave principal en la misma instrucción de creación.
2. Crear la tabla oficinas con su clave principal y su clave foránea ( la columna dir contiene el código de empleado del di-
rector de la oficina luego es un campo que hace referencia a un empleado luego es clave foránea y hace referencia a la
tabla empleados).
3. Crear la tabla productos con su clave principal.
4. Crear la tabla clientes también con todas sus claves y sin la columna limitecredito.
5. Crear la tabla pedidos sin clave principal, con la clave foránea que hace referencia a los productos, la que hace referen-
cia a clientes y la que indica el representante (empleado) que ha realizado el pedido.
6. Añadir a la definición de clientes la columna limitecredito.
7. Añadir a la tabla empleados las claves foráneas que le faltan. (Si no tienes claro cuales son te lo decimos ahora: la co-
lumna oficina indica la oficina donde trabaja el empleado y la columna director indica quién dirige al empleado, su jefe
inmediato).
8. Hacer que no puedan haber dos empleados con el mismo nombre.
9. Añadir a la tabla de pedidos la definición de clave principal.
10. Definir un índice sobre la columna region de la tabla de oficinas.
11. Eliminar el índice creado.

TRABAJO PRÁCTICO SQL (8) COMPENDIO CON PROBLEMAS- SEGUNDA PARTE

Ejercicio 1: Seguros
Consideremos la siguiente estructura de tablas:
EMPLEADO (DNI, NombreEmpleado, Salario)
VENDEDOR (NºVendedor, Zona, DNI)
POLIZA (NºPoliza, Importe, Beneficiario, NºVendedor, Fecha)
EMPLEADO-JEFE (DNI, DNIJefe)
Construir las sentencias de consulta SQL siguientes:

a) Nombre de los vendedores de la zona Norte


b) Nombre del jefe del vendedor con número de vendedor 113.654
c) Nº de póliza e importe de póliza de las vendidas este año por los vendedores cuyo jefe es Pablo Collado.

Ejercicio 2: Empresa2
Consideremos la siguiente estructura de tablas:
DEPARTAMENTO (NombreDepartamento, NºEmpleados)
EDIFICIO (IdEdificio, Nombre, NºDespachos, IdPoligono)
POLÍGONO (IdPoligono, Nombre, Ciudad)
DEPARTAMENTO-EDIFICIO (NombreDepartamento, IdEdificio, NºDespachos)

AÑO 2003 Página 83 de 96


SQL Lic. Gustavo Rei

Construir las sentencias de consulta SQL siguientes:


a) Nombre de los edificios, en los que el departamento de “Contabilidad” tiene más de 5 despachos asignados.
b) Nombre de los departamentos y número de despachos de cada uno que estén ubicados en el edificio “La Campana”.
c) Nombre de los departamentos con representación en “Logroño”.
d) Nombre edificio y número de despachos de los edificios de los polígonos “Cantabria”, y “La Portalada”.

Ejercicio 3: Ríos de España

Consideremos la siguiente estructura de tablas:


COMUNIDADAUTONOMA(NombreAutonomia, NºHabitantes)
CIUDAD (IdCiudad, Nombre, NºHabitantes, NombreAutonomia)
RIO (NombreRio, Caudal, Longitud)
COMUNIDADAUTONOMA-RIO (NombreAutonomia, NombreRio, NºKilometros)
RIO-CIUDAD (NombreRio, IdCiudad)

Construir las sentencias de consulta SQL siguientes:

a) Nombre y número de habitantes de las ciudades de La Rioja.


b) Nombre y longitud de los rios que pasan por la Comunidad de Aragón.
c) Nombre de los rios que pasan parte por Castilla-La Mancha y parte por Andalucía.
d) Suma de los caudales de los rios que pasan por Navarra.

Ejercicio 4: Vehículos

Consideremos la siguiente estructura de tablas:

CONDUCTOR (DNI, Nonbre, Apellido, NºAños)


VEHICULO (Matricula, Marca)
COCHE (Matricula, Nº Puertas)
MOTO (Matricula)
CAMION (Matricula, Tara)
CONDUCTOR-VEHICULO (DNI, Matricula)
Construir las sentencias de consulta SQL siguientes:
1. DNI de los conductores de motos
2. Marca de los vehículos que conduce Pepe Pérez.
3. Marca y tara del camión conducido por la persona cuyo DNI sea “111111111”. Incluir también el número de años con el car-
net de conducir.

Ejercicio 5: Autobuses

Consideremos la siguiente estructura de tablas:


AUTOBUS (NºLinea, NºAsientos)
CONDUCTOR (DNI, Nombre, Apellido, NºAños,NºLinea)
PARADA (IDParada, Calle, Numero, Marquesina?)
AUTOBUS-PARADA (NºLinea, IDParada, 1ªHoraLlegada, Frecuencia)
Construir las sentencias de consulta SQL siguientes:
1. Lineas que tienen parada en Vara de Rey
2. Nº asientos del autobús que conduce Pepe Pérez.
3. ¿Todas las paradas de la línea 30 poseen marquesina?. Para responder a la pregunta se decide contar las paradas de la li-
nea 30 que no tengan marquesina. Si ese número es <> 0, entonces la respuesta a la pregunta es NO, en otro caso será SI.
4. Líneas que tienen parada en Vara de Rey 2 y Vara de Rey 40

Ejercicio 6: Seguros2
AÑO 2003 Página 84 de 96
SQL Lic. Gustavo Rei

Consideremos la siguiente estructura de tablas:


PERSONA (DNI, Nombre, Apellido1, Apellido2)
PISO (IDPiso, Calle, Numero, Ciudad, Nºm2, DNIPropietario)
SEGURO (NºPoliza, Tipo, CuotaBasica, DNIAsegurado, IDPiso, CantidadAsegurada)
Construir las sentencias de consulta SQL siguientes:

1. Datos personales de aquellas personas cuyo primer apellido es García.


2. Dirección completa de los pisos de más de 90 metros cuadrados.
3. Nº de las pólizas contratadas por Pepe Pérez.
4. Nº de póliza y cantidad asegurada, de los seguros de los pisos cuyo propietario es Pepe Pérez.
5. Nº de póliza y cantidad asegurada, de los seguros de hogar en los que el contratante del seguro coincide con el propietario
del piso.

Ejercicio 7: Horarios
Consideremos la siguiente estructura de tablas:
ASIGNATURA (Nombre, Cuatrimestre, NºAula)
PROFESOR (Nombre, Departamento)
AULA (NºAula, Capacidad)
PIZARRA (NºAula, Ancho, Alto)
AULA-NO-INFORMATICA (NºAula)
AULA-DE-INFORMATICA (NºAula, NºOrdenadores)
ASIGNATURA-PROFESOR (NombreAsignatura, NombreProfesor)
Construir las sentencias de consulta SQL siguientes:

1. Nombre de las asignaturas que se imparten en el aula 108 durante el 1er Cuatrimestre. Nótese que se asume que el tipo de
datos del campo “Cuatrimestre” en la tabla “Asignatura” es un campo de tipo numérico, de ahí que se convierte la informa-
ción proporcionada en el enunciado al tipo de datos tal y como se almacena en la tabla.
2. Nombre y cuatrimestre de las asignaturas que se imparten en aulas de informática con capacidad mayor de una veintena de
alumnos
3. Numero y capacidad de las aulas sin pizarra
4. Nombres de los profesores del departamento de Matemáticas y Computación que den clase en aulas de informática. Para
cada uno de ellos, incluir el nombre de la asignatura, el número de ordenadores y la capacidad del aula.

Ejercicio 8: Prensa
Consideremos la siguiente estructura de tablas:
PERIODICO(nombre)
ARTICULO(id-articulo, tipo, titulo, texto completo, resumen)
AUTOR(id-autor, nombre)
PERIODISTA(id-autor)
NOPERIODISTA(id-autor, profesion)
PERIODICO-ARTICULO(nombre-periodico, id-articulo, fecha, seccion)
ARTICULO-AUTOR(id-articulo, id-autor)
PERIODISTA-PERIODICO(id-autor, nombre-periodico, cargo)
1. Listado de artículos (mostrando título y tipo) publicados el 13 de marzo de 2001 en el diario “La Rioja”.
2. Mostrar por orden alfabético los nombres de periódicos en los que algún empresario haya publicado artículos (1 o más) en la
sección de opinión.
3. Verificar si todos los autores son periodistas o no periodistas.
4. Nombres de periódicos en los que haya al menos 6 empleados. Mostrar también el número de empleados.
5. Mostrar los títulos de los artículos que hayan sido publicados simultáneamente (en la misma fecha) en “La Rioja” y “El Co-
rreo”.

Ejercicio 9: Vinos
AÑO 2003 Página 85 de 96
SQL Lic. Gustavo Rei

Consideremos la siguiente estructura de tablas:


VINO(id-vino, marca, tipo-vino, año, graduacion, nombre-bodega)
BODEGA(nombre-bodega)
EMPRESA(nombre propietario, nombre-bodega)
COOPERATIVA(nº cooperativistas, nombre-bodega)
CATADOR(nombre-catador, medio)
UVA(tipo-uva)
VINO-UVA(id-vino, tipo-uva)
VINO-CATADOR(id-vino, nombre-catador, calificacion)
VINO-BODEGA(id-vino, nombre-bodega)

1. Nombres de las bodegas de particulares.


2. Marca y graduación de vinos del año que se hayan elaborado con uva garnacha o tempranillo.
3. Marca, tipo de vino, año de cosecha, graduación y nombre del catador de los vinos de la bodega “Magnífica”.
4. Marcas de vinos (marca, tipo y año de cosecha) en los que para su elaboración se hayan utilizado uva garnacha juntamente
con uva tempranillo (las dos).

Ejercicio 10: Museos


Consideremos la siguiente estructura de tablas:
AUTOR(id_autor, nombre-autor, nacionalidad)
OBRADEARTE(titulo, nombre-museo, ciudad)
PINTURA(ancho, alto, tipo, titulo)
ESCULTURA(material, estilo, titulo)
SALA(id-sala, nombre-sala, nombre-museo, ciudad)
MUSEO(nombre-museo, calle, nº, ciudad, pais)
OBRADEARTE-AUTOR(titulo, id-autor)
OBRADEARTE-SALA(titulo, id-sala)

1. Relación de los títulos de las pinturas junto con el nombre del museo donde se localizan.
2. Nombres de los autores que hayan realizado al menos una pintura y una escultura.
3. Títulos de las obras de arte registradas en España junto con el museo en el que se encuentran.
4. Nombre del autor y nombre del museo en que se encuentran las pinturas al óleo.
5. Título, autor, nombre de la sala y museo de las obras de arte que se encuentran en Madrid.
6. Relación de las salas que tienen el mismo nombre en el museo del Prado y en el Louvre.

Ejercicio 11: Publicidad


Consideremos la siguiente estructura de tablas:
CAMPAÑAPUBLICITARIA(tema, presupuesto, id-anunciante)
ANUNCIO(slogan, tema-campaña)
ANUNCIOTELEVISIVO(minutos, slogan)
CUÑARADIOFONICA(minutos, slogan)
ANUNCIOIMPRESO(ancho, alto, imagenes?, slogan)
ANUNCIANTE(id-anunciante, nombre)
INSTITUCION(id-anunciante)
EMPRESA(id-anunciante)
MEDIOAUDIOVISUAL(nombre)
CADENATELEVISIVA(nombre)
EMISORADERADIO(nombre)
PUBLICACION(nombre, tirada)
PERIODICO(nombre)
REVISTA(nombre, periodicidad)
MEDIOAUDIOVISUAL-EMPRESA(nombre medio audiovisual, id-anunciante)
ANUNCIO-CADENATELEVISIVA(slogan, nombre-cadena, nº veces)
CUÑA-EMISORARADIO(slogan, nombre-emisora, nº veces)
ANUNCIO-PUBLICACION(slogan, nombre-publicacion, nº pagina)
AÑO 2003 Página 86 de 96
SQL Lic. Gustavo Rei

1. Slogan, tema y minutos de duración de los anuncios de televisión y las cuñas radiofónicas.
2. Slogan y formato de los anuncios sin imágenes publicados en "La Rioja" o "El Correo"
3. Nombre de las emisoras de radio que no se anuncien.
4. Nombre de anunciantes con anuncios de televisión de más de 2 minutos de duración.
5. Dar una consulta que permita verificar si todo anunciante es o bien institución o bien empresa.
6. Mayores tiradas de revistas, especificando su periodicidad.
7. Slogan y minutos de duración de los anuncios de televisión que hayan sido emitidos el mismo número de veces por todas las
cadenas de televisión.

Ejercicio 12: Aeropuerto


Consideremos la siguiente estructura de tablas:
PASAJERO(DNI, Nombre, Apellidos, Edad, Id-vuelo, Nº asiento)
VUELO(TipoAvión, Compañia, Id-vuelo)
VUELO-DE-SALIDA(HoraSalida, PuertaEmbarque, Id-vuelo, Ciudad, Aeropuerto)
VUELO-DE-LLEGADA(HoraLlegada, PuertaSalida, Id-vuelo, Ciudad, Aeropuerto)
LUGAR(Ciudad, Pais, Aeropuerto)
1. Hora de salida y puerta de embarque del pasajero Andrés Pérez García.
2. Número de vuelos realizados por la compañía Iberia.
3. Relación de compañías de aviones que utilizan el aeropuerto junto con el número de vuelos de salida y el número de vuelos
de llegada que han realizado.
4. Nombre y apellidos de los pasajeros que viajan a París ordenados alfabéticamente.
5. Compañías que hayan realizado vuelos con mas de 100 pasajeros.

Ejercicio 13: Ciclismo


Consideremos la siguiente estructura de tablas:
CICLISTA (IDCiclista, Nombre, Edad, Altura, Peso, Pulsaciones, NombreSponsor)
EQUIPO (NombreSponsor)
SPONSOR (NombreSponsor)
PRUEBA (NombrePrueba, Año1Edicion)
CLASICA (NombrePrueba, KmsRecorrido)
ETAPAS (NombrePrueba)
ORGANIZADOR (NombreOrganizador)
CICLISTA-PRUEBA (IDCiclista, NombrePrueba, NºVeces)
EQUIPO-ETAPA (NombreSponsor,NombrePrueba, NºVeces)
PRUEBA-ORGANIZADOR (NombrePrueba, NombreOrganizador)
SPONSOR-ORGANIZADOR (NombreSponsor, NombreOrganizador)
Construir las sentencias de consulta SQL siguientes:
1. Nombre y edad de los ciclistas ganadoresdel Tour de Francia más de una vez.
2. Nombre de los ciclistas del grupo Kelme que han ganado alguna clásica
3. Nombre de los ciclistas que han ganado el Tour de Francia y Vuelta a España.
4. Nombre de los sponsor de los equipos que han ganado (clasificación general por equipos) alguna prueba por etapas
organizadas por dichos sponsor.
Nótese que al construir la sentencia, se asume que un equipo puede ganar tanto pruebas clásicas como pruebas por etapas. Del
modelo relacional no se concluye por los nombres de campos utilizados lo que del diagrama E-R, donde se indica que un equipo solo puede
vencer en pruebas por etapas. Si se asume esta misma consideración no sería necesaria ni la tabla ETAPAS ni la primera condición de la
cláusula WHERE. Esta condición se incluye únicamente para asegurar que la prueba vencida es una prueba por etapas.

Ejercicio 14: Cine


Consideremos la siguiente estructura de tablas:
PELICULA (IDPelicula, Titulo, Año, Nacionalidad, OscarPelicula?, NombreDirector, OscarDirector?, TituloGuion, OscarGuion?)
GUION (Titulo)
PERSONA (Nombre, Edad, Nacionalidad)
GUIONISTA (Nombre)
AÑO 2003 Página 87 de 96
SQL Lic. Gustavo Rei

DIRECTOR (Nombre)
INTERPRETE (Nombre)
REMAKE (IDPeliculaOriginal, IDPeliculaRemake)
PELICULA-INTERPRETE (IDPelicula, NombreInterprete, Oscar?)
ESCRITOR-GUION (NombreGuionista, TituloGuion)
Construir las sentencias de consulta SQL siguientes:
1. Id y Título de las películas interpretadaspor Ingrid Bergman.
2. Titulo y Nombre del Director, de las películas en cuyo reparto se incluye a éste último
3. Titulo de las películas que ganaron el Oscar a la mejor película y al mejor guion.
4. Titulo de las películas interpretadas por Spencer Tracy y Catherine Hepburn.
5. Titulo de las películas y sus remakes que hayan sido dirigidas por el mismo director. Incuye el nombre del director

Ejercicio 15: Grupos Musicales


Consideremos la siguiente estructura de tablas:
MUSICO (Nombre, Sexo, Edad, NombreGrupo, AñoIncorporacion)
LETRISTA (Nombre)
INSTRUMENTISTA (Nombre, Instrumento)
GRUPO (Nombre, AñoFundacion)
CANCIÓN (IDCancion, Titulo, Duración, NombreCompañia)
COMPAÑÍA (NombreCompañia, NombreGrupoEstrella)
GRUPO-CANCION (NombreGrupo, IDCancion, Superventas?)
LETRISTA-CANCION (NombreLetrista, IDCancion)
Construir las sentencias de consulta SQL siguientes:
1. Relación de los nombres de los componentes de los grupos musicales surgidos en los años 80.
2. Nombre del bajo del grupo estrella de la EMI
3. Nombre de la compañía con los derechos de las canciones que han sido superventas, tocadas por el grupo Oasis.
4. Nombre de los músicos fundadores de los Rolling Stones.
5. Titulo de las canciones superventas de The Beatles escritas por George Harrison
6. Titulo y grupo de las canciones superventas escritas por algún componente de dicho grupo (The Beatles)
7. Identificador de las canciones tocadas por los Beatles y los Rolling Stones

AÑO 2003 Página 88 de 96


SQL Lic. Gustavo Rei

Tipos de datos SQL Server


En Microsoft® SQL Server™, cada columna, variable local, expresión y parámetro dispone de un tipo de datos relacionado, que
es un atributo que especifica el tipo de datos (integer, character, money, etc) que el objeto puede contener. SQL Server suministra un
conjunto de tipos de datos del sistema que define todos los tipos de datos que pueden utilizarse con SQL Server. El conjunto de tipos de
datos suministrados por el sistema se muestra debajo.
También se pueden utilizar tipos de datos definidos por el usuario, que son en realidad alias de los tipos de datos suministrados
por el sistema.
SQL Server proporciona sinónimos de tipos de datos para la compatibilidad con SQL-92.
Nombre14 Descripción
biginit Datos enteros (números enteros) comprendidos entre -2^63 (-9223372036854775808) y 2^63 -1
(9223372036854775807).
int Datos enteros (números enteros) comprendidos entre -2^31 (-2.147.483.648) y 2^31 - 1 (2.147.483.647).

Smallint Datos enteros comprendidos entre 215 (-32.768) y 215 - 1 (32.767).


tinyint Datos enteros comprendidos 0 y 255.
bit Datos enteros con valor 1 ó 0
decimal Datos de precisión y escala numérica fijas comprendidos entre -1038 +1 y 1038 – 1.

numéric Funcionalmente equivalente a decimal.


Money Valores de moneda comprendidos entre -263 (-922.337.203.685.477,5808) y 263 - 1
(+922.337.203.685.477,5807), con una precisión de una diezmilésima de la unidad monetaria.
Smallmoney Valores de moneda comprendidos entre -214.748,3648 y +214.748,3647, con una precisión de una
diezmilésima de la unidad monetaria.
Float Números con precisión de coma flotante comprendidos entre -1,79E + 308 y 1,79E + 308.
Real Números con precisión de coma flotante comprendidos entre -3,40E + 38 y 3,40E + 38.
Datetime Datos de fecha y hora comprendidos entre el 1 de enero de 1753 y el 31 de diciembre de 9999, con una
precisión de 3,33 milisegundos.
Smalldatetime Datos de fecha y hora comprendidos entre el 1 de enero de 1900 y el 6 de junio de 2079, con una preci-
sión de un minuto.
Char Datos de caracteres no Unicode de longitud fija con una longitud máxima de 8.000 caracteres.
Varchar Datos no Unicode de longitud variable con un máximo de 8.000 caracteres.
Text Datos no Unicode de longitud variable con una longitud máxima de 231 - 1 (2.147.483.647) caracteres.
Nchar Datos Unicode de longitud variable con una longitud máxima de 4.000 caracteres.
Nvarchar Datos Unicode de longitud variable con una longitud máxima de 4.000 caracteres. sysname es el tipo de
datos suministrado por el sistema y definido por el usuario que es funcionalmente equivalente a nvar-
char(128) y que se utiliza para hacer referencia a nombres de objetos de bases de datos.
Ntext Datos Unicode de longitud variable con una longitud máxima de 230 - 1 (1.073.741.823) caracteres.
Binary Datos binarios de longitud fija con una longitud máxima de 8.000 bytes.
Varbinary Datos binarios de longitud variable con una longitud máxima de 8.000 bytes.
Image Datos binarios de longitud variable con una longitud máxima de 231 - 1 (2.147.483.647) bytes.
Cursor Una referencia a un cursor.
Sql_ variant Un tipo de datos que almacena valores de varios tipos de datos aceptados en SQL Server, excepto text,
ntext, timestamp y sql_variant.
Table Un tipo de datos especial que se utiliza para almacenar un conjunto de resultados para un proceso poste-
rior.
Timestamp Un número único para toda la base de datos que se actualiza cada vez que se actualiza una fila.
uniqueidentifier Un identificador exclusivo global (GUID).

Sinónimos de tipos de datos con SQL 92.

Sinónimo Tipo de datos asignado al sistema


Binary varying Varbinary
char varying Varchar
character Char
character char(1)
character(n) char(n)

14
Todos los tipos de datos tienen acepciones diferentes según el DBMS, esta es una tabla que únicamente sirve como guía genérica.

AÑO 2003 Página 89 de 96


SQL Lic. Gustavo Rei

Sinónimo Tipo de datos asignado al sistema


character varying(n) varchar(n)
Dec decimal
Double precision float
float[(n)] para n = 1-7 real
float[(n)] para n = 8-15 float
integer int
national character(n) nchar(n)
national char(n) nchar(n)
national character varying(n) nvarchar(n)
national char varying(n) nvarchar(n)
national text ntext
rowversion timestamp

Tipos de datos Oracle15


CHAR Máximo de 255. Por defecto 1.
NUMBER Máximo de 105 dígitos. Por defecto 44.
INTEGER Numérico sin decimal. Por defecto 38.
DATE Hasta el 31 de diciembre de 4712.
LONG Tipo caracter con tamaño variable hasta 65535 bytes. Permite una sola columna LONG
por tabla. No se puede usar en subconsultas, funciones o índices.
RAW Dato en binario puro (imágenes y sonido) con un ancho máximo de 255.
LONGRAW Igual que LONG, pero para almacenar datos en binario puro.

Tipos de datos informix


CHAR (N):Definen una cadena de caracteres desde una posición. A-32767
SMALLINT: Para un numero entero corto cuyo valor debe estar comprendido entre (+,-)32767
INTEGER: Define un numero entero largo, su valor esta comprendido entre(+,-) 2.150.000.000
DECIMAL (M,N): Permiten números con fracciones decimales, el valor máximo de (M) que indica las posiciones del campo
es de 32 y (n) que indica posiciones decimales debe ser menor o igual que (M).
SMALLFLOAT: Para un numero corto en coma flotante, es equivalente a DECIMAL (8).
FLOAT: Para un numero en coma flotante largo. Es equivalente a DECIMAL(16).
SERIAL [(N)]: Indica un numero entero único y secuencial que se incrementa de forma automática por defecto. El valor
inicial es 1 a no ser que se le indique lo contrario. Sólo puede haber uno por tabla.
MONEY (M,N): Albergan números de tipo decimal con dos cifras después de la coma para expresar una moneda (siempre
que no digamos lo contrario).
MONEY: Es equivalente a datos decimales. Money (8) decimal l (8 posiciones, 2 decimales).
DATE: Sirve para indicar un campo de fecha con el formato (dd-mm-AAAA).

Tipos de datos Acces16


Tipo de datos Tamaño de almacenamiento Descripción
BINARY 1 byte por carácter Se puede almacenar cualquier tipo de datos en un campo de este
tipo. Los datos no se traducen (por ejemplo, a texto). La forma en
que se introducen los datos en un campo binario indica cómo apare-
cerán al mostrarlos.
BIT 1 byte Valores Sí y No, y campos que contienen solamente uno de dos
valores.
TINYINT 1 byte Un número entero entre 0 y 255.

15
Oracle 7 Manual de Referencia, Koch, George., Osborne/McGraw-Hill, 1994
16
La presente corresponde a Acces 2000

AÑO 2003 Página 90 de 96


SQL Lic. Gustavo Rei

Tipo de datos Tamaño de almacenamiento Descripción


MONEY 8 bytes Un número entero comprendido entre
– 922.337.203.685.477,5808 y 922.337.203.685.477,5807.
DATETIME 8 bytes Una valor de fecha u hora entre los años 100 y 9999
(Vea DOUBLE)
UNIQUEIDENTIFIER 128 bits Un número de identificación único utilizado con llamadas a procedi-
mientos remotos.
REAL 4 bytes Un valor de coma flotante de precisión simple con un intervalo com-
prendido entre – 3,402823E38 y – 1,401298E-45 para valores nega-
tivos, y desde 1,401298E-45 a 3,402823E38 para valores positivos,
y 0.
FLOAT 8 bytes Un valor de coma flotante de precisión doble con un intervalo com-
prendido entre – 1,79769313486232E308 y – 4,94065645841247E-
324 para valores negativos, y desde 4,94065645841247E-324 a
1,79769313486232E308 para valores positivos, y 0.
SMALLINT 2 bytes Un entero de tipo Short (corto) entre – 32.768 y 32.767. (Consulte
las notas).
INTEGER 4 bytes Un entero de tipo Long (largo) entre – 2.147.483.648 y
2.147.483.647. (Consulte las notas).
DECIMAL 17 bytes Un tipo de datos numérico exacto con valores comprendidos entre
1028 - 1 y - 1028 - 1. Puede definir la precisión (1 - 28) y la escala (0
- precisión definida). La precisión y la escala predeterminadas son
18 y 0, respectivamente.
TEXT 2 bytes por carácter. (Consulte Desde cero hasta un máximo de 2.14 gigabytes.
las notas).
IMAGE Lo que se requiera Desde cero hasta un máximo de 2.14 gigabytes. Se utiliza para
objetos OLE.
CHARACTER 2 bytes por carácter. (Consulte Desde cero a 255 caracteres.
las notas).

AÑO 2003 Página 91 de 96


SQL Lic. Gustavo Rei

NOTA DEL AUTOR............................................................................................................................................................................................ 1

CAPITULO 1 – CONCEPTOS GENERALES .................................................................................................................................................. 2

BASE DE DATOS Y MODELOS DE DATOS: .......................................................................................................................................................... 2


Objetivos de los sistemas de gestión de base de datos:................................................................................................................................... 2
Sublenguajes Del SQL.:.................................................................................................................................................................................. 2
Objetivos S.G.B.D.: ........................................................................................................................................................................................ 2
Gestión De Los Accesos Concurrentes:.......................................................................................................................................................... 2
CONCEPCIÓN DE UNA BASE DE DATOS: ............................................................................................................................................................... 2
PROBLEMAS ADQUIRIDOS POR UNA MALA CONCEPCIÓN DE UNA BASE DE DATOS: .............................................................................................. 2
ESTRUCTURA BÁSICA DEL LENGUAJE DE PROGRAMACIÓN SQL.:........................................................................................................................ 3
¿QUÉ ES EL SQL? ............................................................................................................................................................................................... 3
CARACTERÍSTICAS DEL LENGUAJE ...................................................................................................................................................................... 3
¿EXISTE UN SOLO SQL?...................................................................................................................................................................................... 3
COMPOSICIÓN DEL LENGUAJE............................................................................................................................................................................. 4

CAPITULO 2 – INTRODUCCIÓN AL LENGUAJE........................................................................................................................................ 5

PRIMEROS COMANDOS ........................................................................................................................................................................................ 5


CONSULTAS SIMPLES .......................................................................................................................................................................................... 5
select............................................................................................................................................................................................................... 5
from ................................................................................................................................................................................................................ 5
FROM especificación de tabla........................................................................................................................................................................ 5
alias de tabla .................................................................................................................................................................................................. 5
IN.................................................................................................................................................................................................................... 6
Columnas (campos) ........................................................................................................................................................................................ 6
asterisco ......................................................................................................................................................................................................... 6
Alias de columna. ........................................................................................................................................................................................... 6
Columnas calculadas...................................................................................................................................................................................... 6
Formar expresiones........................................................................................................................................................................................ 6
Operadores..................................................................................................................................................................................................... 6
Access......................................................................................................................................................................................................... 6
SQL Server ................................................................................................................................................................................................. 7
Operadores aritméticos ........................................................................................................................................................................... 7
Operadores BIT a BIT ............................................................................................................................................................................ 7
Operadores de comparación.................................................................................................................................................................... 7
Operadores lógicos ................................................................................................................................................................................. 8
Funciones.................................................................................................................................................................................................... 8
Access..................................................................................................................................................................................................... 8
SQL Server ............................................................................................................................................................................................. 8
Funciones de agregado........................................................................................................................................................................ 8
Funciones de fecha y hora................................................................................................................................................................... 8
Funciones matemáticas ....................................................................................................................................................................... 9
Funciones de cadena ........................................................................................................................................................................... 9
Observaciones:........................................................................................................................................................................................ 9
ORDENACIÓN DE LAS FILAS - ORDER BY ........................................................................................................................................................... 9
EJEMPLOS DE SELECT: ........................................................................................................................................................................................ 9
SELECCIÓN DE FILAS LAS CLÁUSULAS DISTINCT / ALL ................................................................................................................................. 10
LA CLÁUSULA TOP........................................................................................................................................................................................... 10
LA CLÁUSULA WHERE .................................................................................................................................................................................... 10
Operador AND ............................................................................................................................................................................................. 11
Operador OR................................................................................................................................................................................................ 11
Operador NOT. ............................................................................................................................................................................................ 11
CONDICIONES DE SELECCIÓN ............................................................................................................................................................................ 11
El test de comparación. ................................................................................................................................................................................ 11

AÑO 2003 Página 92 de 96


SQL Lic. Gustavo Rei

Test de rango (BETWEEN)........................................................................................................................................................................... 11


Test de pertenencia a conjunto (IN).............................................................................................................................................................. 11
Test de valor nulo (IS NULL) ....................................................................................................................................................................... 11
Test de correspondencia con patrón (LIKE)................................................................................................................................................. 12
Resumen Operadores.................................................................................................................................................................................... 12

CAPITULO 3 – LAS CONSULTAS MULTITABLA ..................................................................................................................................... 14

CONCEPTOS GENERALES .................................................................................................................................................................................. 14


La unión de tablas ........................................................................................................................................................................................ 14
La composición de tablas ............................................................................................................................................................................. 14
APLICACIÓN DE LOS CONCEPTOS GENERALES .................................................................................................................................................. 15
El operador UNION ..................................................................................................................................................................................... 15
El producto cartesiano ................................................................................................................................................................................. 16

CAPITULO 4 – COMPOSICIONES EFICIENTES ....................................................................................................................................... 18

EL INNER JOIN ............................................................................................................................................................................................... 18


EL LEFT JOIN Y RIGHT JOIN......................................................................................................................................................................... 18
EXPLICACIÓN DE SQL SERVER ® ..................................................................................................................................................................... 20
Columnas de combinación............................................................................................................................................................................ 20
Columnas relacionadas ................................................................................................................................................................................ 20
Columnas no relacionadas ........................................................................................................................................................................... 21
Tipos de combinaciones................................................................................................................................................................................ 21
Combinación interna................................................................................................................................................................................. 21
Combinación externa ................................................................................................................................................................................ 21
Combinación externa izquierda ............................................................................................................................................................ 21
Combinación externa derecha............................................................................................................................................................... 21
Combinación externa completa............................................................................................................................................................. 22
Combinación cruzada ........................................................................................................................................................................... 22
Operadores de comparación JOIN ............................................................................................................................................................ 22
Coincidencia en igualdad...................................................................................................................................................................... 22
Otros ..................................................................................................................................................................................................... 22
Combinar tres o más tablas....................................................................................................................................................................... 22
Utilizar una tabla sólo para combinar otras tablas..................................................................................................................................... 22
Utilizar una tabla dos veces en una consulta............................................................................................................................................. 23
Utilizar otro elemento en lugar de una tabla ............................................................................................................................................. 23

CAPÍTULO 5. LAS CONSULTAS DE RESUMEN ........................................................................................................................................ 24

INTRODUCCIÓN ................................................................................................................................................................................................. 24
FUNCIONES DE COLUMNA ................................................................................................................................................................................. 24
Selección en el origen de datos..................................................................................................................................................................... 26
Origen múltiple............................................................................................................................................................................................. 26
LA CLÁUSULA GROUP BY............................................................................................................................................................................... 27
LA CLÁUSULA HAVING................................................................................................................................................................................... 28
RESUMEN DEL TEMA ......................................................................................................................................................................................... 28

CAPÍTULO 6. LAS SUBCONSULTAS............................................................................................................................................................ 30

DEFINICIONES ................................................................................................................................................................................................... 30
REFERENCIAS EXTERNAS .................................................................................................................................................................................. 30
¿Qué pasa cuando se ejecuta la consulta principal?.................................................................................................................................... 30
ANIDAR SUBCONSULTAS ................................................................................................................................................................................... 30
SUBCONSULTA EN LA LISTA DE SELECCIÓN....................................................................................................................................................... 31
EN LA CLÁUSULA FROM .................................................................................................................................................................................. 31
SUBCONSULTA EN LAS CLÁUSULAS WHERE Y HAVING ................................................................................................................................ 31
CONDICIONES DE SELECCIÓN CON SUBCONSULTAS ........................................................................................................................................... 31
El test de comparación con subconsulta....................................................................................................................................................... 32
La sintaxis es la siguiente:............................................................................................................................................................................ 32
AÑO 2003 Página 93 de 96
SQL Lic. Gustavo Rei

El test de comparación cuantificada.......................................................................................................................................................... 32


El test ANY. ......................................................................................................................................................................................... 32
El test ALL. .......................................................................................................................................................................................... 32
Test de pertenencia a conjunto (IN). ..................................................................................................................................................... 33
El test de existencia EXISTS. ............................................................................................................................................................... 33
Resumen del tema..................................................................................................................................................................................... 33

CAPÍTULO 7: ACTUALIZACIÓN DE DATOS............................................................................................................................................. 35

INTRODUCCIÓN ................................................................................................................................................................................................. 35
PARA ACCESS ................................................................................................................................................................................................... 35
Insertar una fila INSERT INTO...VALUES ................................................................................................................................................... 35
Errores que se pueden producir cuando se ejecuta la sentencia INSERT INTO(Con Access):..................................................................... 36
PARA SQL SERVER ........................................................................................................................................................................................... 36
Agregar filas con INSERT ............................................................................................................................................................................ 36
INSERTAR VARIAS FILAS INSERT INTO...SELECT ......................................................................................................................................... 37
INSERTAR FILAS EN UNA NUEVA TABLA SELECT ... INTO............................................................................................................................... 38
MODIFICAR EL CONTENIDO DE LAS FILAS ( UPDATE )..................................................................................................................................... 38
La instrucción UPDATE tiene estas cláusulas principales:.......................................................................................................................... 39
SET........................................................................................................................................................................................................... 39
FROM....................................................................................................................................................................................................... 39
WHERE.................................................................................................................................................................................................... 39
Utilizar una instrucción UPDATE simple..................................................................................................................................................... 40
Utilizar la instrucción UPDATE con información de otra tabla................................................................................................................... 40
Utilizar UPDATE con la cláusula TOP en una instrucción SELECT ........................................................................................................... 41
BORRAR FILAS (DELETE) ................................................................................................................................................................................ 41
Resumen del tema ......................................................................................................................................................................................... 41
Ejemplos de SQL Server ............................................................................................................................................................................... 42
Utilizar DELETE sin parámetros.............................................................................................................................................................. 42
Utilizar DELETE en un conjunto de filas ................................................................................................................................................. 42
Utilizar DELETE en la fila actual de un cursor ........................................................................................................................................ 43
Utilizar la instrucción DELETE basada en una subconsulta o utilizar la extensión de Transact-SQL ...................................................... 43
Utilizar DELETE y SELECT con la cláusula TOP................................................................................................................................... 43

CAPÍTULO 8: EL DDL (L. DEFINICIÓN DE DATOS)................................................................................................................................ 44

CREATE DATABASE..................................................................................................................................................................................... 44
CREATE TABLE............................................................................................................................................................................................. 46
Restricciones PRIMARY KEY....................................................................................................................................................................... 48
Restricciones UNIQUE................................................................................................................................................................................. 48
Restricciones FOREIGN KEY ...................................................................................................................................................................... 49
Ejemplos....................................................................................................................................................................................................... 49
Utilizar restricciones PRIMARY KEY ..................................................................................................................................................... 49
Utilizar restricciones FOREIGN KEY...................................................................................................................................................... 49
Utilizar restricciones UNIQUE................................................................................................................................................................. 50
Utilizar restricciones CHECK................................................................................................................................................................... 50
Definiciones de tablas completas.............................................................................................................................................................. 50
Utilizar una expresión para una columna calculada .................................................................................................................................. 51
Restricciones CHECK .................................................................................................................................................................................. 51
ALTER TABLE.................................................................................................................................................................................................... 52
DROP TABLE.................................................................................................................................................................................................. 53
CREATE INDEX ............................................................................................................................................................................................. 53
DROP INDEX .................................................................................................................................................................................................. 54

CAPÍTULO 9: AVANZADOS........................................................................................................................................................................... 55

CLUSTERED | NONCLUSTERED:.......................................................................................................................................................................... 55
FUNCIONES DE FECHA ....................................................................................................................................................................................... 55
DATEADD.................................................................................................................................................................................................... 55
AÑO 2003 Página 94 de 96
SQL Lic. Gustavo Rei

DATEDIFF................................................................................................................................................................................................... 56
DATENAME ................................................................................................................................................................................................. 57
DATEPART .................................................................................................................................................................................................. 57
DAY .............................................................................................................................................................................................................. 58
SUBSTRING.................................................................................................................................................................................................... 58
Sintaxis ......................................................................................................................................................................................................... 58
Argumentos................................................................................................................................................................................................... 58
Ejemplos....................................................................................................................................................................................................... 59
Utilizar SUBSTRING con una cadena de caracteres ................................................................................................................................ 59
Utilizar SUBSTRING con datos de tipo text, ntext e image ..................................................................................................................... 59
CONVERSIÓN DE TIPOS DE DATOS ..................................................................................................................................................................... 60
CAST y CONVERT ....................................................................................................................................................................................... 61
Ejemplos....................................................................................................................................................................................................... 62
CASE ............................................................................................................................................................................................................... 63
Ejemplos....................................................................................................................................................................................................... 64
REVERSE ........................................................................................................................................................................................................ 66
RIGHT ............................................................................................................................................................................................................. 66
RTRIM ............................................................................................................................................................................................................. 67
LTRIM ............................................................................................................................................................................................................. 67
LOWER............................................................................................................................................................................................................ 67
LEFT ................................................................................................................................................................................................................ 67
ATN2 ............................................................................................................................................................................................................... 68
UPPER ............................................................................................................................................................................................................. 68
REPLICATE .................................................................................................................................................................................................... 68
COMPUTE / COMPUTE BY .................................................................................................................................................................................. 68
Conjuntos de resultados generados por COMPUTE .................................................................................................................................... 68
Ejemplos de COMPUTE............................................................................................................................................................................... 69
Comparar COMPUTE con GROUP BY ....................................................................................................................................................... 69
ELSE (IF...ELSE)............................................................................................................................................................................................. 70
IF...ELSE.......................................................................................................................................................................................................... 70
Utilizar un bloque IF...ELSE ........................................................................................................................................................................ 70
Utilizar más de un bloque IF...ELSE ............................................................................................................................................................ 71
END (BEGIN...END).................................................................................................................................................................................... 71
WHILE............................................................................................................................................................................................................. 72
Utilizar BREAK y CONTINUE con IF...ELSE y WHILE anidados............................................................................................................... 72
Utilizar WHILE en un procedimiento con cursores ...................................................................................................................................... 73
GROUPING ..................................................................................................................................................................................................... 73
ROLLUP .......................................................................................................................................................................................................... 73
CUBE ............................................................................................................................................................................................................... 74
Cubos multidimensionales ............................................................................................................................................................................ 76
INFORMES DE TABLAS DE REFERENCIAS CRUZADAS .......................................................................................................................................... 76

ANEXO 1 – PRÁCTICOS ................................................................................................................................................................................. 79

Trabajo práctico sql (1)............................................................................................................................................................................. 79


Trabajo práctico sql (2)............................................................................................................................................................................. 79
Trabajo práctico sql (3)............................................................................................................................................................................. 80
Trabajo práctico sql (4) Compendio con problemas ................................................................................................................................. 81
Trabajo práctico sql (5)............................................................................................................................................................................. 82
Trabajo práctico sql (6)............................................................................................................................................................................. 82
Trabajo práctico sql (7)............................................................................................................................................................................. 83
Trabajo práctico sql (8) Compendio con problemas- Segunda Parte......................................................................................................... 83

ANEXO 2 – TIPOS DE DATOS........................................................................................................................................................................ 89

TIPOS DE DATOS SQL SERVER................................................................................................................................................................... 89

SINÓNIMOS DE TIPOS DE DATOS CON SQL 92.................................................................................................................................................... 89

AÑO 2003 Página 95 de 96


SQL Lic. Gustavo Rei

TIPOS DE DATOS ORACLE .................................................................................................................................................................................. 90


TIPOS DE DATOS INFORMIX ............................................................................................................................................................................... 90
TIPOS DE DATOS ACCES .................................................................................................................................................................................... 90

ÍNDICE ............................................................................................................................................................................................................... 92

AÑO 2003 Página 96 de 96

S-ar putea să vă placă și