Sei sulla pagina 1di 101

n d i c e

d e t a l l a d o Unidad 5 . Consultas de resumen 5.1. Introduccin 5.2. Las funciones de agregado 5.3. La funcin COUNT 5.4. La funcin COUNT_BIG 5.5. La funcin MAX 5.6. La funcin MIN 5.7. La funcin SUM 5.8. La funcin AVG 5.9. La funcin VAR 5.10. La funcin VARP 5.11. La funcin STDEV 5.12. La funcin STDEVP 5.13. La funcin GROUPING 5.14. Agrupamiento de filas (clusula GROUP BY). 5.15. Seleccin sobre grupos de filas, la clusula HAVING

Unidad 1 . El entorno grfico SSMS 1.1. Introduccin 1.2. Instalar SQL Server 2005 1.3. Entrada al SQL Server Management Studio Introduccin a las bases de datos Ediciones de SQL Server 2005 1.4. Estructura interna de una base de datos 1.5. Crear una base de datos en SSMS 1.6. Adjuntar una base de datos 1.7. Conectar y Desconectar la base de datos 1.8. Crear una nueva tabla 1.9. Tipos de datos 1.10. Valores nulos 1.11. Columna con contador 1.12. Clave primaria 1.13. Aadir o eliminar columnas 1.14. Modificar la definicin de una tabla 1.15. Insertar datos en la tabla 1.16. Modificar datos 1.17. Eliminar filas 1.18. Relacionar tablas 1.19. Abrir una nueva consulta 1.20. Escribir y ejecutar cdigo TRANSACT-SQL 1.21. La base de datos predeterminada 1.22. El editor de texto 1.23. Configurar un esquema de colores personalizado 1.24. Las Vistas 1.25. El panel de diagrama 1.26. El panel de criterios 1.27. El panel SQL

Unidad 6 . Las subconsultas 6.1. Introduccin 6.2. Subconsultas de resultado nico 6.3. Subconsultas de lista de valores 6.4. El operador IN con subconsulta 6.5. La comparacin modificada (ANY, ALL) 6.6. Subconsultas con cualquier nmero de columnas (EXISTS)

Unidad 7 . Actualizacin de datos 7.1. Introduccin 7.2. Insertar creando una nueva tabla 7.3. Insertar en una tabla existente INSERT INTO 7.4. Insertar una fila de valores 7.5. Insercin de varias filas 7.6. Insertar una fila de valores por defecto 7.7. Modificar datos almacenados UPDATE 7.8. Eliminar filas - DELETE 7.9. Borrado masivo - TRUNCATE

Unidad 2 . Introduccin al SQL. Transact-SQL

2.1. Conceptos bsicos de SQL 2.2. Introduccin al TRANSACT-SQL 2.3. Caractersticas generales del lenguaje Transact-SQL 2.4. Reglas de formato de los identificadores 2.5. Tipos de datos Unidad 8 . El DDL, Lenguaje de Definicin de 2.6. Las constantes Datos Tipos de datos Definir constantes segn el tipo de dato 8.1. Introduccin 2.7. Las expresiones 8.2. Definir una base de datos CREATE 2.8. Funciones DATABASE 2.9. Las variables Intercalaciones COLLATE

2.10. Otros elementos del lenguaje

Unidad 3 . Consultas simples 3.1. Introduccin 3.2. Origen de datos FROM 3.3. La lista de seleccin 3.4. Columnas del origen de datos 3.5. Alias de columna 3.6. Funciones Funciones en Transact-SQL 3.7. Columnas calculadas 3.8. Utilizacin del asterisco * 3.9. Las palabras clave $IDENTITY y $ROWGUID 3.10. Ordenacin de las filas del resultado ORDER BY 3.11. Eliminar filas duplicadas DISTINCT/ALL 3.12. La clusula TOP 3.13. Seleccin de filas WHERE 3.14. Predicados Los predicados CONTAINS y FREETEXT 3.15. Condiciones de bsqueda compuestas

8.3. Eliminar una base de datos DROP DATABASE 8.4. Modificar las propiedades de una BD ALTER DATABASE 8.5. Crear una tabla CREATE TABLE Tipos de datos: precisin, escala, longitud y prioridad 8.6. Eliminar una tabla DROP TABLE 8.7. Modificar la definicin de una tabla ALTER TABLE 8.8. Crear una vista CREATE VIEW 8.9. Eliminar una vista DROP VIEW 8.10. Definicin de ndice 8.11. Tipos de ndices 8.12. Ventajas e inconvenientes de los ndices 8.13. Definir un ndice CREATE INDEX 8.14. Eliminar un ndice DROP INDEX

Unidad 9 . Programacin en TRANSACT SQL 9.1. Introduccin 9.2. Procedimientos almacenados STORE PROCEDURE 9.3. Eliminar procedimientos almacenados 9.4. Crear y ejecutar un procedimiento 9.5. Instrucciones de control de flujo 9.6. IF ELSE 9.7. WHILE BREAK- CONTINUE 9.8. WAITFOR 9.9. GOTO 9.10. TRY... CATCH 9.11. Desencadenadores o TRIGGERS 9.12. CREATE TRIGGER 9.13. DISABLE TRIGGER 9.14. ENABLE TRIGGER 9.15. DROP TRIG

Unidad 4 . Consultas multitabla 4.1. Introduccin 4.2. La unin de tablas UNION 4.3. La diferencia EXCEPT 4.4. La interseccin INTERSECT 4.5. La composicin de tablas 4.6. El producto cartesiano CROSS JOIN 4.7. La composicin interna INNER JOIN 4.8. La Composicin externa LEFT, RIGHT y FULL OUTER JOIN 4.9. Combinar varias operaciones

Unidad 1. El entorno grfico SSMS (I)


1.1. Introduccin SQL Server 2005 es un sistema gestor de bases de datos relacionales de Microsoft Corporation orientado a sistemas medianos y grandes aunque tambin puede rodar en ordenadores personales. SQL Server Management Studio (SSMS) es la herramienta de SQL Server que permite definir y gestionar todas las bases de datos almacenadas en el servidor SQL Server 2005. En este tema veremos cmo utilizar el SQL Server Management Studio para manejar las bases de datos del servidor y organizaremos el texto en los siguientes puntos:

Instalar SQL Server 2005. Entrada al SQL Server Management Studio Las bases de datos: Estructura interna, crear, adjuntar, conectar y desconectar. Las tablas: crear tablas, definirlas, modificar su contenido, etc. Relacionar tablas Las Consultas Las Vistas

Si no sabes lo que es una base de datos relacional o no tienes conocimientos previos acerca de las bases de datos, puedes leer una introduccin a las bases de datos en el siguiente bsico

1.2. Instalar SQL Server 2005

Existen diferentes versiones (ediciones) del producto, por lo que es un producto muy verstil, que puede cumplir con las exigencias de cualquier empresa, puede ser utilizado para gestionar bases de datos en un PC en modo local a gestionar todo el sistema de informacin de grandes empresas pasando por sistemas que requieran menos potencia y por sistemas mviles. Actualmente se utiliza ms en entornos Cliente/servidor con equipos medianos y grandes. Para realizar este curso te recomendamos instalar la versin gratuita: Express. Puedes descargarla desde la pgina web de Microsoft, desde el enlace para iniciar descarga. Si quieres ver las diferentes ediciones y sus caractersticas principales visita el siguiente avanzado Si la instalacin se realiza a partir del archivo descargado de Internet, la descarga se empaqueta como un nico ejecutable mediante una tecnologa de instalacin de Microsoft llamada SFXCab. Al hacer doble clic en el .exe se inicia automticamente el proceso de instalacin. Tan slo deberemos seguir el asistente. Los puntos ms importantes a tener en cuenta son: Habilitar el SQL Server Management Studio en la instalacin (si no lo est por defecto) cuando nos pregunte qu componentes deseamos instalar. Indicar que se trata de una Instancia predeterminada.

Lo ideal es que en este punto instales el programa, para ir probando lo que vayas aprendiendo de aqu en adelante. Puedes realizar el siguiente Ejercicio Instalacin de SQL Server 2005. El videotutorial prctico de instalacin tambin te ayudar. 1.3. Entrada al SQL Server Management Studio

Aunque trabajemos en modo local, la entrada a la herramienta es la misma. Para empezar entramos a travs del acceso directo o a travs de Inicio, Programas, Microsoft SQL Server 2005, SQL Server Management Studio. Lo primero que deberemos hacer es establecer la conexin con el servidor:

Seleccionamos el nombre del servidor y pulsamos el botn Conectar. Se abrir la ventana inicial del SQL Server Management Studio (en adelante SSMS):

En la parte izquierda tenemos abierto el panel Explorador de Objetos en el que aparece debajo del nombre del servidor con el que estamos conectados una serie de carpetas y objetos que forman parte del servidor. En el panel de la derecha se muestra la zona de trabajo, que vara segn lo que tengamos seleccionado en el Explorador de objetos, en este caso vemos el contenido de la carpeta que representa el servidor ord01. En la parte superior tenemos el men de opciones y la barra de herramientas Estndar.

Con las siguientes opciones:

1. Nueva consulta 2. Consulta datos 3. Consulta Services 4. Consulta Services 5. Consulta Services de motor de Base de MDX de Analysis DMX de Analysis MXLA de Analysis

6. Consulta de SQL Server Mobile 7. Abrir archivo 8. Guardar 9. Guardar todo 10. Servidores registrados

11. Resumen 12. Explorador de Objetos 13. Explorador de Plantillas 14. Ventana de Propiedades

En caso de que utilices la versin Express, es posible que no dispongas de algunos de stos botones.

Unidad 1. El entorno grfico SSMS (II)


1.4. Estructura interna de una base de datos Antes de empezar tenemos que tener claro cmo se organiza la informacin en una base de datos SQL Server 2005. Las bases de datos de SQL Server 2005 utilizan tres tipos de archivos: Archivos de datos principales En una base de datos SQLServer los datos se pueden repartir en varios archivos para mejorar el rendimiento de la base de datos. El archivo de datos principal es el punto de partida de la base de datos y apunta a los otros archivos de datos de la base de datos. Cada base de datos tiene obligatoriamente un archivo de datos principal. La extensin recomendada para los nombres de archivos de datos principales es .mdf. Archivos de datos secundarios Los archivos de datos secundarios son todos los archivos de datos menos el archivo de datos principal. Puede que algunas bases de datos no tengan archivos de datos secundarios, mientras que otras pueden tener varios archivos de datos secundarios. La extensin de nombre de archivo recomendada para los archivos de datos secundarios es .ndf. Adems los archivos de datos se pueden agrupar en grupos de archivos. Para cada base de datos pueden especificarse hasta 32.767 archivos y 32.767 grupos de archivos. Archivos de registro Los archivos de registro (archivos de log) almacenan toda la informacin de registro que se utiliza para recuperar la base de datos, el tambin denominado registro de transacciones. Como mnimo, tiene que haber un archivo de registro por cada base de datos, aunque puede haber varios. La extensin recomendada para los nombres de archivos de registro es .ldf.

SQL Server 2005 no exige las extensiones de nombre de archivo .mdf, .ndf y .ldf, pero estas extensiones ayudan a identificar las distintas clases de archivos y su uso. Cada base de datos tiene al menos 2 archivos (un archivo de datos principal y un archivo de registro) y opcionalmente un grupo de archivos. Los archivos de datos y de registro de SQL Server se pueden colocar en sistemas de archivos FAT o NTFS. Se recomienda utilizar NTFS por los aspectos de seguridad que ofrece. No se

pueden colocar grupos de archivos de datos de lectura y escritura, y archivos de registro, en un sistema de archivos NTFS comprimido. Slo las bases de datos de slo lectura y los grupos de archivos secundarios de slo lectura se pueden colocar en un sistema de archivos NTFS comprimido. 1.5. Crear una base de datos en SSMS En el Explorador de objetos, si desplegamos la carpeta Bases de datos nos aparecen Bases de datos del sistema y las bases de datos de usuario despus de la carpeta Instantneas...

Despus de la instalacin, en la carpeta Bases de datos del sistema se habr creado una especial denominada master se utiliza como base de datos de usuario por defecto. Las dems bases de datos forman tambin parte del diccionario de datos y las utiliza el sistema para llevar a cabo su gestin.

Las bases de datos de los usuarios se deben crear preferentemente fuera de la carpeta Bases de datos del sistema.

Unidad 1. El entorno grfico SSMS (III)


Para crear una nueva base de datos de usuario nos posicionamos sobre la carpeta Bases de datos y con el botn derecho del ratn desplegamos el men contextual del que elegimos la opcin Nueva base de datos

Se abre a continuacin el cuadro de dilogo donde definiremos la base de datos que queremos crear:

Lo mnimo a introducir ser el campo Nombre de la base de datos, ste es el nombre de la base de datos lgica, la base de datos a la que nos referiremos dentro del SSMS, a nivel conceptual (en la imagen Mibase). Esta base de datos est asociada a dos archivos fsicos, en la parte inferior aparecen esos archivos. Para facilitarnos la tarea, al teclear el nombre de la bd lgica, se rellenan automticamente los nombres de los archivos fsicos, el de datos con el mismo nombre y el del archivo de registro con el mismo nombre seguido de _log. Estos nombres son los nombres que se asumen por defecto pero los podemos cambiar, posicionando el cursor en el nombre y cambindolo. Para cada archivo fsico podemos definir una serie de parmetros como el tipo de archivo (si es de datos o de transacciones Registro) y su ocupacin inicial (Tamao inicial). Si no indicamos ninguna ubicacin podemos ver que los guarda en la carpeta del SQL Server/MSSQL.n/MSSQL/DATA. n representa un nmero que puede variar de una instalacin a otra.

Estos son los archivos mnimos en los que se almacenar la base de datos, pero como ya vimos anteriormente se puede almacenar en ms archivos, los tenemos que definir todos en esta ventana a continuacin de los dos obligatorios. Para aadir ms archivos fsicos disponemos del botn Agregar. Al pulsar el botn Agregar se crea una nueva fila en la tabla de archivos fsicos donde deberemos escribir el nombre del archivo, su tipo (desplegando la lista podemos elegir entre de datos o de registro) y dems parmetros.

Al agregar un nuevo archivo se activa el botn Quitar, siempre que estemos posicionados encima de un archivo secundario para poder as eliminarlo si lo queremos.

No podemos eliminar ni el de datos primario, ni el de registro inicial. Unidad 1. El entorno grfico SSMS (IV) Si nos fijamos en la zona de la izquierda, vemos que nos encontramos en la pestaa General, podemos cambiar otros parmetros de la base de datos pulsando en Grupos de archivos o en Opciones:

Al final pulsamos en Aceptar y se crear la base de datos.

Aparecer dentro de la carpeta Bases de datos. Si no se ve pulsa en el icono Actualizar

Desde el Explorador de Windows podemos ver que en la carpeta indicada se han creado los archivos fsicos con los nombres que le hemos indicado.

Unidad 1. El entorno grfico SSMS (V) 1.6. Adjuntar una base de datos En ocasiones no necesitaremos crear la base de datos desde cero, porque sta ya estar creada. ste es el caso de los ejercicios del curso. Para realizarlos, debers adjuntar una base de datos ya existente a tu servidor. Para ello, lo que tenemos que hacer es pegar los archivos en la ubicacin que queramos, y luego indicar al SQL Server que vamos a utilizar esta base de datos, de la siguiente manera: En el Explorador de objetos, sobre la carpeta Bases de datos desplegar el men contextual y elegir Adjuntar...

En la siguiente ventana elegimos la base de datos:

10

Pulsando en Agregar indicamos el archivo de datos primario en su ubicacin y automticamente se adjuntar la base de datos lgica asociada a este archivo.

Finalmente pulsamos en Aceptar y aparece la base de datos en nuestro servidor.

11

La opcin Adjuntar slo se utiliza la primera vez, cuando todava no tenemos la base de datos en el disco. Realiza el siguiente Ejercicio Adjuntar base de datos. En l adjuntars las bases de datos que vas a utilizar en los ejercicios que se plantearn ms adelante. 1.7. Conectar y Desconectar la base de datos Una vez hemos creado la base de datos o la hemos adjuntado a nuestro servidor, nos daremos cuenta de que no podremos manipular los archivos de la base desde fuera del gestor SSMS, por ejemplo, desde el Explorador de Windows. Es decir, no podremos copiar, cortar, mover o eliminar los archivos fuente mdf, ndf y ldf. Si lo intentamos se mostrar un aviso de que la base de datos est en uso. sto es as porque SQL Server sigue en marcha, a pesar de que se cierre el gestor. Ten en cuenta que el servidor de base de datos normalmente se crea para que sirva informacin a diferentes programas, por eso sera absurdo que dejara de funcionar cuando cerramos el programa gestor, que slo se utiliza para realizar modificaciones sobre la base. Para poder realizar acciones sobre la base de datos, sta debe estar desconectada. Para ello, desde el SSMS, desplegamos el men contextual de la base de datos que nos interese manipular y seleccionaremos la opcin Poner fuera de conexin:

Aparecer un smbolo a la izquierda de la base de datos indicndonos que la base de datos est desconectada, a partir de este momento Windows nos dejar manipular los archivos. Para volver a conectar la base de datos y seguir trabajando con ella, accederemos al mismo men contextual pero elegiremos la opcin Poner en conexin:

12

El caso ms inmediato en el que puedes necesitar conectar y desconectar la base de datos es copiar a un pendrive los archivos de las bases que utilizars en los ejercicios para poder trabajar en diferentes ordenadores con ellos. Para aprender cmo hacerlo, visita el siguiente Ejercicio Trasladar una base de datos a otro equipo. En caso de que tu versin de SQL Server no tenga las opciones Poner en conexin y Poner fuera de conexin, debers utilizar la opcin Separar... y luego volver a adjuntarla.

Unidad 1. El entorno grfico SSMS (VI)


1.8. Crear una nueva tabla

Para crear una nueva tabla primero nos tenemos que posicionar en la base de datos donde queremos que se almacene la tabla, desplegar el men contextual y seleccionar la opcin Nueva tabla.

En la ventana que se abre debemos definir las columnas de la tabla:

13

A cada columna se le asigna un nombre, un tipo de datos, y opcionalmente una serie de propiedades, en este tema veremos las bsicas y las dems las veremos con ms detalle cuando veamos la instruccin SQL CREATE TABLE. De momento no tenemos definida ninguna columna, al teclear un nombre se crea una primera entrada en esta tabla con la definicin de la primera columna. En la columna Tipo de datos elegimos qu tipo de valores se podrn almacenar en la columna. 1.9. Tipos de datos

Podemos elegir entre todos los tipos que aparecen arriba. Algunos tipos no necesitan ms, como por ejemplo el tipo entero (int), y otros se pueden completar con una longitud, como los tipos alfanumricos:

En este ejemplo hemos definido una columna (Codigo) de tipo Entero corto (Smallint), y una columna (Nombre) que almacenar hasta 20 caracteres alfanumricos (nchar(20)), en este caso la longitud la indicamos en la pestaa Propiedades de columna en la propiedad Longitud. Las propiedades de la columna pueden variar dependiendo del tipo de datos de la columna seleccionada, por ejemplo los campos enteros no tienen la propiedad longitud, ya que el propio tipo define la longitud del campo, en cambio los campos de tipo numeric o decimal no tiene la propiedad longitud pero s las propiedades escala y precisin, los valores que permiten definir el tamao del campo.

14

Unidad 1. El entorno grfico SSMS (VII)


1.10. Valores nulos Tambin podemos indicar si la columna permitir valores nulos o no, o bien cambiando la propiedad Permitir valores nulos que aparece debajo de la propiedad Longitud, o bien simplemente marcando o desmarcando la casilla de la columna Permitir valores nulos que se encuentra al lado de la columna Tipo de datos. Si la casilla est marcada, el usuario podr no rellenar el campo cuando inserte una fila de datos en la tabla. 1.11. Columna con contador

En la mayora de los sistemas gestores de bases de datos tenemos un tipo de datos de tipo contador, autonumrico, autoincremental, etc. Este tipo hace que el propio sistema es el encargado de rellenar el campo con un valor que va incrementando conforme se crean ms filas de datos en la tabla. Las columnas de este tipo se utilizan normalmente para numerar las filas de la tabla, como no habrn dos filas con el mismo valor (el sistema se encarga de incrementar el valor cada vez que se crea una nueva fila), estos campos se suelen utilizar como claves primarias. En SQL Server 2005 no existe el tipo de datos Contador pero se consigue el mismo funcionamiento asignando a la columna un tipo de datos numrico y definiendo la columna como columna de identidad. En las propiedades de la columna marcamos S en la propiedad (Identidad) y a continuacin podemos indicar en qu valor queremos que empiece el contador (Inicializacin de identidad) y en cunto incrementar cada vez que se cree un nuevo registro (Incremento de identidad). Aunque este tipo de columnas se utiliza frecuentemente como clave primaria, SQL Server no le asigna automticamente esta funcin, la tenemos que definir nosotros mismos, pero s fuerza a que sea una columna sin valores nulos. No se puede definir ms de una columna de identidad por tabla.

15

1.12. Clave primaria Para definir una columna como clave primaria, posicionamos el puntero del ratn sobre la columna, desplegamos el men contextual y seleccionamos la opcin Establecer Clave principal:

Aparecer una llave a la izquierda del nombre, smbolo de las claves principales:

Para definir una clave primaria compuesta por varias columnas, seleccionamos las columnas manteniendo pulsada la tecla Ctrl y luego seleccionamos la opcin. Para quitar una clave principal, hacemos lo mismo pero en esta ocasin seleccionamos la opcin Quitar clave principal.

Tambin podemos utilizar el icono de la barra de herramientas.

Unidad 1. El entorno grfico SSMS (VIII)


1.13. Aadir o eliminar columnas Una vez definidas algunas columnas, si queremos aadir una nueva columna entre dos, nos posicionamos en la segunda y seleccionamos la opcin Insertar columna del men contextual.

La nueva columna se colocar delante:

16

Del mismo modo si queremos eliminar la definicin de una columna, nos posicionamos en la columna a eliminar y seleccionamos la opcin Eliminar columna:

O simplemente hacemos clic en la zona a la izquierda del nombre y pulsamos la tecla Supr. Finalmente guardamos la tabla, nos pedir el nombre de la tabla:

La nueva tabla aparecer en la lista de tablas de la base de datos:

1.14. Modificar la definicin de una tabla Para entrar a la ventana de definicin de la tabla utilizamos la opcin Modificar de su men contextual (Tambin es posible que se llame Diseo):

17

Se abrir la ventana que ya conocemos para definir las columnas de la tabla.

Unidad 1. El entorno grfico SSMS (IX) 1.15. Insertar datos en la tabla Ahora que tenemos la tabla creada podemos rellenarla con datos. Para eso debemos abrir la tabla:

Se abrir una ventana parecida a esta:

La primera columna sirve para indicarnos el estado de una fila, por ejemplo el * nos indica que es una nueva fila, esta fila realmente no est en la tabla, nos sirve de contenedor para los nuevos datos que queremos insertar. Para insertar una nueva fila de datos slo tenemos que rellenar los campos que aparecen en esa fila (la del *), al cambiar de fila los datos se guardarn automticamente en la tabla a no ser que alguno infrinja alguna regla de integridad, en ese caso SQL Server nos devuelve un mensaje de error para que corrijamos el dato errneo, si no lo podemos corregir entonces slo podemos deshacer los cambios. 1.16. Modificar datos Para modificar un valor que ya est en una fila de la tabla slo tenemos que posicionarnos en el campo y rectificar el valor. En cuanto modificamos un valor, la fila aparece con un lpiz escribiendo (ver imagen), este lpiz nos indica que la fila se ha modificado y tiene nuevos datos por guardar. Al salir de la fila sta se guardar automticamente a no ser que el nuevo valor infrinja alguna regla de integridad. Si queremos salir de la fila sin guardar los cambios, tenemos que cancelar la actualizacin pulsando la tecla ESC.

18

1.17. Eliminar filas Para eliminar una fila completa, la seleccionamos y pulsamos la tecla Supr o bien desplegamos

su men contextual y seleccionamos la opcin Eliminar. En cualquiera de los dos casos nos aparece un mensaje de confirmacin.

1.18. Relacionar tablas

Como ya hemos visto, en una base de datos relacional, las relaciones entre las tablas se implementan mediante la definicin de claves ajenas, que son campos que contienen valores que sealan a un registro en otra tabla, en esta relacin as creada, la tabla referenciada se considera principal y la que contiene la clave ajena es la subordinada. Desde el entorno grfico del SSMS podemos definir claves ajenas entrando en el diseo de la tabla y desplegando el men contextual del campo que va a ser clave ajena:

Seleccionamos la opcin Relaciones y se abre la ventana:

19

Al pulsar el botn que se encuentra en la fila Especificacin de tablas y columnas se abre el dilogo donde definiremos la relacin:

Unidad 1. El entorno grfico SSMS (X) En la parte derecha tenemos la tabla en la que estamos y el campo que va a actuar como clave ajena, slo nos queda elegir en el desplegable de la izquierda la tabla a la que hace referencia la clave y al seleccionar una tabla, a la izquierda del campo clave ajena podremos elegir el campo de la otra tabla por el que se relacionarn las tablas. En nuestro caso ser:

De esta forma hemos definido una relacin entre las tablas Facturas y Clientes. Para ver las relaciones existentes entre las diferentes tablas tenemos los diagramas. Primero debemos definir el diagrama, para ello seleccionamos la opcin correspondiente:

20

Si no tenemos todava ningn diagrama creado, nos aparece un mensaje:

Elegimos S y se crea digamos el soporte donde se pintar el diagrama. A continuacin nos aparece el nuevo diagrama ahora si elegimos crear un nuevo diagrama nos preguntar las tablas a incluir en el diagrama:

Seleccionamos cada una y pulsamos Agregar, cuando hayamos agregado al diagrama todas las que queremos pulsamos en Cerrar y aparecern en el diagrama las tablas con las relaciones que tengan definidas en ese momento:

21

La llave indica la tabla principal (padre) y el smbolo infinito seala la tabla que contiene la clave ajena. En el examinador de objetos en la carpeta Diagramas de base de datos aparecen todos los diagramas definidos hasta el momento:

Hemos aprendido hasta ahora lo bsico para poder crear una base de datos y rellenarla con tablas relacionadas entre s y con datos, ahora veamos cmo recuperar esos datos.

Unidad 1. El entorno grfico SSMS (XI)


1.19. Abrir una nueva consulta Vamos a ver ahora cmo crear consultas SQL y ejecutarlas desde el entorno del SSMS. Para ello debemos abrir la zona de trabajo de tipo Query, abriendo una nueva consulta, seleccionando previamente el servidor y pulsando el botn de la barra de botones o si queremos realizar la consulta sobre un servidor con el cual todava no hemos establecido conexin, seleccionando de la barra de mens la opcin Nuevo > Consulta de motor de base de datos:

. En este ltimo caso nos aparecer el cuadro de dilogo para establecer la conexin (el mismo que vimos al principio del tema). A continuacin se abrir una nueva pestaa donde podremos teclear las sentencias SQL:

22

Adems aparece una nueva barra de botones que nos permitir ejecutar los comandos ms tiles del modo query. 1.20. Escribir y ejecutar cdigo TRANSACT- SQL

Slo tenemos que teclear la sentencia a ejecutar, por ejemplo empezaremos por crear la base de datos. Utilizaremos la sentencia CREATE DATABASE mnima: CREATE DATABASE ventas; Al pulsar el botn Ejecutar se ejecuta la sentencia y aparece en la parte inferior el resultado de la ejecucin, en la pestaa Mensajes:

Si ahora desplegamos la carpeta Bases de Datos del Explorador de Objetos, observaremos la base de datos que hemos creado:

23

Si la ejecucin de la sentencia produce un error, el sistema nos devolver el mensaje de error escrito en rojo en la pestaa Mensajes. Podemos incluir en una misma consulta varias sentencias SQL, cuando pulsamos Ejecutar se ejecutarn todas una detrs de otra. Si tenemos varias consultas y slo queremos ejecutar una, la seleccionaremos antes de ejecutarla.

Unidad 1. El entorno grfico SSMS (XII)


1.21. La base de datos predeterminada Cuando ejecutamos consultas desde el editor, nos tenemos que fijar sobre qu base de datos se va a actuar. Fijndonos en la pestaa de la consulta, en el nombre aparece el nombre del servidor seguido de un punto y el nombre de la base de datos sobre la que se va a actuar y luego un guin y el nombre de la consulta. En la imagen anterior tenemos ord01.master SQLQuery1.sql, lo que nos indica que la consulta se llama SQLQuery1.sql, y que se va a ejecutar sobre la base de datos master que se encuentra en el servidor ord01. Cuando creamos una nueva consulta, sta actuar sobre la base de datos activa en ese momento. Por defecto la base de datos activa es la predeterminada (master). Si queremos que la base de datos activa sea por ejemplo la base de datos ventas, hacemos clic sobre su nombre en el Explorador de objetos, y sta pasar a ser la base de datos activa. Si ahora creamos una nueva consulta, sta actuar sobre la base de datos ventas. Si queremos crear una consulta que siempre acte sobre una determinada base de datos y no nos queremos preocupar de qu base de datos tenemos activa podemos aadir al principio de la consulta la instruccin USE nombreBaseDatos; esto har que todas las instrucciones que aparezcan despus, se ejecuten sobre la base de datos indicada.

24

Por ejemplo: USE ventas; SELECT * FROM pedidos; Obtiene todos los datos de la tabla pedidos que se encuentra en la base de datos ventas. Si no utilizamos USE y almacenamos la consulta, al abrirla otra vez, coger como base de datos la predeterminada (no la activa) y se volver a ejecutar sobre la base de datos master. Normalmente utilizaremos como base de datos la nuestra y no la base de datos master, por lo que nos ser til cambiar el nombre de la base de datos por defecto, esto lo podemos hacer cambiando la base de datos por defecto en el id de sesin. Para ello, cuando vamos a conectar con el servidor:

Pulsamos en el botn Opciones >>

25

En la pestaa Propiedades de conexin, en el cuadro Conectar con base de datos: Seleccionamos <Examinar servidor > para elegir la base de datos.

La elegimos y aceptamos. A partir de ese momento la base de datos elegida ser la que SQL Server coja por defecto en todas las sesiones de ese usuario.

Unidad 1. El entorno grfico SSMS (XIII)


1.22. El editor de texto Para facilitarnos la redaccin y correccin de las sentencias, el editor de SQL presenta las palabras de distintos colores segn su categora y podemos utilizar el panel Explorador de Objetos para arrastrar desde l los objetos sobre la zona de trabajo y as asegurarnos de que los nombres de los objetos (por ejemplo nombre de tabla, de columna, etc.) sean los correctos. Como hemos dicho el texto que se escribe en este editor de cdigo se colorea por categora. Los colores son los mismos que se utilizan en todo el entorno SQL Server. En esta tabla aparecen los colores ms comunes. Color Categora Rojo Cadena de caracteres Verde oscuro Comentario Negro sobre fondo plateado Comando SQLCMD Fucsia Funcin del sistema Verde Tabla del sistema Azul Palabra clave Verde azulado Nmeros de lnea o parmetro de plantilla Rojo oscuro Procedimiento almacenado de SQL Server Gris oscuro Operadores 1.23. Configurar un esquema de colores personalizado

26

En el men Herramientas > Opciones, desplegando la opcin Entorno, Fuentes y colores, se puede ver la lista completa de colores y sus categoras, as como configurar un esquema de colores personalizado:

En la lista Mostrar valores para, seleccionamos el entorno que se ver afectado. El botn Usar predeterminados nos permite volver a la configuracin predeterminada. Ahora slo nos queda aprender a redactar sentencias SQL, cosa que se ver en otro momento, mientras tanto podemos utilizar el Generador de Consulta que incluye SSMS y que veremos a continuacin en el apartado sobre vistas. 1.24. Las Vistas Las consultas que hemos visto hasta ahora son trozos de cdigo SQL que podemos guardar en un archivo de texto y abrir y ejecutar cuando queramos, pero si queremos que nuestra consulta de recuperacin de datos se guarde en la propia base de datos y se comporte como una tabla (algo parecido a una consulta almacenada de Access), la tenemos que definir como una vista. Esta vista tiene la ventaja entre otras de poder ser utilizada como si fuese una tabla en otras consultas. Realmente al ejecutarla obtenemos una tabla lgica almacenada en memoria y lo que se guarda en la base de datos es su definicin, la instruccin SQL que permite recuperar los datos.

27

Para definir una vista en el Explorador de Objetos desplegamos la base de datos donde la guardaremos y elegimos la opcin Nueva vista del men contextual de la carpeta Vistas, se pondr en funcionamiento el generador de consultas pidindonos las tablas en las que se basar la vista. Pulsamos sobre la tabla a aadir al diseo de la vista y pulsamos el botn Agregar, podemos aadir as cuntas tablas queramos. Despus de Cerrar, vemos a la derecha del Explorador de Objetos la pestaa con la definicin de la vista que puede incluir varios paneles:

28

La aparicin de estos paneles es configurable, en la barra de herramientas Diseador de vistas los iconos remarcados en azul son los correspondientes a cada panel:

29

Unidad 1. El entorno grfico SSMS (XIV)


Nosotros, a lo largo del curso, crearemos las vistas desde el panel SQL que veremos ms adelante. 1.25. El panel de diagrama Es el primero que aparece, incluye una representacin grfica de las tablas con sus campos y de la forma en que se juntan en la vista. En este caso, como las tablas tienen relaciones definidas (claves ajenas), esta relacin ha aparecido automticamente al aadir la segunda tabla. Pero se puede cambiar el tipo de relacin eligiendo la opcin correspondiente en el men contextual que aparece con el clic derecho sobre la relacin:

Desde el panel diagrama podemos aadir cmodamente campos de las tablas a la consulta marcando la casilla correspondiente. En la imagen anterior la nica casilla seleccionada es la del * en la tabla Libros por lo que se visualizarn todas las columnas de la tabla Libros y ninguna de la tabla Prstamos. Conforme vamos marcando casillas de las tablas del panel diagrama, los cambios se ven reflejados en los dems paneles excepto en el panel de resultados que se actualiza ejecutando la consulta. 1.26. El panel de criterios Es una rejilla en la que podemos definir las columnas del resultado de la consulta (las columnas de la vista).

En cada fila de la rejilla se define una columna del resultado o una columna que se utiliza para obtener el resultado. En Columna tenemos el nombre de la columna de la se obtienen los datos o la expresin cuando se trata de una columna calculada. En Alias escribimos el nombre que tendr la columna en la vista, tambin corresponde con el encabezado de la columna en la rejilla de resultado. Si se deja el campo en blanco, por defecto se asume el mismo nombre que hay en Columna. En Tabla tenemos el nombre de la tabla del origen de la consulta a la que pertenece la Columna, por ejemplo la primera columna del resultado se saca de la columna Codigo de la tabla LIBROS y se llamar CodLibro. La cuarta columna de la vista coger sus

30

datos de la columna Usuario de la tabla Prestamos y se llamar Usuario (Alias se ha dejado en blanco por lo que asume el nombre que hay en Columna. En la columna Resultados indicamos si queremos que la columna se visualice o no, las columnas con la casilla marcada se visualizan. Las columnas Criterio de ordenacin y Tipo de orden permiten ordenar las filas del resultado segn una o ms columnas. Se ordena por las columnas que tienen algo en Tipo de orden y cuando se ordena por varias columnas Criterio de ordenacin indica que primero se ordena por la columna que lleva el n 1 y despus por la columna que lleva el n 2 y as sucesivamente. En el ejemplo las filas del resultado se ordenarn primero por cdigo de libro y despus por cdigo de prstamo, todas las filas dentro del mismo libro se ordenarn por cdigo de prstamo.

Si queremos aadir unos criterios de seleccin tenemos las columnas Filtro y O

En cada celda indicamos una condicin que debe cumplir la columna correspondiente y se puede combinar varias condiciones mediante O (OR) e Y (AND) segn coloquemos las condiciones en la misma columna o en columnas diferentes. En el ejemplo anterior tenemos la condicin compuesta: ((usuario=1) AND (Dias>5)) OR (Usuario=2). Podemos variar el orden de aparicin de las columnas arrastrando la fila correspondiente de la rejilla hasta el lugar deseado. Tambin podemos Elimnar filas de la rejilla para eliminar columnas del resultado, lo conseguimos seleccionando la fila haciendo clic sobre su extremo izquierda y cuando aparece toda la fila remarcada pulsamos Supr o desde el men contextual de la fila. Podemos definir consultas ms complejas como por ejemplo consultas de resumen, pulsando sobre el botn Agrupar por de la barra de herramientas, se aade a la rejilla una nueva columna Agrupar por con las siguientes opciones:

31

Unidad 1. El entorno grfico SSMS (XV)


1.27. El panel SQL En l vemos la instruccin SQL generada, tambin podemos redactar directamente la sentencia SQL en el panel y ver los cambios equivalentes en los distintos paneles. Para ver estos cambios debemos de ejecutar o Comprobar la sintaxis para que se actualicen los dems paneles. Por defecto el generador aade a la consulta una clusula TOP (100) PERCENT que indica que se visualizarn el 100% de las filas. Esta clusula no la hemos definido nosotros sino que la aade automticamente el generador.

Una vez tenemos la vista definida la guardamos y podremos hacer con ella casi todo lo que podemos hacer con una tabla. De hecho si nos fijamos en el Explorador de objetos, en la carpeta Vistas:

Vemos que la estructura es muy similar a la estrutura de una tabla. Y que podemos modificar su definicin y ejecutarla, igual que con las tablas: Modificar para modificar la definicin de la vista

32

Abrir vista para ejecutarla y ver los datos como si fuese una tabla real. Prueba evaluativa de la Unidad 1

Ejercicio propuesto de la Unidad 1

Unidad 2. Introduccin al SQL. Transact-SQL (I)


2.1. Conceptos bsicos de SQL SQL (Structured Query Language), Lenguaje Estructurado de Consulta es el lenguaje utilizado para definir, controlar y acceder a los datos almacenados en una base de datos relacional. Como ejemplos de sistemas gestores de bases de datos que utilizan SQL podemos citar DB2, SQL Server, Oracle, MySql, Sybase, PostgreSQL o Access. El SQL es un lenguaje universal que se emplea en cualquier sistema gestor de bases de datos relacional. Tiene un estndar definido, a partir del cual cada sistema gestor ha desarrollado su versin propia. En SQL Server la versin de SQL que se utiliza se llama TRANSACT-SQL. EL SQL en principio es un lenguaje orientado nicamente a la definicin y al acceso a los datos por lo que no se puede considerar como un lenguaje de programacin como tal ya que no incluye funcionalidades como son estructuras condicionales, bucles, formateo de la salida, etc. (aunque veremos que esto est evolucionando). Se puede ejecutar directamente en modo interactivo, pero tambin se suele emplear embebido en programas escritos en lenguajes de programacin convencionales. En estos programas se mezclan las instrucciones del propio lenguaje (denominado anfitrin) con llamadas a procedimientos de acceso a la base de datos que utilizan el SQL como lenguaje de acceso. Como por ejemplo en Visual Basic, Java, C#, PHP .NET, etc. Las instrucciones SQL se clasifican segn su propsito en tres grupos: El DDL (Data Description Language) Lenguaje de Descripcin de Datos. El DCL (Data Control Language) Lenguaje de Control de Datos. El DML (Data Manipulation Language) Lenguaje de Manipulacin de Datos.

El DDL, es la parte del SQL dedicada a la definicin de la base de datos, consta de sentencias para definir la estructura de la base de datos, permiten crear la base de datos, crear, modificar o eliminar la estructura de las tablas, crear ndices, definir reglas de validacin de datos, relaciones entre las tablas, etc. Permite definir gran parte del nivel interno de la base de datos. Por este motivo estas sentencias sern utilizadas normalmente por el administrador de la base de datos. El DCL (Data Control Language) se compone de instrucciones que permiten: Ejercer un control sobre los datos tal como la asignacin de privilegios de acceso a los datos (GRANT/REVOKE). La gestin de transacciones (COMMIT/ROLLBACK).

Una transaccin se puede definir como un conjunto de acciones que se tienen que realizar todas o ninguna para preservar la integridad de la base de datos. Por ejemplo supongamos que tenemos una base de datos para las reservas de avin. Cuando

33

un usuario pide reservar una plaza en un determinado vuelo, el sistema tiene que comprobar que queden plazas libres, si quedan plazas reservar la que quiera el usuario generando un nuevo billete y marcando la plaza como ocupada. Aqu tenemos un proceso que consta de dos operaciones de actualizacin de la base de datos (crear una nueva fila en la tabla de billetes y actualizar la plaza reservada en el vuelo, ponindola como ocupada) estas dos operaciones se tienen que ejecutar o todas o ninguna, si despus de crear el billete no se actualiza la plaza porque se cae el sistema, por ejemplo, la base de datos quedara en un estado inconsistente ya que la plaza constara como libre cuando realmente habra un billete emitido para esta plaza. En este caso el sistema tiene el mecanismo de transacciones para evitar este error. Las operaciones se incluyen las dos en una misma transaccin y as el sistema sabe que las tiene que ejecutar las dos, si por lo que sea no se pueden ejecutar las dos, se encarga de deshacer los cambios que se hubiesen producido para no ejecutar ninguna. Las instrucciones que gestionan las autorizaciones sern utilizadas normalmente por el administrador mientras que las otras, referentes a proceso de transacciones sern utilizadas tambin por los programadores. No todos los sistemas disponen de ellas. El DML se compone de las instrucciones para el manejo de los datos, para insertar nuevos datos, modificar datos existentes, para eliminar datos y la ms utilizada, para recuperar datos de la base de datos. Veremos que una sola instruccin de recuperacin de datos es tan potente que permite recuperar datos de varias tablas a la vez, realizar clculos sobre estos datos y obtener resmenes. El DML interacta con el nivel externo de la base de datos por lo que sus instrucciones son muy parecidas, por no decir casi idnticas, de un sistema a otro, el usuario slo indica lo que quiere recuperar no cmo se tiene que recuperar, no influye el cmo estn almacenados los datos. Es el lenguaje que utilizan los programadores y los usuarios de la base de datos. A lo largo del curso se explicarn cada una de las formas de explotacin de la base de datos. Dependiendo de tu perfil profesional (programador o administrador) o de tu inters personal te resultar ms til un bloque u otro. 2.2. Introduccin al TRANSACT- SQL Como hemos dicho, el sistema gestor de base de datos SQL-Server 2005 utiliza su propia versin del lenguaje SQL, el TRANSACT-SQL. TRANSACT-SQL es un lenguaje muy potente que nos permite definir casi cualquier tarea que queramos efectuar sobre la base de datos. En este tema veremos que TRANSACT-SQL va ms all de un lenguaje SQL cualquiera ya que incluye caractersticas propias de cualquier lenguaje de programacin, caractersticas que nos permiten definir la lgica necesaria para el tratamiento de la informacin: Tipos de datos. Definicin de variables. Estructuras de control de flujo. Gestin de excepciones. Funciones predefinidas.

Sin embargo no permite: Crear interfaces de usuario.

34

Crear aplicaciones ejecutables, sino elementos que en algn momento llegarn al servidor de datos y sern ejecutados.

Debido a estas restricciones se emplea generalmente para crear procedimientos almacenados, triggers y funciones de usuario. Puede ser utilizado como cualquier SQL como lenguaje embebido en aplicaciones desarrolladas en otros lenguajes de programacin como Visual Basic, C, Java, etc. Y por supuesto los lenguajes incluidos en la plataforma .NET. Tambin lo podremos ejecutar directamente de manera interactiva, por ejemplo desde el editor de consultas de SSMS (SQL Server Management Studio) el entorno de gestin que ya conocemos. Esta es la forma en que lo utilizaremos nosotros.

Unidad 2. Introduccin al SQL. Transact-SQL (II)


2.3. Caractersticas generales del lenguaje Transact- SQL El lenguaje SQL se cre con la finalidad de ser un lenguaje muy potente y a la vez muy fcil de utilizar, se ha conseguido en gran medida ya que con una sola frase (instruccin) podemos recuperar datos complejos (por ejemplo datos que se encuentran en varias tablas, combinndolos, calculando resmenes), y utilizando un lenguaje muy cercano al lenguaje hablado (suponiendo que hablamos ingls, claro!). Por ejemplo: SELECT codigo, nombre FROM Clientes WHERE localidad=Valencia; Esta instruccin nos permite SELECCIONAR el cdigo y nombre DE los Clientes CUYA localidad sea Valencia. La sencillez tambin radica en que lo que indicamos es lo que queremos obtener, no el cmo lo tenemos que obtener, de eso se encargar el sistema automticamente. Las sentencias SQL adems siguen todas el mismo patrn: Empiezan por un verbo que indica la accin a realizar, completado por el objeto sobre el cual queremos realizar la accin, seguido de una serie de clusulas (unas obligatorias, otras opcionales) que completan la frase, y proporcionan ms detalles acerca de lo que se quiere hacer.

Si sabemos algo de ingls nos ser ms fcil interpretar a la primera lo que quiere decir la instruccin, y de lo contrario, como el nmero de palabras que se emplean es muy reducido, enseguida nos las aprenderemos.

Por ejemplo en el DDL (acciones sobre la definicin de la base de datos ), tenemos 3 verbos bsicos:
CREATE (Crear) DROP (Eliminar) ALTER (Modificar)

35

Completados por el tipo de objeto sobre el que actan y el objeto concreto: CREATE DATABASE mibase .......; Permite crear una base de datos llamada mibase, a continuacin escribiremos las dems clusulas que completarn la accin, en este caso dnde se almacenar la base de datos, cunto ocupar, etc... CREATE TABLE mitabla (.....); Create table kakita (code varchar,descripcion varchar(200),numeros int) Permite crear una nueva tabla llamada mitabla, entre parntesis completaremos la accin indicando la definicin de las columnas de la tabla. CREATE INDEX miindex...; Lo mismo para crear un ndice (a que lo habais adivinado?). DROP DATABASE mibase; Permite borrar, eliminar la base de datos mibase. DROP TABLE mitabla; Elimina la tabla mitabla. ALTER TABLE mitabla.....; Permite modificar la definicin de la tabla mitabla.

En el DML (acciones sobre los datos almacenados) utilizaremos los verbos:


INSERT (Crear, es decir, insertar una nueva fila de datos) DELETE (Eliminar filas de datos) UPDATE (Modificar filas de datos) SELECT (Seleccionar, obtener) Por ejemplo: INSERT INTO mitabla ..... Inserta nuevas filas en mitabla DELETE FROM mitabla Eliminar filas de mitabla UPDATE mitabla ....... Actualiza filas de mitabla Como ejemplo de clusula dentro de una instruccin tenemos: SELECT codigo, nombre FROM Clientes WHERE localidad=Valencia;

36

En esta sentencia nos aparecen dos clusulas, la clusula FROM que nos permite indicar de dnde hay que coger los datos y la clusula WHERE que permite indicar una condicin de seleccin. Otra caracterstica de una sentencia SQL es que acaba con un punto y coma (;) originalmente ste era obligatorio y serva para indicar el fin de la instruccin, pero ahora se puede omitir, aunque se recomienda su uso. En una sentencia utilizaremos palabras reservadas (las fijas del lenguaje), y nombres de objetos y variables (identificadores). Las palabras reservadas no se pueden utilizar para otro propsito, por ejemplo una tabla no se puede llamar FROM, y los nombres (los identificadores) siguen las reglas detalladas en el punto siguiente. Nombres cualificados. En ocasiones deberemos utilizar nombres cualificados, por ejemplo cuando se escribe un nombre de tabla, SQL presupone que se est refiriendo a una de las tablas de la base de datos activa, si queremos hacer referencia a una tabla de otra base de datos utilizamos su nombre cualificado nombrebasedatos.nombredeesquema.nombretabla, utilizamos el punto para separar el nombre del objeto y el nombre de su contenedor. O por ejemplo si en una consulta cuyo origen son dos tablas, queremos hacer referencia a un campo y ese nombre de campo es un nombre de campo en las dos tablas, pues utilizaremos su nombre cualificado nombretabla.nombrecampo. El valor NULL. Puesto que una base de datos es un modelo de una situacin del mundo real, ciertos datos pueden inevitablemente faltar, ser desconocidos o no ser aplicables, esto se debe de indicar de alguna manera especial para no confundirlo con un valor conocido pero que sea cero por ejemplo, SQL tiene para tal efecto el valor NULL que indica precisamente la ausencia de valor. Por ejemplo: no es lo mismo que el alumno no tenga nota a que tenga la nota cero, esto afectara tambin a todos los clculos que se pueden realizar sobre la columna nota. Unidad 2. Introduccin al SQL. Transact-SQL (III) 2.4. Reglas de formato de los identificadores Los identificadores son los nombres de los objetos de la base de datos. Cualquier elemento de Microsoft SQL Server 2005 puede tener un identificador: servidores, bases de datos, tablas, vistas, columnas, ndices, desencadenadores, procedimientos, restricciones, reglas, etc. Las reglas de formato de los identificadores normales dependen del nivel de compatibilidad de la base de datos, que se estableca con el parmetro sp_dbcmptlevel pero que ahora Microsoft aconseja no utilizar ya que desaparecer en versiones posteriores en vez de eso se tiene que utilizar la clusula SET COMPATIBILITY_LEVEL de la instruccin ALTER TABLE. Cuando el nivel de compatibilidad es 90, (el asignado por defecto) se aplican las reglas siguientes para los nombres de los identificadores: No puede ser una palabra reservada. El nombre debe tener entre 1 y 128 caracteres, excepto para algunos tipos de objetos en los que el nmero es ms limitado. El nombre debe empezar por:

37

Una letra, como aparece definida por el estndar Unicode 3.2. La definicin Unicode de letras incluye los caracteres latinos de la "a" a la "z" y de la "A" a la "Z". o El carcter de subrayado ( _ ), arroba ( @ ) o nmero ( # ). Ciertos smbolos al principio de un identificador tienen un significado especial en SQL Server. Un identificador que empieza con el signo de arroba indica un parmetro o una variable local. Un identificador que empieza con el signo de nmero indica una tabla o procedimiento temporal. Un identificador que empieza con un signo de nmero doble (##) indica un objeto temporal global. Algunas funciones de Transact-SQL tienen nombres que empiezan con un doble signo de arroba (@@). Para evitar confusiones con estas funciones, se recomienda no utilizar nombres que empiecen con @@. No se permiten los caracteres especiales o los espacios incrustados. o

Si queremos utilizar un nombre que no siga estas reglas, normalmente para poder incluir espacios en blanco, lo tenemos que escribir encerrado entre corchetes [ ] (tambin se pueden utilizar las comillas pero recomendamos utilizar los corchetes). 2.5. Tipos de datos En SQL Server 2005, cada columna, expresin, variable y parmetro est asociado a un tipo de datos. Un tipo de datos, realmente define el conjunto de valores vlidos para los campos definidos de ese tipo. Indica si el campo puede contener: datos numricos, de caracteres, moneda, fecha y hora, etc. SQL Server proporciona un conjunto de tipos de datos del sistema que define todos los tipos de datos que pueden utilizarse. Tambin podemos definir nuestros propios tipos de datos en Transact-SQL o Microsoft .NET Framework. Los tipos de datos ms utilizados son: Los numricos: int, decimal, money Los de fecha y hora: datetime Y las cadenas de caracteres: varchar

Si quieres conocer todos los tipos de datos disponibles en SQLServer 2005, visita el siguiente avanzado .

2.6. Las constantes Una constante es un valor especfico o un smbolo que representa un valor de dato especfico. El formato de las constantes depende del tipo de datos del valor que representan. En este apartado veremos las ms utilizadas. Las constantes numricas se escriben mediante una cadena de nmeros, con la consideracin de que el separador decimal es un punto, no una coma, y que si se trata de un valor monetario deberemos incluir la moneda al inicio de la constante. Por ejemplo: 85.90 y 85.90 , el primero sera un valor decimal y el segundo un valor money. De forma predeterminada, los valores sern positivos. Para indicar lo contrario escribimos el signo - al principio. Las constantes de fecha y hora van entre comillas simples y con un formato de fecha y hora adecuado. Por ejemplo: '03/10/90'. Y las constantes en cadenas de caracteres van entre comillas simples. Por ejemplo: 'Juan Garca Lpez'.

38

Para indicar valores negativos y positivos aadimos el prefijo + o - segn sea el valor positivo o negativo. Sin prefijo se entiende que el valor es positivo. Si quieres ver cmo definir constantes para otros tipos de datos, visita el siguiente avanzado . Unidad 2. Introduccin al SQL. Transact-SQL (IV) 2.7. Las expresiones Una expresin es una combinacin de smbolos y operadores que el motor de base de datos de SQL Server evala para obtener un nico valor. Una expresin simple puede ser una sola constante, variable, columna o funcin escalar. Los operadores se pueden usar para combinar dos o ms expresiones simples y formar una expresin compleja. Dos expresiones pueden combinarse mediante un operador si ambas tienen tipos de datos admitidos por el operador y se cumple al menos una de estas condiciones: Las expresiones tienen el mismo tipo de datos. El tipo de datos de menor prioridad se puede convertir implcitamente al tipo de datos de mayor prioridad. La funcin CAST puede convertir explcitamente el tipo de datos con menor prioridad al tipo de datos con mayor prioridad o a un tipo de datos intermedio que pueda convertirse implcitamente al tipo de datos con la mayor prioridad.

Tipos de operadores: - Operadores numricos: suma resta multiplicacin divisin mdulo (resto de una divisin) + * / %

- Operadores bit a bit: realizan manipulaciones de bits entre dos expresiones de cualquiera de los tipos de datos de la categora del tipo de datos entero. AND OR OR exclusivo & | ^

- Operadores de comparacin:

39

Igual a Mayor que Menor que Mayor o igual que Menor o igual que Distinto de No es igual a No menor que No mayor que - Operadores lgicos:

= > < >= <= <> != !< !>

Aqu slo los nombraremos ya que en el tema de consultas simples los veremos en detalle. ALL AND ANY BETWEEN EXISTS IN LIKE NOT OR SOME

- Operadores de cadenas: Concatenacin Resultados de la expresin - Si se combinan dos expresiones mediante operadores de comparacin o lgicos, el tipo de datos resultante es booleano y el valor es uno de los siguientes: TRUE, FALSE o UNKNOWN. - Cuando dos expresiones se combinan mediante operadores aritmticos, bit a bit o de cadena, el operador determina el tipo de datos resultante. Las expresiones complejas formadas por varios smbolos y operadores se evalan como un resultado formado por un solo valor. El tipo de datos, intercalacin, precisin y valor de la expresin resultante se determina al combinar las expresiones componentes de dos en dos, hasta que se alcanza un resultado final. La prioridad de los operadores de la expresin define la secuencia en que se combinan las expresiones. +

Unidad 2. Introduccin al SQL. Transact-SQL (V)


2.8. Funciones SQL Server 2005 proporciona numerosas funciones integradas y permite crear funciones definidas por el usuario. Existen diferentes tipos de funciones: Funciones de conjuntos de filas: devuelven un objeto que se puede utilizar, en instrucciones Transact-SQL, en lugar de una referencia a una tabla. Funciones de agregado (tambin llamadas funciones de columna): Operan sobre una coleccin de valores y devuelven un solo valor de resumen. Por ejemplo, la funcin de suma sobre la columna importe para conocer el importe total: SUM(importe)

40

Funciones de categora: Devuelven un valor de categora para cada fila de un conjunto de filas, por ejemplo devuelve el nmero de la fila, el ranking de la fila en una determinada ordenacin, etc. Funciones escalares: Operan sobre un valor y despus devuelven otro valor. Son las funciones que estamos acostumbrados a utilizar. Las funciones escalares se clasifican segn el tipo de datos de sus operandos

Las variables En Transact-SQL podemos definir variables, que sern de un tipo de datos determinado, como tipos de datos podemos utilizar los propios de la base de datos SQL-SERVER, pero tambin podemos utilizar tipos propios del lenguaje que no pueden ser utilizados en DDL. El tipo Cursor y el tipo Table son dos de estos tipos. Las variables se definen utilizando la instruccin DECLARE con el siguiente formato: DECLARE @nbvariable tipo El nombre de la variable debe empezar por el smbolo @, este smbolo hace que SQL interprete el nombre como un nombre de variable y no un nombre de objeto de la base de datos. Por ejemplo: DECLARE @empleados INT Con esto hemos definido la variable @empleados de tipo entero. Para asignar un valor a una variable, la asignacin se realiza con la palabra SELECT y el signo igual con el formato: SELECT @nbvariable = valor El valor puede ser cualquier valor constante, otro nombre de variable, una expresin vlida o algo ms potente, parte de una sentencia SELECT de SQL. Por ejemplo: SELECT @empleados = 0; SELECT @empleados = @otra * 100; SELECT @EMPLEADOS = COUNT(numemp) FROM empleados; El valor almacenado en la variable se puede visualizar mediante la orden PRINT. o SELECT PRINT @nbvariable o SELECT @nbvariable El valor almacenado en la variable se visualizar en la pestaa de resultados. Tambin se puede usar para escribir mensajes: PRINT 'Este es el mensaje' Otros elementos del lenguaje Comentarios. Como en cualquier otro lenguaje de programacin, debemos utilizar comentarios destinados a facilitar la legibilidad del cdigo. En SQL se insertan comentarios con los signos:

41

/* */ --

Varias lneas Una nica lnea

/* Esto es un comentario en varias lneas */ -- Esto es un comentario en una nica lnea.

USE. Cambia el contexto de la base de datos al de la base de datos especificada. USE nbBaseDeDatos Hace que la base de datos activa pase a ser la base de datos indicada en la instruccin, las consultas que se ejecuten a continuacin se harn sobre tablas de esa base de datos si no se indica lo contrario. Es una instruccin til para asegurarnos de que la consulta se ejecuta sobre la base de datos correcta. GO GO no es una instruccin Transact-SQL, sino un comando reconocido por las utilidades sqlcmd y osql, as como por el Editor de cdigo de SQL Server Management Studio. Las utilidades de SQL Server interpretan GO como una seal de que deben enviar el lote actual de instrucciones Transact-SQL a una instancia de SQL Server. El lote actual de instrucciones est formado por todas las instrucciones especficadas desde el ltimo comando GO o desde el comienzo de la sesin o script si se trata del primer comando GO. Por ejemplo si queremos crear una consulta para crear una base de datos y sus tablas, despus del CREATE DATABASE; tenemos que poner GO antes del primer CREATE TABLE para que el sistema efecte la primera operacin y la base de datos est creada antes de ejecutar el primer CREATE TABLE. BEGIN...END Encierra un conjunto de instrucciones Transact-SQL de forma que estas instrucciones formen un bloque de instrucciones. Prueba evaluativa de la Unidad 2

Unidad 3. Consultas simples (I) 3.1. Introduccin Vamos a empezar por la instruccin que ms se utiliza en SQL, la sentencia SELECT. La sentencia SELECT es, con diferencia, la ms compleja y potente de las sentencias SQL, con ella podemos recuperar datos de una o ms tablas, seleccionar ciertos registros e incluso obtener resmenes de los datos almacenados en la base de datos. Es tan compleja que la estudiaremos a lo largo de varias unidades didcticas incorporando poco a poco nuevas funcionalidades. El resultado de una SELECT es una tabla lgica que alberga las filas resultantes de la ejecucin de la sentencia. La sintaxis completa es la siguiente: SELECT sentencia::= [WITH <expresion_tabla_comun> [,... n]] <expresion_consulta> [ORDER BY {expression_columna|posicion_columna [ASC|DESC] } [ ,...n ]] [COMPUTE

42

{{AVG|COUNT|MAX|MIN|SUM} ( expression)}[ ,...n ] [BY expression[ ,...n ]] ] [<FOR clausula_for>] [OPTION (<query_hint>[ ,...n ])] <expresion_consulta> ::= {<especificacion_consulta> | ( < expresion_consulta > ) } [ {UNION [ALL]|EXCEPT|INTERSECT} <especificacion_consulta> | (<expresion_consulta>) [...n ] ] <especificacion_consulta> ::= SELECT [ALL|DISTINCT] [TOP expresion [PERCENT] [WITH TIES] ] <lista_seleccion> [INTO nueva_tabla] [FROM { <origen> } [ ,...n ] ] [WHERE <condicion_busqueda> ] [GROUP BY [ ALL ] expresion_agrupacion [ ,...n ] [WITH { CUBE | ROLLUP } ] ] [HAVING < condicion_busqueda > ] Debido a la complejidad de la sentencia (en la sintaxis anterior no se han detallado algunos elementos), la iremos viendo poco a poco, empezaremos por ver consultas bsicas para luego ir aadiendo ms clusulas. Empezaremos por ver las consultas ms simples, basadas en una sola tabla y nos limitaremos a la siguiente sintaxis: SELECT [ALL|DISTINCT] [TOP expresion [PERCENT] [WITH TIES]] <lista_seleccion> FROM <origen> [WHERE <condicion_busqueda> ] [ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n ]] 3.2. Origen de datos FROM De la sintaxis anterior, el elemento <origen> indica de dnde se va a extraer la informacin y se indica en la clusula FROM, es la nica clusula obligatoria. En este tema veremos un origen de datos basado en una sola tabla. La sintaxis ser la siguiente: <origen>::= nb_tabla | nb_vista [[ AS ] alias_tabla ] nb_tabla representa un nombre de tabla. nb_vista un nombre de vista. Tanto para las tablas como para las vistas, podemos hacer referencia a tablas que estn en otras bases de datos (siempre que tengamos los permisos adecuados), en este caso tenemos que cualificar el nombre de la tabla, indicando delante el nombre de la base de datos (Lgica) y el nombre del esquema al que pertenece la tabla dentro de la base de datos.

43

Por ejemplo: MiBase.dbo.MiTabla se refiere a la tabla MiTabla que se encuentra en el esquema dbo de la base de datos MiBase. Cuando no se definen esquemas, SQL-Server crea uno por defecto en cada base de datos denominado dbo. Opcionalmente podemos definir un nombre de alias. Un nombre de alias (alias_tabla) es un nombre alternativo que se le da a la tabla dentro de la consulta. Si se define un nombre de alias, dentro de la consulta, ser el nombre a utilizar para referirnos a la tabla, el nombre original de la tabla ya no tendr validez. Se utilizan los nombres de alias para simplificar los nombres de tablas a veces largos y tambin cuando queremos combinar una tabla consigo misma; ya volveremos sobre los alias de tabla cuando veamos consultas multitabla. La palabra AS no aade ninguna operatividad, est ms por esttica. Podemos escribir: SELECT ... FROM tabla1 Sacamos los datos de la tabla tabla1 SELECT ... FROM tabla1 t1 Sacamos los datos de la tabla tabla1 y le asignamos un alias de tabla: t1 SELECT ... FROM tabla1 AS t1 Es equivalente a la sentencia anterior. Si la tabla o la vista estn en otra base de datos del mismo equipo que est ejecutando la instancia de SQL Server, se utiliza el nombre cualificado con el formato nbBaseDatos.nbEsquema.nbTabla. Si la tabla o la vista estn fuera del servidor local en un servidor vinculado, se utiliza un nombre de cuatro partes con el formato nbservidor.catalogo.nbEsquema.nbTabla. Volveremos ms adelante sobre las conexiones remotas. Unidad 3. Consultas simples (II) 3.3. La lista de seleccin En la lista de seleccin <lista_seleccion> indicamos las columnas que se tienen que visualizar en el resultado de la consulta. <lista_seleccion> ::= { * | {nombre_tabla|nombre_vista|alias_tabla}.* | { [{nombre_tabla|nombre_vista|alias_tabla}.] {nb_columna|$IDENTITY|$ROWGUID} |<expresion> }[[AS] alias_columna] | alias_columna = <expresion> } [ ,...n ]

44

Separamos la definicin de cada columna por una coma y las columnas del resultado aparecern en el mismo orden que en la lista de seleccin. Para cada columna del resultado su tipo de datos, tamao, precisin y escala son los mismos que los de la expresin que da origen a esa columna. Podemos definir las columnas del resultado de varias formas, mediante: Una expresin simple: o una referencia a una funcin. o una variable local o una constante o una columna del origen de datos, Una subconsulta escalar, que es otra instruccin SELECT que devuelve un nico valor y se evala para cada fila del origen de datos (esto no lo veremos de momento). Una expresin compleja generada al usar operadores en una o ms expresiones simples. La palabra clave *. La asignacin de variables con el formato @variable_local = expresin. La palabra clave $IDENTITY. La palabra clave $ROWGUID.

3.4. Columnas del origen de datos Cuando queremos indicar en la lista de seleccin una columna del origen de datos, la especificamos mediante su nombre simple o nombre cualificado. El nombre cualificado consiste en el nombre de la columna precedido del nombre de la tabla donde se encuentra la columna. Si en el origen de datos hemos utilizado una vista o un nombre de alias, deberemos utilizar ese nombre. Es obligatorio utilizar el nombre cualificado cuando el nombre de la columna aparece en ms de una tabla del origen de datos. Ejemplos de consulta simple. Listar nombres, oficinas, y fechas de contrato de todos los empleados: SELECT nombre, oficina, contrato FROM empleados; El resultado sera: nombre Antonio Viguer Alvaro Jaumes Juan Rovira Jos Gonzlez Vicente Pantalla Luis Antonio Jorge Gutirrez Ana Bustamante Mara Sunta Juan Victor Listar una tarifa de productos: oficina 12 21 12 12 13 11 22 21 11 NULL contrato 1986-10-20 1986-12-10 1987-03-01 1987-05-19 1988-02-12 1988-06-14 1988-11-14 1989-10-12 1999-10-12 1990-01-13

45

SELECT idfab, idproducto, descripcion, productos.precio FROM productos; Hemos cualificado la columna precio aunque no es necesario en este caso. El resultado sera: Idfab aci aci aci aci aci aci aci bic bic idproducto 41001 41002 41003 41004 4100x 4100y 4100z 41003 41089 descripcion arandela bisagra art t3 art t4 junta extractor mont manivela rodamiento precio 0,58 0,80 1,12 1,23 0,26 28,88 26,25 6,52 2,25

Unidad 3. Consultas simples (III) 3.5. Alias de columna Por defecto, en el encabezado de cada columna del resultado, aparece el nombre de la columna origen, pero esto se puede cambiar definiendo un alias de columna, el alias de columna es un nombre alternativo que se le da a esa columna. El alias de columna se indica mediante la clusula AS. Se escribe el nuevo texto tal cual sin comillas siguiendo las reglas de los identificadores. Ejemplo: SELECT numclie,nombre AS nombrecliente FROM clientes; El resultado ser : Numclie 2101 2102 2103 en vez de: Numclie 2101 2102 2103 nombre Luis Garca Antn Alvaro Rodrguez Jaime Llorens nombrecliente Luis Garca Antn Alvaro Rodrguez Jaime Llorens

La palabra AS es opcional. SELECT numclie,nombre nombrecliente FROM clientes;

46

Sera equivalente a la consulta anterior Si queremos incluir espacios en blanco en el nombre lo debemos encerrar entre corchetes. SELECT numclie,nombre AS [nombre cliente] FROM clientes; Nota importante: Este nombre de alias se podr utilizar en la lista de seleccin y en la clusula ORDER BY pero no en la clusula WHERE. 3.6. Funciones Existen funciones que podemos utilizar en la lista de seleccin, e incluso en otras clusulas que veremos ms adelante, como el WHERE. Las principales funciones son las siguientes: Funciones de fecha: Funcin GETDATE GETUTCDATE DATEPART DAY MONTH YEAR DATENAME DATEADD DATEDIFF @@DATEFIRST SET DATEFIRST Descripcin Devuelve la fecha actual. Devuelve la hora UTC. Devuelve un entero que corresponde a la parte de la fecha solicitada. Devuelve el da de la fecha indicada. Devuelve el mes de la fecha indicada. Devuelve el ao de la fecha indicada. Devuelve una cadena de caracteres que representa el valor de la unidad especificada de una fecha especificada. Devuelve un valor datetime nuevo que resulta de sumar un intervalo de tiempo a una fecha especificada.> Devuelve el n de intervalos que hay entre dos fechas. Devuelve el primer da de la semana establecido con SET DATEFIRST. Establece el primer da de la semana en un nmero del 1 al 7. Ver +

Unidad 3. Consultas simples (IV) Funciones de cadena: Funcin ASCII CHAR NCHAR UNICODE LEN LTRIM RTRIM LEFT RIGHT Descripcin Devuelve el valor de cdigo ASCII del carcter situado ms a la izquierda de una expresin de caracteres. Devuelve el carcter ASCII del entero indicado. Devuelve el carcter Unicode del entero indicado. Devuelve el entero que se corresponde al carcter Unicode indicado. Devuelve el total de caracteres de una cadena, excluidos los espacios en blanco finales. Devuelve una cadena tras quitarle los espacios en blanco iniciales. Devuelve una cadena tras quitarle los espacios en blanco finales. Devuelve los N ltimos caracteres de una cadena. Devuelve los N primeros caracteres de una cadena. Ver +

47

SUBSTRING LOWER UPPER REPLACE STUFF QUOTENAME SPACE STR REPLICATE REVERSE CHARINDEX PATINDEX

Devuelve parte de una expresin. Devuelve la cadena convertida a minsculas. Devuelve la cadena convertida a maysculas. Reemplaza una determinada cadena. Elimina el nmero de caracteres especificado e inserta otro conjunto de caracteres en el punto de inicio indicado. Devuelve una cadena Unicode con los delimitadores agregados para convertirla en un identificador delimitado vlido de Microsoft SQL Server 2005. Devuelve una cadena de espacios repetidos. Devuelve una cadena de caracteres a partir de datos numricos. Repite una cadena N veces. Devuelve una cadena invertida. Devuelve la posicin inicial de la expresin especificada en una cadena de caracteres. Devuelve la posicin inicial de la primera repeticin de un patrn en la expresin especificada, o ceros si el patrn no se encuentra, en todos los tipos de datos de texto y caracteres.

Otras funciones: Funcin ROUND CAST y CONVERT CASE ISNULL COALESCE Descripcin Redondea un valor a la longitud y precisin indicadas. Convierten de un tipo de datos a otro de forma explcita. Evala una lista de condiciones. Reemplaza el valor NULL por otro especificado. Devuelve la primera expresin distinta de NULL entre sus argumentos. Ver +

Unidad 3. Consultas simples (V) 3.7. Columnas calculadas Adems de las columnas que provienen directamente de la tabla origen, una consulta SQL puede incluir columnas calculadas cuyos valores se evalan a partir de una expresin. La expresin puede contener cualquier operador vlido (+, -, *, /, &), cualquier funcin vlida, nombres de columnas del origen de datos, nombres de parmetros o constantes y para combinar varias operaciones se pueden utilizar los parntesis. Ejemplos de columnas calculadas: Listar la ciudad, regin y el supervit de cada oficina. Consideraremos el supervit como el volumen de ventas que se encuentran por encima o por debajo del objetivo de la oficina. SELECT ciudad, region, (ventas-objetivo) AS superavit FROM oficinas; El resultado ser: ciudad region superavit

48

Valencia Alicante Castellon Badajoz A Corua Madrid Madrid Pamplona Valencia

este este este oeste oeste centro centro norte este

11800,00 -6500,00 1800,00 11100,00 -11400,00 NULL -10000,00 NULL -90000,00

De cada producto queremos saber el id de fabricante, id de producto, su descripcin y el valor de sus existencias. SELECT idfab,idproducto,descripcion,(existencias*precio) AS valoracion FROM productos; El resultado sera: Idfab aci aci aci aci aci aci aci bic bic idproducto 41001 41002 41003 41004 4100x 4100y 4100z 41003 41089 descripcion arandela bisagra art t3 art t4 junta extractor mont manivela rodamiento valoracion 160,66 133,60 231,84 170,97 9,62 722,00 735,00 19,56 175,50

Para practicar puedes realizar este Ejercicio Columna calculada. Unidad 3. Consultas simples (VI) Listar el nombre, mes y ao del contrato de cada vendedor. SELECT nombre, MONTH(contrato) AS [Mes de contrato], YEAR(contrato) AS [Ao de contrato] FROM empleados; El resultado ser: Nombre Antonio Viguer Alvaro Jaumes Juan Rovira Mes de contrato 10 12 3 Ao de contrato 1986 1986 1987

Para practicar puedes realizar este Ejercicio Funciones en la lista de seleccin. Listar las ventas en cada oficina con el formato: 22 tiene ventas de 186,042.00 SELECT oficina, 'tiene ventas de ' AS [ ], ventas FROM oficinas;

49

El resultado sera: oficina 11 12 13 21 22 23 24 26 28 ventas 69300,00 73500,00 36800,00 83600,00 18600,00 NULL 15000,00 NULL 0,00

tiene tiene tiene tiene tiene tiene tiene tiene tiene

ventas ventas ventas ventas ventas ventas ventas ventas ventas

de de de de de de de de de

El incluir una constante como columna en la lista de seleccin puede parecer intil (se repetir el mismo valor en todas las filas) pero veremos ms adelante que tiene utilidad en ciertos casos. Tambin podemos utilizar la sintaxis:

alias_columna = <expresion>
Ejemplo: SELECT oficina, superavit = ventas-objetivo Esto tiene el mismo efecto que SELECT oficina, ventas-objetivo AS superavit

Unidad 3. Consultas simples (VII)


3.8. Utilizacin del asterisco * Si queremos visualizar todas las columnas del origen de datos, en lugar de indicar todas las columnas una a una se puede utilizar el carcter de sustitucin *. Mostrar todos los datos de la tabla oficinas. SELECT * FROM oficinas; Obtener todos los datos y el supervit de cada oficina. SELECT *, (ventas-objetivo) AS superavit FROM oficinas; Tambin podemos cualificar el * con un nombre de tabla, de vista o un alias de tabla: SELECT oficinas.* FROM oficinas; oficinas.* se interpreta como: todas las columnas de la tabla oficinas.

50

Esta forma se utiliza normalmente cuando el origen est basado en varias tablas y queremos indicar todas las columnas no del origen completo sino de una tabla concreta. Para practicar puedes realizar este Ejercicio La palabra clave *. 3.9. Las palabras clave $IDENTITY y $ROWGUID La palabra clave $IDENTITY se interpreta como la columna de la tabla que tiene la propiedad IDENTITY (la columna de identidad que vimos en un tema anterior). Por ejemplo, si en la columna codigo de la tabla usuarios (BD Biblio) se ha definido la propiedad IDENTITY. SELECT $IDENTITY, nombre, apellidos FROM usuarios; Es equivalente a: SELECT codigo, nombre, apellidos FROM usuarios; La palabra clave $ROWGUID se interpreta como la columna de la tabla que tiene la propiedad ROWGUIDCOL y se puede utilizar de la misma forma que $IDENTITY. Unidad 3. Consultas simples (VIII) 3.10. Ordenacin de las filas del resultado ORDER BY Si queremos que las filas del resultado de la consulta aparezcan ordenadas, lo podemos indicar mediante la clusula ORDER BY. ORDER BY {expression_columna|posicion_columna [ASC|DESC]}[ ,...n ] Podemos indicar una columna o varias separadas por una coma, la columna de ordenacin se especifica mediante el nombre de columna en el origen de datos o su posicin dentro de la lista de seleccin. Si utilizamos el nombre de columna, no hace falta que la columna aparezca en la lista de seleccin. Si utilizamos la posicin es la posicin de la columna dentro de la lista de seleccin empezando en 1. Por defecto la filas se ordenarn en modo ascendente (ASC), de menor a mayor; si queremos invertir ese orden aadimos detrs de la columna la palabra DESC. Si la columna de ordenacin es alfanumrica, las filas se ordenarn por orden alfabtico. Si la columna de ordenacin es numrica, las filas se ordenarn de menor a mayor. Si la columna de ordenacin es de tipo fecha, las filas se ordenarn de ms antigua a ms reciente o futura.

Ejemplos: Mostrar las ventas de cada oficina, ordenadas por orden alfabtico de regin y dentro de cada regin por ciudad. SELECT oficina, region, ciudad, ventas

51

FROM oficinas ORDER BY region, ciudad; Da como resultado: Oficina 24 23 12 13 11 28 26 22 21 region centro centro este este este este norte oeste oeste ciudad Aranjuez Madrid Alicante Castelln Valencia Valencia Pamplona A Corua Badajoz ventas 15000,00 NULL 73500,00 36800,00 69300,00 0,00 NULL 18600,00 83600,00

Listar las oficinas de manera que las oficinas de mayores ventas aparezcan en primer lugar. SELECT ciudad, region, ventas FROM oficinas ORDER BY ventas DESC; ciudad region Badajoz oeste Alicante este Valencia este Castellon este A Corua oeste Aranjuez centro Valencia este Pamplona norte Madrid centro

ventas 83600,00 73500,00 69300,00 36800,00 18600,00 15000,00 0,00 NULL NULL

Listar las oficinas clasificadas en orden descendente de rendimiento de ventas, de modo que las de mayor rendimiento aparezcan las primeras. SELECT ciudad, region, ventas-objetivo FROM oficinas ORDER BY 3 DESC; Lo mismo que el anterior pero agrupadas por regin. SELECT region, ciudad, (ventas-objetivo) AS superavit FROM oficinas ORDER BY region, superavit DESC; Resultado: Region centro centro este este este ciudad Aranjuez Madrid Valencia Castelln Alicante superavit -10000,00 NULL 11800,00 1800,00 -6500,00

52

este norte oeste oeste

Valencia Pamplona Badajoz A Corua

-90000,00 NULL 11100,00 -11400,00

En este caso hemos utilizado el alias de columna para hacer referencia a la columna calculada y tambin se puede observar que las filas aparecen ordenadas por regin ascendente (no hemos incluido nada despus del nombre de la columna) y dentro de cada regin por supervit y descendente. Para practicar puedes realizar este Ejercicio Ordenar los datos. Unidad 3. Consultas simples (IX) 3.11. Eliminar filas duplicadas DISTINCT/ALL SQL no elimina las filas duplicadas en el resultado de la consulta, si nosotros no queremos que se repitan las filas, tenemos la clusula DISTINCT. Al incluir la clusula DISTINCT en la SELECT, se eliminar del resultado las repeticiones de filas de resultado. Si por el contrario queremos que aparezcan todas las filas seleccionadas podemos incluir la clusula ALL o nada, ya que ALL es el valor por defecto. Listar los n de empleado de los directores de las oficinas. SELECT dir FROM oficinas; dir 106 104 105 108 108 108 108 NULL NULL Si un mismo empleado dirige varias oficinas (por ejemplo el 108), su cdigo aparece repetido en el resultado. Para evitarlo modificamos la consulta: SELECT DISTINCT dir FROM oficinas; dir NULL 104 105 106 108 Han desaparecido los valores duplicados. Los que se eliminan son valores duplicados de filas del resultado, por ejemplo:

53

SELECT DISTINCT dir, region FROM oficinas; dir region NULL este NULL norte 104 este 105 este 106 este 108 centro 108 oeste Ahora el 108 aparece dos veces porque las dos filas donde aparece no son iguales (porque tienen distinta regin). NOTA: La clusula DISTINCT hace que la consulta tarde algo ms en ejecutarse debido al proceso adicional de buscar y eliminar las repeticiones, por lo que se aconseja utilizarla nicamente cuando sea imprescindible. Para practicar puedes realizar este Ejercicio Eliminar filas duplicadas.

Unidad 3. Consultas simples (X) 3.12. La clusula TOP [TOP <expresin> [PERCENT] [WITH TIES]] La clusula TOP indica que en el resultado no deben aparecer todas las filas resultantes sino un cierto nmero de registros, las n primeras. Si la consulta incluye la clusula ORDER BY, se realiza la ordenacin antes de extraer los n primeros registros. La expresin representa ese nmero n y debe devolver un nmero entero sin signo. Por ejemplo tenemos la siguiente tabla: SELECT * FROM productos:

Si ordenamos por ventas: SELECT * FROM productos ORDER BY ventas;

54

Obtenemos el siguiente resultado: Si aadimos la clusula TOP: SELECT TOP 3 * FROM productos ORDER BY ventas Obtenemos los 3 primeros registros:

Si existen ms registros con las mismas ventas que el ltimo valor de la lista, stos no saldrn en el resultado de la consulta. En el ejemplo el registro con cod = 2 no sale en el resultado y tiene las mismas ventas que cod = 3. Si queremos que salgan aadimos la clusula WITH TIES. La clusula WITH TIES slo se puede emplear si la SELECT incluye un ORDER BY, de lo contrario dar error. Si aadimos la clusula WITH TIES: SELECT TOP 3 WITH TIES * FROM productos ORDER BY ventas Obtenemos:

Se incluyen en el resultado todos los registros que tienen ventas iguales al ltimo registro. Otro ejemplo: SELECT TOP 10 oficina, ciudad, ventas FROM oficinas ORDER BY ventas;

55

Devuelve las 10 peores oficinas en cuanto a ventas: ordenamos las oficinas por ventas de menor a mayor y sacamos las 10 primeras. Si incluimos la palabra PERCENT, entonces n no indica el nmero de registros a recuperar sino el porcentaje de registros a recuperar del total de filas recuperadas despus de ejecutar la clusula WHERE. SELECT TOP 50 PERCENT * FROM productos ORDER BY ventas Devuelve:

Si el porcentaje no da exacto, siempre redondea al alza. Para practicar puedes realizar este Ejercicio La clusula TOP. Unidad 3. Consultas simples (XI) 3.13. Seleccin de filas WHERE La clusula WHERE se emplea para especificar las filas que se desean recuperar del origen de datos. WHERE <condicion_bsqueda> <condicion_bsqueda> ::= { [NOT]<predicado> |(<condicion_bsqueda>) } [{AND|OR} [NOT] {<predicado>|(<condicion_bsqueda>)}] [ ...n ] En el resultado de la consulta slo aparecern las filas que cumplan que la condicin de bsqueda sea TRUE, los valores NULL no se incluyen, por lo tanto, en las filas del resultado. La condicin de bsqueda puede ser una condicin simple o una condicin compuesta por varias condiciones (predicados) unidas por operadores AND y OR, no hay lmite en cuanto al nmero de predicados que se pueden incluir. En las condiciones compuestas se pueden utilizar parntesis para delimitar predicados y se aconseja su uso cuando se incluyen operadores AND y OR en la misma condicin de bsqueda. 3.14. Predicados En SQL tenemos 7 tipos de predicados, condiciones bsicas de bsqueda: Comparacin estndar Pertenencia a un intervalo (BETWEEN) Pertenencia a un conjunto (IN) Test de valor nulo (IS NULL).

56

Coincidencia con patrn (LIKE) Si contiene (CONTAINS) FREETEXT

Comparacin estndar. Compara el valor de una expresin con el valor de otra. Para la comparacin se pueden emplear = , <> , !=, < , <= , !<, > , >= ,!> Sintaxis: <expresion> {=|<>|!=|>|>=|!>|<|<=|!<} <expresion> <expresion> Puede ser: Un nombre de columna, una constante, una funcin (inclusive la funcin CASE), una variable, una subconsulta escalar o cualquier combinacin de nombres de columna, constantes y funciones conectados mediante uno o varios operadores o una subconsulta.

Ejemplo: Listar los "buenos" vendedores (los que han rebasado su cuota). SELECT numemp, nombre, ventas, FROM empleados WHERE ventas > cuota numemp nombre 101 Antonio Viguer 102 Alvaro Jaumes 103 Juan Rovira 105 Vicente Pantalla 106 Luis Antonio 108 Ana Bustamante 109 Mara Sunta cuota

ventas 30500,00 47400,00 28600,00 36800,00 29900,00 36100,00 39200,00

cuota 30000,00 35000,00 27500,00 35000,00 27500,00 35000,00 3000,00

Las columnas que aparecen en el WHERE no tienen por qu aparecer en la lista de seleccin, esta instruccin es igual de vlida: SELECT numemp, nombre FROM empleados WHERE ventas > cuota; Hallar vendedores contratados antes de 1988. SELECT numemp, nombre, contrato FROM empleados WHERE contrato < '01/01/1988'; numemp nombre contrato 101 Antonio Viguer 1986-10-20 102 Alvaro Jaumes 1986-12-10

57

103 104

Juan Rovira Jos Gonzlez

1987-03-01 1987-05-19

Tambin podemos utilizar funciones, sta es equivalente a la anterior: SELECT numemp, nombre FROM empleados WHERE YEAR(contrato) < 1988; La funcin YEAR(fecha) devuelve el ao de una fecha. Hallar oficinas cuyas ventas estn por debajo del 80% de su objetivo: SELECT oficina FROM oficinas WHERE ventas < (.8 * objetivo); Hallar las oficinas dirigidas por el empleado 108: SELECT oficina FROM oficinas WHERE dir = 108;

Unidad 3. Consultas simples (XII) Pertenencia a un intervalo. BETWEEN <expresion> [NOT] BETWEEN <expresion2> AND <expresion3> Examina si el valor de la expresin de test est en el rango delimitado por los valores resultantes de expresion1 y expresion2, estos valores no tienen porqu estar ordenados en ANSI/ISO; expresion1 debe ser menor o igual a expresion2. Hallar vendedores cuyas ventas estn entre 20.000 euros y 50.000. SELECT numemp, nombre, ventas FROM empleados WHERE ventas BETWEEN 20000 AND 100000; numemp nombre ventas 101 Antonio Viguer 30500,00 102 Alvaro Jaumes 47400,00 103 Juan Rovira 28600,00 105 Vicente Pantalla 36800,00 106 Luis Antonio 29900,00 108 Ana Bustamante 36100,00 109 Mara Sunta 39200,00 La instruccin anterior es equivalente a: SELECT numemp, nombre, ventas FROM empleados WHERE ventas >= 20000 AND ventas <=100000;

58

Parece que con BETWEEN se lee mejor. Observa que no hemos utilizado separadores de millares (100.000), porque se habra interpretado por una coma decimal. Para practicar puedes realizar este Ejercicio Intervalos con BETWEEN. Test de pertenencia a conjunto IN <expresion> IN ( <exp_valor> [ ,...n ] ) Examina si el valor de la expresion es uno de los valores incluidos en la lista de valores indicados entre parntesis. Se pueden expresar los valores mediante cualquier expresin, la nica condicin es que todas las exp_valor devuelvan el mismo tipo de datos. Ejemplo: Obtener los empleados que trabajan en las oficinas 11, 20 o 22: SELECT oficina, numemp, nombre FROM empleados WHERE oficina IN (11,20,22); oficina numemp nombre 11 106 Luis Antonio 22 107 Jorge Gutirrez 11 109 Mara Sunta Para practicar puedes realizar este Ejercicio Pertenencia a un conjunto con IN. Test de valor nulo IS NULL <expression> IS [NOT] NULL Una condicin de bsqueda puede ser TRUE, FALSE o NULL/UNKNOW, este ltimo caso se produce cuando algn campo que interviene en la condicin tiene valor NULL. A veces es til comprobar explcitamente los valores NULL en una condicin de bsqueda ya que estas filas puede que queramos darles un tratamiento especial, para ello tenemos el predicado IS NULL. Este test produce un valor TRUE o FALSE, por lo que se podr combinar con otras condiciones. El valor NULL no es en s un valor por eso no lo podemos utilizar en una igualdad. SELECT numemp,nombre FROM empleados WHERE oficina = NULL; Esta instruccin no da error pero no obtiene lo que en principio parece que quiere obtener. No obtenemos los empleados cuya oficina sea un valor nulo (es decir los empleados que no tienen oficina), no obtenemos nada, en cambio los obtendremos utilizando el test de valor nulo: SELECT numemp,nombre, oficina FROM empleados WHERE oficina IS NULL; Resultado:

59

numemp 110

nombre Juan Victor

oficina NULL

Juan Victor es el nico empleado que no tiene oficina asignada. Listar los vendedores asignados a alguna oficina. SELECT numemp, nombre, oficina FROM empleados WHERE oficina IS NOT NULL; numemp nombre 101 Antonio Viguer 102 Alvaro Jaumes 103 Juan Rovira 104 Jos Gonzlez 105 Vicente Pantalla 106 Luis Antonio 107 Jorge Gutirrez 108 Ana Bustamante 109 Mara Sunta

oficina 12 21 12 12 13 11 22 21 11

Para practicar puedes realizar este Ejercicio Test de valor nulo.

Unidad 3. Consultas simples (XIII) Test de correspondencia con patrn LIKE Se utiliza cuando queremos comparar el valor de una columna con un patrn en el que se utilice caracteres comodines. <expression> [NOT] LIKE <patron> [ESCAPE 'car_escape'] Con expresin indicamos el valor a comparar (normalmente ser el nombre de una columna) y patrn es la cadena que se busca. El patrn es de tipo texto y tiene que escribirse entre comillas simples. Dentro del patrn podemos utilizar los siguientes comodines: % representa cualquier cadena de cero o ms caracteres.

SELECT numemp,nombre FROM empleados WHERE nombre LIKE An%; numemp nombre 101 Antonio Viguer 108 Ana Bustamante Obtiene todos los nombres que empiecen por An. SELECT numemp,nombre FROM empleados WHERE nombre LIKE %z; numemp nombre

60

104 107

Jos Gonzlez Jos Gonzlez

Obtiene los nombres que acaban en z. SELECT numemp,nombre FROM empleados WHERE nombre LIKE %on%; numemp nombre 101 Antonio Viguer 104 Jos Gonzlez 106 Luis Antonio Obtiene los nombres que contienen on. _ representa cualquier carcter (slo uno).

SELECT numemp,nombre FROM empleados WHERE nombre LIKE '__a%'; numemp nombre 103 Juan Rovira 108 Ana Bustamante 110 Juan Victor Obtiene los nombres cuya tercera letra sea una a (en el patrn tenemos dos caracteres subrayado). [ ] sirve para indicar un carcter cualquiera perteneciente al conjunto indicando. El conjunto se indica enumerando los caracteres o indicando un intervalo. SELECT numemp,nombre FROM empleados WHERE nombre LIKE '[a-d]%'; Obtiene los nombres que empiezan por cualquier letra de la a a la d. Es equivalente a escribir: SELECT numemp,nombre FROM empleados WHERE nombre LIKE '[abcd]%'; [^] significa cualquier carcter individual que no se encuentre en el conjunto. SELECT numemp,nombre FROM empleados WHERE nombre LIKE '[^abcd]%'; Y SELECT numemp,nombre FROM empleados WHERE nombre LIKE '[^a-d]%';

61

Obtienen los nombres que no empiecen por a, b, c ni d. Es importante tener en cuenta que dentro del patrn el espacio en blanco es considerado como un carcter ms, si colocamos dos espacios en el patrn, se buscarn dos espacios en el campo. Si queremos incluir en el patrn uno de los caracteres comodines y que no sea interpretado como un comodn, sino como un carcter normal, lo tenemos que encerrar entre corchetes o utilizar un carcter de escape. [ESCAPE 'car_escape'] La clusula ESCAPE es opcional y permite definir un carcter de escape. Un carcter de escape es un carcter que se coloca delante de un carcter comodn para indicar que el comodn no debe interpretarse como tal, sino como un carcter normal. Por ejemplo queremos buscar los nombres compuestos que incluyen un subrayado. En este caso tenemos que poner el carcter _ como un carcter normal no como un comodn, as que lo escribiremos as: SELECT numemp,nombre FROM empleados WHERE nombre LIKE '%[_]%'; O bien, SELECT numemp,nombre FROM empleados WHERE nombre LIKE '%!_%' ESCAPE '!'; Para practicar puedes realizar este Ejercicio Test de correspondencia con LIKE. Existen dos predicados ms para evaluar expresiones: CONTAINS y FREETEXT. Puedes ver ms informacin sobre ellas en este avanzado .

Unidad 3. Consultas simples (XIV) 3.15. Condiciones de bsqueda compuestas En una clusula WHERE podemos incluir una condicin de bsqueda simple (formada por un solo predicado) o compuesta (formada por la combinacin de predicados unidos por los operadores lgicos NOT, AND, OR). Cuando la condicin incluye varios operadores lgicos, el orden de prioridad de estos operadores es: NOT (el ms alto), seguido de AND y OR (estos dos al mismo nivel).

Como siempre, se pueden utilizar parntesis para alterar esta prioridad en una condicin de bsqueda.

62

El orden de evaluacin de los operadores lgicos puede variar dependiendo de las opciones elegidas por el optimizador de consultas. Los operadores lgicos pueden devolver tres valores distintos: TRUE, FALSE, NULL (UNKNOWN). Tablas de verdad de los operadores: AND Combina dos condiciones y se evala como TRUE cuando ambas condiciones son TRUE. AND TRUE FALSE NULL TRUE TRUE FALSE NULL FALSE FALSE FALSE FALSE NULL NULL FALSE NULL

OR Combina dos condiciones y se evala como TRUE cuando alguna de las condiciones es TRUE. OR TRUE FALSE NULL TRUE TRUE TRUE TRUE FALSE TRUE FALSE NULL NULL TRUE NULL NULL

NOT Niega la expresin booleana que especifica el predicado NOT TRUE FALSE NULL FALSE TRUE NULL Hallar los vendedores que estn por debajo de su cuota y tienen ventas inferiores a 30.000. SELECT nombre FROM empleados WHERE ventas < cuota AND ventas < 30000; Hallar los vendedores que estn debajo de su cuota, pero cuyas ventas no sean inferiores a 150.000. SELECT nombre FROM empleados WHERE ventas < cuota AND ventas < 150000; Hallar las oficinas no dirigidas por el empleado 108 SELECT oficina FROM oficinas WHERE NOT dir = 108; O SELECT oficina FROM oficinas WHERE dir <> 108;

63

Devuelven: oficina 11 12 13 Las oficinas sin director no aparecen, para que aparezcan deben aadir otro predicado: SELECT oficina, dir FROM oficinas WHERE NOT dir = 108 or dir is null; oficina dir 11 106 12 104 13 105 26 NULL 28 NULL Para practicar puedes realizar este Ejercicio Consultas con mltiples condiciones. Ejercicio propuesto de la Unidad 3 Unidad 4. Consultas multitabla (I) 4.1. Introduccin Hasta ahora hemos visto consultas que obtienen los datos de una sola tabla, en este tema veremos cmo obtener datos de diferentes tablas. En esta parte ampliaremos la clusula FROM y descubriremos nuevas palabras reservadas (UNION, EXCEPT e INTERSECT) que corresponden a operaciones relacionales. Para obtener datos de varias tablas tenemos que combinar estas tablas mediante alguna operacin basada en el lgebra relacional. El lgebra relacional define una serie de operaciones cuyos operandos son tablas y cuyo resultado es tambin una tabla. Las operaciones de lgebra relacional implementadas en Transact-Sql son: La unin UNION La diferencia EXCEPT La interseccin INTERSECT El producto cartesiano CROSS JOIN La composicin interna INNER JOIN La composicin externa LEFT JOIN, RIGHT JOIN Y FULL JOIN Prueba evaluativa de la Unidad 3

En todo el tema cuando hablemos de tablas nos referiremos tanto a las tablas que fsicamente estn almacenadas en la base de datos como a las tablas temporales y a las resultantes de una consulta o vista. 4.2. La unin de tablas UNION La unin de tablas consiste en coger dos tablas y obtener una tabla con las filas de las dos tablas, en el resultado aparecern las filas de una tabla y, a continuacin, las filas de la otra tabla.

64

Para poder realizar la operacin, las dos tablas tienen que tener el mismo esquema (mismo nmero de columnas y tipos compatibles) y la tabla resultante hereda los encabezados de la primera tabla. La sintaxis es la siguiente: {< consulta >|(< consulta >)} UNION [ALL] {< consulta >|(< consulta >)} [{UNION [ALL] {< consulta >|(< consulta >)}}[ ...n ] ] [ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n ]] < consulta > representa la especificacin de la consulta que nos devolver la tabla a combinar. Puede ser cualquier especificacin de consulta con la limitacin de que no admite la clusula ORDER BY, los alias de campo se pueden definir pero slo tienen efecto cuando se indican en la primera consulta ya que el resultado toma los nombres de columna de esta. Ejemplo: Suponemos que tenemos una tabla Valencia con las nuevas oficinas de Valencia y otra tabla Madrid con las nuevas oficinas de Madrid y queremos obtener una tabla con las nuevas oficinas de las dos ciudades: SELECT oficina as OFI, ciudad FROM Valencia UNION ALL SELECT oficina, ciudad FROM Madrid; El resultado sera: OFI 11 28 23 ciudad Valencia Valencia Madrid

El resultado coge los nombres de columna de la primera consulta y aparecen primero las filas de la primera consulta y despus las de la segunda. Si queremos que el resultado aparezca ordenado podemos incluir la clusula ORDER BY, pero despus de la ltima especificacin de consulta, y expresion_columna ser cualquier columna vlida de la primera consulta. SELECT oficina as OFI, ciudad FROM Valencia UNION SELECT oficina, ciudad FROM Madrid ORDER BY ofi; OFI ciudad 11 Valencia 23 Madrid 28 Valencia Ahora las filas aparecen ordenadas por el nmero de oficina y hemos utilizado el nombre de columna de la primera consulta. Cuando aparezcan en el resultado varias filas iguales, el sistema por defecto elimina las repeticiones.

65

Si se especifica ALL, el sistema devuelve todas las filas resultante de la unin incluidas las repetidas El empleo de ALL tambin hace que la consulta se ejecute ms rpidamente ya que el sistema no tiene que eliminar las repeticiones. Se pueden combinar varias tablas con el operador UNION. Por ejemplo supongamos que tenemos otra tabla Pamplona con las oficinas nuevas de Pamplona: SELECT oficina, ciudad FROM Valencia UNION SELECT oficina, ciudad FROM Madrid UNION SELECT oficina, ciudad FROM Pamplona; Combinamos las tres tablas. Otro ejemplo: Obtener todos los productos cuyo precio exceda de 20 o que se haya vendido ms de 300 euros del producto en algn pedido. SELECT idfab, idproducto FROM productos WHERE precio > 20 UNION SELECT fab, producto FROM pedidos WHERE importe > 300; Unidad 4. Consultas multitabla (II) 4.3. La diferencia EXCEPT Aparecen en la tabla resultante las filas de la primera consulta que no aparecen en la segunda. Las condiciones son las mismas que las de la unin. {<consulta>|(<consulta>)} EXCEPT {<consulta>|(<consulta>)} [{EXCEPT {<consulta>|(<consulta>)}}[ ...n ] ] [ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n ]] Por ejemplo tenemos las tablas T1 y T2. T1 T2 Cod Codigo 1 2 2 3 4 4 5 5 6 SELECT cod FROM T1 EXCEPT SELECT codigo FROM T2;

66

Devuelve: Cod 1 6 Ejemplo: Listar los productos que no aparezcan en ningn pedido. SELECT idfab, idproducto FROM productos EXCEPT SELECT DISTINCT fab, producto FROM pedidos; Para practicar puedes realizar este Ejercicio La diferencia EXCEPT. 4.4. La interseccin INTERSECT Tiene una sintaxis parecida a las anteriores pero en el resultado de la interseccin aparecen las filas que estn simultneamente en las dos consultas. Las condiciones son las mismas que las de la unin. { <consulta>|(<consulta>)} INTERSECT {<especificacion_consulta>|(<especificacion_consulta>)} [{INTERSECT {<consulta>|(<consulta>)}} [ ...n ] ] [ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n ]] Retomando el ejemplo anterior: SELECT cod FROM T1 INTERSECT SELECT cod FROM T2; Devuelve: Cod 2 4 5 Ejemplo: Obtener todos los productos que valen ms de 20 euros y que adems se haya vendido en un pedido ms de 300 euros de ese producto. SELECT idfab, idproducto FROM productos WHERE precio > 20 INTERSECT SELECT fab, producto FROM pedidos WHERE importe > 300;

67

Para practicar puedes realizar este Ejercicio La interseccin INTERSECT. Unidad 4. Consultas multitabla (III) 4.5. La composicin de tablas Hasta ahora hemos operado con tablas que tenan el mismo esquema, pero muchas veces lo que necesitamos es obtener una tabla que tenga en una misma fila datos de varias tablas, por ejemplo, obtener las facturas y que en la misma fila de factura aparezca el nombre y direccin del cliente. Pues en lo que queda del tema estudiaremos este tipo de consultas basadas en la composicin de tablas. La composicin de tablas consiste en obtener a partir de dos tablas cualesquiera una nueva tabla fusionando las filas de una con las filas de la otra, concatenando los esquemas de ambas tablas. Consiste en formar parejas de filas. La sentencia SELECT permite realizar esta composicin, incluyendo dos o ms tablas en la clusula FROM. Es hora de ampliar la clusula FROM que vimos en el tema anterior. Empezaremos por estudiar la operacin a partir de la cual estn definidas las dems operaciones de composicin de tabla, el producto cartesiano. 4.6. El producto cartesiano CROSS JOIN El producto cartesiano obtiene todas las posibles concatenaciones de filas de la primera tabla con filas de la segunda tabla. Se indica escribiendo en la clusula FROM los nombres de las tablas separados por una coma o utilizando el operador CROSS JOIN. FROM {<tabla_origen>} [ ,...n ] |<tabla_origen> CROSS JOIN <tabla_origen>

Tabla_origen puede ser un nombre de tabla o de vista o una tabla derivada (resultado de una SELECT), en este ltimo caso la SELECT tiene que aparecer entre parntesis y la tabla derivada debe llevar asociado obligatoriamente un alias de tabla. Tambin puede ser una composicin de tablas. Se pueden utilizar hasta 256 orgenes de tabla en una instruccin, aunque el lmite vara en funcin de la memoria disponible y de la complejidad del resto de las expresiones de la consulta. Tambin se puede especificar una variable table como un origen de tabla.
Ejemplo: SELECT * FROM empleados, oficinas; Si ejecutamos esta consulta veremos que las filas del resultado estn formadas por las columnas de empleados y las columnas de oficinas. En las filas aparece cada empleado combinado con la primera oficina, luego los mismos empleados combinados con la segunda oficina y as hasta combinar todos los empleados con todas las oficinas. Si ejecutamos: SELECT * FROM empleados CROSS JOIN oficinas; Obtenemos lo mismo.

68

Este tipo de operacin no es la que se utiliza ms a menudo, lo ms frecuente sera combinar cada empleado con los datos de SU oficina. Lo podramos obtener aadiendo a la consulta un WHERE para filtrar los registros correctos: SELECT * FROM empleados, oficinas WHERE empleados.oficina=oficinas.oficina; Aqu nos ha aparecido la necesidad de cualificar los campos ya que el nombre oficina es un campo de empleados y de oficinas por lo que si no lo cualificamos, el sistema nos da error. Hemos utilizado en la lista de seleccin *, esto nos recupera todas las columnas de las dos tablas. SELECT empleados.*,ciudad, region FROM empleados, oficinas WHERE empleados.oficina=oficinas.oficina; Recupera todas las columnas de empleados y las columnas ciudad y regin de oficinas. Tambin podemos combinar una tabla consigo misma, pero en este caso hay que definir un alias de tabla, en al menos una, sino el sistema da error ya que no puede nombrar los campos. SELECT * FROM oficinas, oficinas as ofi2; No insistiremos ms sobre el producto cartesiano porque no es la operacin ms utilizada, ya que normalmente cuando queramos componer dos tablas lo haremos con una condicin de seleccin basada en campos de combinacin y para este caso es ms eficiente el JOIN que veremos a continuacin. Para practicar puedes realizar este Ejercicio El producto cartesiano CROSS JOIN. Unidad 4. Consultas multitabla (IV) 4.7. La composicin interna INNER JOIN Una composicin interna es aquella en la que los valores de las columnas que se estn combinando se comparan mediante un operador de comparacin. Es otra forma, mejor, de expresar un producto cartesiano con una condicin. Es la operacin que ms emplearemos ya que lo ms frecuente es querer juntar los registros de una tabla relacionada con los registros correspondientes en la tabla de referencia (aadir a cada factura los datos de su cliente, aadir a cada lnea de pedido los datos de su producto, etc..,). FROM <tabla_origen> INNER JOIN <tabla_origen> ON <condicion_combi>

tabla_origen tiene el mismo significado que en el producto cartesiano. condicion_combi es cualquier condicin que permite seleccionar las parejas de filas que aparecen en el resultado. Normalmente ser una condicin de igualdad.
SELECT * FROM empleados INNER JOIN oficinas ON empleados.oficina=oficinas.oficina;

69

Obtiene los empleados combinados con los datos de su oficina. SELECT * FROM pedidos INNER JOIN productos ON producto = idproducto AND fab = idfab; Obtiene los pedidos combinados con los productos correspondientes. Normalmente la condicin de combinacin ser una igualdad pero se puede utilizar cualquier operador de comparacin (<>, >). Es fcil ver la utilidad de esta instruccin y de hecho se utilizar muy a menudo, pero hay algn caso que no resuelve. En las consultas anteriores, no aparecen las filas que no tienen fila correspondiente en la otra tabla. SELECT numemp,nombre,empleados.oficina, ciudad FROM empleados INNER JOIN oficinas ON empleados.oficina=oficinas.oficina; numemp nombre oficina 101 Antonio Viguer 12 102 Alvaro Jaumes 21 103 Juan Rovira 12 104 Jos Gonzlez 12 105 Vicente Pantalla 13 106 Luis Antonio 11 107 Jorge Gutirrez 22 108 Ana Bustamante 21 109 Mara Sunta 11

ciudad Alicante Badajoz Alicante Alicante Castelln Valencia A Corua Badajoz Valencia

No aparecen los empleados que no tienen oficina, ni las oficinas que no tienen empleados, porque para que salga la fila, debe de existir una fila de la otra tabla que cumpla la condicin. Para resolver este problema debemos utilizar otro tipo de composicin, la composicin externa. Para practicar puedes realizar este Ejercicio La composicin interna INNER JOIN.

Unidad 4. Consultas multitabla (V) 4.8. La Composicin externa LEFT, RIGHT y FULL OUTER JOIN La composicin externa se escribe de manera similar al INNER JOIN indicando una condicin de combinacin pero en el resultado se aaden filas que no cumplen la condicin de combinacin. Sintaxis FROM <tabla_origen> {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla_origen> ON <condicion_combi> La palabra OUTER es opcional y no aade ninguna funcin. Las palabras LEFT, RIGHT y FULL indican la tabla de la cual se van a aadir las filas sin correspondencia.

70

SELECT numemp,nombre,empleados.oficina, ciudad FROM empleados LEFT JOIN oficinas ON empleados.oficina=oficinas.oficina; numemp nombre oficina 101 Antonio Viguer 12 102 Alvaro Jaumes 21 103 Juan Rovira 12 104 Jos Gonzlez 12 105 Vicente Pantalla 13 106 Luis Antonio 11 107 Jorge Gutirrez 22 108 Ana Bustamante 21 109 Mara Sunta 11 110 Juan Victor NULL Ahora s aparece el empleado 110 que no tiene oficina

ciudad Alicante Badajoz Alicante Alicante Castelln Valencia A Corua Badajoz Valencia NULL

Obtiene los empleados con su oficina y los empleados (tabla a la izquierda LEFT del JOIN) que no tienen oficina aparecern tambin en el resultado con los campos de la tabla oficinas rellenados a NULL. SELECT numemp,nombre,empleados.oficina, ciudad, FROM empleados RIGHT JOIN oficinas ON empleados.oficina=oficinas.oficina; numemp nombre oficina 106 Luis Antonio 11 109 Mara Sunta 11 101 Antonio Viguer 12 103 Juan Rovira 12 104 Jos Gonzlez 12 105 Vicente Pantalla 13 102 Alvaro Jaumes 21 108 Ana Bustamante 21 107 Jorge Gutirrez 22 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Las oficinas 23,24,26 y 28 no tienen empleados. Obtiene los empleados con su oficina y las oficinas (tabla a la derecha RIGHT del JOIN) que no tienen empleados aparecern tambin en el resultado con los campos de la tabla empleados rellenados a NULL. SELECT numemp,nombre,empleados.oficina, ciudad, FROM empleados FULL JOIN oficinas ON empleados.oficina=oficinas.oficina; numemp nombre oficina 101 Antonio Viguer 12 102 Alvaro Jaumes 21 103 Juan Rovira 12 104 Jos Gonzlez 12 oficinas.oficina ciudad Alicante Badajoz Alicante Alicante oficina 12 21 12 12 oficinas.oficina ciudad Valencia Valencia Alicante Alicante Alicante Castelln Badajoz Badajoz A Corua Madrid Aranjuez Pamplona Valencia oficina 11 11 12 12 12 13 21 21 22 23 24 26 28

71

105 106 107 108 109 110 NULL NULL NULL NULL

Vicente Pantalla Luis Antonio Jorge Gutirrez Ana Bustamante Mara Sunta Juan Victor NULL NULL NULL NULL

13 11 22 21 11 NULL NULL NULL NULL NULL

Castelln Valencia A Corua Badajoz Valencia NULL Madrid Aranjuez Pamplona Valencia

13 11 22 21 11 NULL 23 24 26 28

Aparecen tanto los empleados sin oficina como las oficinas sin empleados. SELECT numemp,nombre,empleados.oficina, ciudad, oficinas.oficina FROM empleados FULL OUTER JOIN oficinas ON empleados.oficina=oficinas.oficina; Es equivalente, la palabra OUTER como hemos dicho no aade ninguna funcionalidad y se utiliza si se quiere por cuestiones de estilo. NOTA: Cuando necesitamos obtener filas con datos de dos tablas con una condicin de combinacin utilizaremos un JOIN, os aconsejo empezar por escribir el JOIN con la condicin que sea necesaria para combinar las filas, y luego plantearos si la composicin debe de ser interna o externa. Para este segundo paso sta sera la norma a seguir: Empezamos con INNER JOIN. Si pueden haber filas de la primera tabla que no estn relacionadas con filas de la segunda tabla y nos interesa que salgan en el resultado, entonces cambiamos a LEFT JOIN. Si pueden haber filas de la segunda tabla que no estn relacionadas con filas de la primera tabla y nos interesa que salgan en el resultado, entonces cambiamos a RIGHT JOIN. Si necesitamos LEFT y RIGHT entonces utilizamos FULL JOIN.

Siguiendo el ejemplo anterior nos preguntaramos: Pueden haber empleados que no tengan oficina y nos interesan?, si es que s, necesitamos un LEFT JOIN. Seguiramos preguntando: Pueden haber oficinas que no tengan empleados y nos interesan?, si es que s, necesitamos un RIGHT JOIN. Si al final necesitamos LEFT y tambin RIGHT entonces utilizamos FULL JOIN. Para practicar puedes realizar este Ejercicio La composicin externa LEFT JOIN y RIGHT JOIN.

Unidad 4. Consultas multitabla (VI) 4.9. Combinar varias operaciones

72

En las operaciones anteriores tabla_origen puede ser a su vez una composicin de tablas, en este caso aunque slo sea obligatorio cuando queramos cambiar el orden de ejecucin de las composiciones, es recomendable utilizar parntesis para delimitar las composiciones. Por ejemplo: SELECT numemp, nombre, empleados.oficina, ciudad, oficinas.oficina, pedidos.* FROM (oficinas RIGHT JOIN empleados ON empleados.oficina = oficinas.oficina) INNER JOIN pedidos on rep=numemp; O bien: SELECT numemp, nombre, empleados.oficina, ciudad, oficinas.oficina, pedidos.* FROM oficinas RIGHT JOIN (empleados INNER JOIN pedidos on rep = numemp) ON empleados.oficina = oficinas.oficina); Ejercicio propuesto de la Unidad 4 Prueba evaluativa de la Unidad 4

Unidad 5. Consultas de resumen (I) 5.1. Introduccin Una de las funcionalidades de la sentencia SELECT es el permitir obtener resmenes de los datos contenidos en las columnas de las tablas. Para poder llevarlo a cabo la sentencia SELECT consta de una serie de clusulas especficas (GROUP BY, HAVING), y Transact-SQL tiene definidas unas funciones para poder realizar estos clculos, las funciones de agregado (tambin llamadas funciones de columna). La diferencia entre una consulta de resumen y una consulta de las que hemos visto hasta ahora es que en las consultas normales las filas del resultado se obtienen directamente de las filas del origen de datos y cada dato que aparece en el resultado tiene su dato correspondiente en el origen de la consulta mientras que las filas generadas por las consultas de resumen no representan datos del origen sino un total calculado sobre estos datos. Esta diferencia har que las consultas de resumen tengan algunas limitaciones que veremos a lo largo del tema. Un ejemplo sera:

73

A la izquierda tenemos una consulta simple que nos saca las oficinas con sus ventas ordenadas por regin, y a la derecha una consulta de resumen que obtiene la suma de las ventas de las oficinas de cada regin 5.2. Las funciones de agregado Una funcin de agregado SQL acepta un grupo de datos (normalmente una columna de datos) como argumento, y produce un nico dato que resume el grupo. Por ejemplo la funcin AVG() acepta una columna de datos numricos y devuelve la media aritmtica (average) de los valores contenidos en la columna. El mero hecho de utilizar una funcin de agregado en una consulta, convierte sta en una consulta de resumen. Todas las funciones de agregado tienen una estructura muy parecida: Funcin ([ALL|DISTINCT] expression)

El grupo de valores sobre el que acta la funcin lo determina el resultado de la expresin que ser un nombre de columna o una expresin basada en una columna o varias del origen de datos. En la expresin nunca puede aparecer una funcin de agregado ni una subconsulta. La palabra ALL indica que se tiene que tomar en cuenta todos los valores de la columna. Es el valor por defecto. La palabra DISTINCT hace que se consideren todas las repeticiones del mismo valor como uno slo (considera valores distintos). Todas las funciones de agregado se aplican a las filas del origen de datos una vez ejecutada la clusula WHERE (si la hubiera). Si exceptuamos la funcin COUNT, todas las funciones de agregado ignoran los valores NULL. Una funcin de agregado puede aparecer en la lista de seleccin en cualquier lugar en el que puede aparecer un nombre de columna. Puede, por ejemplo, formar parte de una expresin pero no se pueden anidar funciones de agregado. Tampoco se pueden mezclar funciones de columna con nombres de columna ordinarios. Hay excepciones a esta regla pero cuando definimos agrupaciones y subconsultas que veremos ms adelante. Unidad 5. Consultas de resumen (II) 5.3. La funcin COUNT COUNT ({[ALL|DISTINCT] expresion | * } )

Expresion puede ser de cualquier tipo excepto text, image o ntext . No se permite utilizar funciones de agregado ni subconsultas. El tipo de dato devuelto es int. Si el nmero de valores devueltos por expresion es superior a 231-1, COUNT genera un error, en ese caso hay que utilizar la funcin COUNT_BIG.
La funcin cuenta los valores distintos de NULL que hay en la columna. La palabra ALL indica que se tienen que tomar todos los valores de la columna, mientras que DISTINCT hace que se consideren todas las repeticiones del mismo valor como uno solo. Estos parmetros son opcionales, por defecto se considera ALL. Por ejemplo: SELECT COUNT(region) FROM oficinas;

74

Devuelve 9 porque tenemos nueve valores no nulos en la columna region. A la hora de interpretar un COUNT es conveniente no olvidar que cuenta valores no nulos, por ejemplo si interpretramos la sentencia tal cual se lee, cuntas regiones tenemos en oficinas sera errneo, realmente estamos obteniendo cuntas oficinas tienen una regin asignada.

SELECT COUNT(DISTINCT region) FROM oficinas; Devuelve 4 porque tenemos cuatro valores distintos, no nulos, en la columna regin, los valores repetidos los considera slo una vez. Ahora s nos devuelve cuntas regiones tenemos en oficinas. Si utilizamos * en vez de expresin, devuelve el nmero de filas del origen que nos quedan despus de ejecutar la clusula WHERE. COUNT(*) no acepta parmetros y no se puede utilizar con DISTINCT. COUNT(*) no requiere un parmetro expression porque, por definicin, no utiliza informacin sobre ninguna columna especfica. En el recuento se incluyen las filas que contienen valores NULL. SELECT COUNT(*) FROM empleados WHERE oficina=12; Obtiene el nmero de empleados asignados a la oficina 12. Si tenemos un COUNT(columna) y columna no contiene valores nulos, se obtiene el mismo resultado que COUNT(*) pero el COUNT(*) es ms rpido por lo que en este caso hay que utilizarlo en vez de COUNT(columna). Por ejemplo: SELECT COUNT(*) FROM empleados WHERE oficina IS NOT NULL; Es mejor que: SELECT COUNT(oficina) FROM empleados WHERE oficina IS NOT NULL; Las dos nos devuelven el nmero de empleados que tienen una oficina asignada pero la primera es mejor porque se calcula ms rpidamente. Para practicar puedes realizar este Ejercicio La funcin COUNT. 5.4. La funcin COUNT_BIG Funciona igual que la funcin COUNT. La nica diferencia entre ambas funciones est en los valores devueltos, COUNT_BIG siempre devuelve un valor de tipo bigint y por lo tanto admite ms valores de entrada, no est limitado a 231-1 valores de entrada como COUNT. 5.5. La funcin MAX MAX ([ALL|DISTINCT] expression) Devuelve el valor mximo de la expresin sin considerar los nulos. MAX se puede usar con columnas numricas, de caracteres y de datetime , pero no con columnas de bit. No se permiten funciones de agregado ni subconsultas. Utilizar DISTINCT no tiene ningn sentido con MAX (el valor mximo ser el mismo si

75

consideramos las repeticiones o no) y slo se incluye para la compatibilidad con SQL-92. Por ejemplo: SELECT SUM(ventas) AS VentasTotales, MAX(objetivo) AS MayorObjetivo FROM oficinas; Devuelve 9 porque tenemos nueve valores no nulos en la columna region. A la hora de interpretar un COUNT es conveniente no olvidar que cuenta valores no nulos, por ejemplo si interpretramos la sentencia tal cual se lee, cuntas regiones tenemos en oficinas sera errneo, realmente estamos obteniendo cuntas oficinas tienen una regin asignada. Para practicar puedes realizar este Ejercicio La funcin MAX. 5.6. La funcin MIN MIN ([ALL|DISTINCT] expression) Devuelve el valor mnimo de la expresin sin considerar los nulos. MIN se puede usar con columnas numricas, de caracteres y de datetime , pero no con columnas de bit. No se permiten funciones de agregado ni subconsultas. Utilizar DISTINCT no tiene ningn sentido con MIN (el valor mnimo ser el mismo si consideramos las repeticiones o no) y slo se incluye para la compatibilidad con SQL-92.

Unidad 5. Consultas de resumen (III) 5.7. La funcin SUM SUM ([ALL|DISTINCT] expresion ) Devuelve la suma de los valores devueltos por la expresin. Slo puede utilizarse con columnas numricas. El resultado ser del mismo tipo aunque puede tener una precisin mayor. SELECT SUM(importe) FROM pedidos; Obtiene el importe total vendido en todos los pedidos. SELECT SUM(ventas) AS VentasTotales, MAX(objetivo) AS MayorObjetivo FROM oficinas; Devuelve la suma de las ventas de todas las oficinas y de los objetivos de todas las oficinas, el de mayor importe. Para practicar puedes realizar este Ejercicio La funcin SUM. 5.8. La funcin AVG AVG ([ALL|DISTINCT] expresion ) Devuelve el promedio de los valores de un grupo, para calcular el promedio se omiten los valores nulos.

76

El grupo de valores lo determina el resultado de la expresin que ser un nombre de columna o una expresin basada en una columna o varias del origen de datos. La funcin se aplica tambin a campos numricos, y en este caso el tipo de dato del resultado puede cambiar segn las necesidades del sistema para representar el valor del resultado. Para practicar puedes realizar este Ejercicio La funcin AVG. 5.9. La funcin VAR VAR ([ALL|DISTINCT] expresion ) Devuelve la varianza estadstica de todos los valores de la expresin especificada. VAR slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto. 5.10. La funcin VARP VARP ([ALL|DISTINCT] expresion ) Devuelve la varianza estadstica de la poblacin para todos los valores de la expresin especificada. Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto. 5.11. La funcin STDEV STDEV ([ALL|DISTINCT] expresion ) Devuelve la desviacin tpica estadstica de todos los valores de la expresin especificada. Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto. 5.12. La funcin STDEVP STDEVP ([ALL|DISTINCT] expresion ) Devuelve la desviacin estadstica estndar para la poblacin de todos los valores de la expresin especificada. Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto. 5.13. La funcin GROUPING GROUPING (nb_columna) Es una funcin de agregado que genera como salida una columna adicional con el valor 1 si la fila se agrega mediante el operador CUBE o ROLLUP, o el valor 0 cuando la fila no es el resultado de CUBE o ROLLUP. Nb_columna tiene que ser una de las columnas de agrupacin y la clusula GROUP BY debe contener el operador CUBE o ROLLUP. En el siguiente punto, cuando veamos las clusulas CUBE y ROLLUP quedar ms claro.

Unidad 5. Consultas de resumen (IV) 5.14. Agrupamiento de filas (clusula GROUP BY).

77

Hasta ahora las consultas sumarias que hemos visto obtienen totales de todas las filas del origen y producen una nica fila de resultado. Muchas veces cuando calculamos resmenes nos interesan totales parciales, por ejemplo saber de cada empleado cunto ha vendido, y cul ha sido su pedido mximo, de cada cliente cundo fue la ltima vez que nos compr, etc. En todos estos casos en vez de obtener una fila nica de resultados necesitamos una fila por cada empleado, cliente, etc. Podemos obtener estos subtotales con la clusula GROUP BY. GROUP BY [ ALL ] expresion_agrupacion [ ,...n ] [ WITH { CUBE | ROLLUP } ] Una consulta con una clusula GROUP BY agrupa los datos de la tabla origen y produce una nica fila resultado por cada grupo formado. Las columnas indicadas en el GROUP BY se llaman columnas de agrupacin o agrupamiento . Cuando queremos realizar una agrupacin mltiple, por varias columnas, stas se indican en la clusula GROUP BY en el orden de mayor a menor agrupacin igual que con la clusula ORDER BY. expresion_agrupacion puede ser una columna o una expresin no agregada que haga referencia a una columna devuelta por la clusula FROM. Un alias de columna que est definido en la lista de seleccin no puede utilizarse para especificar una columna de agrupamiento. No se pueden utilizar columnas de tipo text, ntext e image en expresion_agrupacion. En las clusulas GROUP BY que no contengan CUBE o ROLLUP, el nmero de columnas de agrupacin est limitado por los tamaos de columna de GROUP BY, las columnas de agregado y los valores de agregado que participan en la consulta. Este lmite procede del lmite de 8.060 bytes de la tabla de trabajo intermedia que se necesita para contener los resultados intermedios de la consulta. Se permite un mximo de 10 expresiones de agrupamiento cuando se especifica CUBE o ROLLUP. Si en la columna de agrupacin existen valores nulos, se generar una fila de resumen para este valor, en este caso se considera el valor nulo como otro valor cualquiera. Ejemplo: SELECT oficina, count(numemp) AS [Nmero de empleados] FROM empleados GROUP BY oficina; Resultado: oficina NULL 11 12 13 21 22 Nmero de empleados 2 2 3 1 2 1

78

Hay empleados sin oficinas (con oficina a nulo), estos forman un grupo con el valor NULL en oficina, en este caso hay dos empleados as. Podemos indicar varias columnas de agrupacin. Ejemplo: SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo] FROM pedidos WHERE YEAR(fechapedido) = 1997 GROUP BY rep, clie ORDER BY rep, clie; Resultado: Nmero rep clie de pedidos 101 2113 1 102 2106 2 102 2120 1 103 2111 2 105 2103 4 105 2111 1 106 2101 1 107 2109 1 107 2124 2 108 2112 1 108 2114 1 108 2118 3 Importe mximo 225,00 21,30 37,50 21,00 275,00 37,45 14,58 313,50 24,30 29,25 71,00 14,20

De cada representante obtenemos el nmero de pedidos y el importe mximo vendido a cada cliente, de las ventas de 1997. La clusula ORDER BY se ha incluido para que las filas aparezcan ordenadas y quede ms claro. Unidad 5. Consultas de resumen (V) Hemos dicho que los resmenes se calculan sobre todas las filas del origen despus de haber ejecutado el WHERE, pues ALL permite obtener un resumen de las filas que no cumplen el WHERE. ALL Incluye todos los grupos y conjuntos de resultados, incluso aquellos en los que no hay filas que cumplan la condicin de bsqueda especificada en la clusula WHERE. Cuando se especifica ALL, se devuelven valores NULL para las columnas de resumen de los grupos que no cumplen la condicin de bsqueda. No se puede especificar ALL con los operadores CUBE y ROLLUP. GROUP BY ALL no se admite en consultas que tienen acceso a tablas remotas si tambin hay una clusula WHERE en la consulta. Por ejemplo, vamos a modificar la consulta anterior: SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo] FROM pedidos

79

WHERE YEAR(fechapedido) = 1997 GROUP BY ALL rep, clie ORDER BY rep, clie; Resultado: Nmero rep clie de pedidos 101 2102 0 101 2108 0 101 2113 1 102 2106 2 102 2120 1 103 2111 2 105 2103 4 105 2111 1 106 2101 1 106 2117 0 107 2109 1 107 2124 2 108 2112 1 108 2114 1 108 2118 3 Importe mximo NULL NULL 225,00 21,30 37,50 21,00 275,00 37,45 14,58 NULL 313,50 24,30 29,25 71,00 14,20

Cul ha sido el efecto de aadir ALL? Se han aadido filas para las filas del origen que no cumplen la condicin del WHERE pero sin que intervengan en el clculo de las funciones de agregado. Por ejemplo el representante 101 tiene pedidos con el cliente 2102 pero estos pedidos no son del ao 1997, por eso aparece la primera fila (no estaba en el resultado de la otra consulta) pero con 0 y NULL como resultados de las funciones de agregado. ROLLUP especifica que, adems de las filas que normalmente proporciona GROUP BY, se incluyen filas de resumen en el conjunto de resultados. Los grupos se resumen en un orden jerrquico, desde el nivel inferior del grupo hasta el superior. La jerarqua del grupo se determina por el orden en que se especifican las columnas de agrupamiento. Cambiar el orden de las columnas de agrupamiento puede afectar al nmero de filas generadas en el conjunto de resultados. Por ejemplo: SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo] FROM pedidos WHERE YEAR(fechapedido) = 1997 GROUP BY rep, clie WITH ROLLUP; Resultado: Nmero clie de pedidos 2113 1 NULL 1 2106 1 Importe mximo 225,00 225,00 21,30

rep 101 101 102

80

102 102 103 103 105 105 105 106 106 107 107 107 108 108 108 108 ... NULL

2120 NULL 2111 NULL 2103 2111 NULL 2101 NULL 2109 2124 NULL 2112 2114 2118 NULL ... NULL

1 3 2 2 4 1 5 1 1 1 2 3 1 1 3 5 ... 23

37,50 37,50 21,00 21,00 275,00 37,45 275,00 14,28 14,28 313,50 24,30 313,50 29,25 71,00 14,20 71,00 ... 450,00

Efecto: Se han aadido automticamente subtotales por cada nivel de agrupamiento y una lnea de totales generales al final. En este caso no hemos incluido ORDER BY porque las filas salen ya ordenadas. Unidad 5. Consultas de resumen (VI) CUBE especifica que, adems de las filas que normalmente proporciona GROUP BY, deben incluirse filas de resumen en el conjunto de resultados. Se devuelve una fila de resumen GROUP BY por cada posible combinacin de grupo y subgrupo del conjunto de resultados. En el resultado se muestra una fila de resumen GROUP BY como NULL, pero se utiliza para indicar todos los valores. Por ejemplo: SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo] FROM pedidos WHERE YEAR(fechapedido) = 1997 GROUP BY rep, clie WITH CUBE; Resultado: Nmero clie de pedidos 2113 1 NULL 1 2106 1 2120 1 NULL 3 2111 2 NULL 2 2103 4 2111 1 Importe mximo 225,00 225,00 21,30 37,50 37,50 21,00 21,00 275,00 37,45

rep 101 101 102 102 102 103 103 105 105

81

105 106 106 107 107 107 108 108 108 108 ... NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL

NULL 2101 NULL 2109 2124 NULL 2112 2114 2118 NULL ... NULL 2101 2103 2106 2107 2108 2109 2111 2112 2113 2114 2118 2120 2124

5 1 1 1 2 3 1 1 3 5 ... 23 1 4 2 1 1 1 3 2 1 1 3 1 2

275,00 14,28 14,28 313,50 24,30 313,50 29,25 71,00 14,20 71,00 ... 450,00 14,58 275,00 21,30 6,32 56,25 313,50 37,45 450,00 225,00 71,00 14,20 37,50 24,30

Efecto: Obtenemos adems de los resultados obtenidos con ROLLUP (los totales por cada representante), los totales por el otro criterio (los totales por cada cliente). El nmero de filas de resumen del conjunto de resultados se determina mediante el nmero de columnas que contiene la clusula GROUP BY. Cada operando (columna) de la clusula GROUP BY se enlaza segn el agrupamiento NULL y se aplica el agrupamiento al resto de los operandos (columnas). CUBE devuelve todas las combinaciones posibles de grupo y subgrupo. Tanto si utilizamos CUBE como ROLLUP, nos ser til la funcin de agregado GROUPING. Si cogemos por ejemplo la primera fila remarcada (101 NULL ) el valor NULL, no sabemos si se refiere a una fila de subtotal o a que el representante 101 ha realizado un pedido sin nmero de cliente. Para poder salvar este problema se utiliza la funcin de agregado GROUPING. SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo], GROUPING(clie) AS [Fila resumen] FROM pedidos WHERE YEAR(fechapedido) = 1997 GROUP BY rep, clie WITH ROLLUP; Nmero Importe Fila rep clie de mximo Resumen pedidos 101 2113 1 225,00 0 101 NULL 1 225,00 1 102 2106 2 21,30 0 102 2120 1 37,50 0 102 NULL 3 37,50 1 103 2111 2 21,00 0

82

Las filas que corresponden a subtotales aparecen con un 1 y las normales con un cero. Ahora que estamos ms familiarizados con las columnas de agrupamiento debemos comentar una regla a no olvidar: EN LA LISTA DE SELECCIN DE UNA CONSULTA DE RESUMEN UN NOMBRE DE COLUMNA NO PUEDE APARECER FUERA DE UNA FUNCIN DE AGREGADO SI NO ES UNA COLUMNA DE AGRUPACIN. Para practicar puedes realizar este Ejercicio Agrupar filas con GROUP BY. Unidad 5. Consultas de resumen (VII) 5.15. Seleccin sobre grupos de filas, la clusula HAVING Cuando queremos incluir una clusula de seleccin sobre las filas del origen, utilizamos la clusula WHERE, pero cuando estamos definiendo una consulta de resumen, no podemos utilizar esta clusula para seleccionar filas del resultado ya que cada una de stas representa un grupo de filas de la tabla original. Para seleccionar filas del resumen tenemos la clusula HAVING. HAVING condicin de bsqueda HAVING funciona igual que la clusula WHERE pero en vez de actuar sobre las filas del origen de datos, acta sobre las filas del resultado, selecciona grupos de filas por lo que la condicin de bsqueda sufrir alguna limitacin, la misma que para la lista de seleccin: Ejemplo: SELECT oficina, count(numemp) AS [Nmero de empleados] FROM empleados GROUP BY oficina HAVING COUNT(numemp)<2; Resultado: oficina 13 22 Nmero de empleados 1 1

Esta SELECT es la misma que la del primer ejemplo del apartado sobre la clusula GROUP BY, la diferencia es que le hemos aadido la clusula HAVING, que hace que del resultado slo se visualicen los grupos que cumplan la condicin. Es decir slo aparecen las oficinas que tienen menos de 2 empleados. Siempre que en una condicin de seleccin haya una funcin de columna, la condicin deber incluirse en la clusula HAVING, adems, como HAVING filtra filas del resultado, slo puede contener expresiones (nombres de columnas, expresiones, funciones) que tambin pueden aparecer en la lista de seleccin, por lo que tambin se aplica la misma regla a no olvidar: EN LA CLUSULA HAVING UN NOMBRE DE COLUMNA NO PUEDE APARECER FUERA DE UNA FUNCIN DE AGREGADO SI NO ES UNA COLUMNA DE AGRUPACIN. Las expresiones que pongamos en HAVING no tienen porqu aparecer en la lista de seleccin, por ejemplo en la SELECT anterior se poda haber escrito:

83

HAVING SUM(ventas)=10000 Para practicar puedes realizar este Ejercicio Seleccin sobre agrupaciones con HAVING. Ejercicio propuesto de la Unidad 5 Unidad 6. Las subconsultas (I) 6.1. Introduccin Una subconsulta es una consulta que aparece dentro de otra consulta o subconsultas, en la lista de seleccin o en la clusula WHERE o HAVING, originalmente no se podan incluir en la lista de seleccin. Una subconsulta se denomina tambin consulta o seleccin interna, mientras que la instruccin que contiene la subconsulta es conocida como consulta o seleccin externa. Aparece siempre encerrada entre parntesis y tiene la misma sintaxis que una sentencia SELECT normal con alguna limitacin: No puede incluir una clusula COMPUTE o FOR BROWSE y slo puede incluir una clusula ORDER BY cuando se especifica tambin una clusula TOP. Una subconsulta puede anidarse en la clusula WHERE o HAVING de una instruccin externa SELECT, INSERT, UPDATE o DELETE, o bien en otra subconsulta. Se puede disponer de hasta 32 niveles de anidamiento, aunque el lmite vara dependiendo de la memoria disponible y de la complejidad del resto de las expresiones de la consulta. Hay que tener en cuenta que para cada fila de la consulta externa, se calcula la subconsulta, si anidamos varias consultas, el nmero de veces que se ejecutarn las subconsultas puede dispararse! Cuando la subconsulta aparece en la lista de seleccin de otra consulta, deber devolver un solo valor, de lo contrario provocar un error. Ejemplo de subconsulta: Listar los empleados cuya cuota no supere el importe vendido por el empleado. SELECT nombre FROM empleados WHERE cuota <= (SELECT SUM(importe) FROM pedidos WHERE rep = numemp); Por cada fila de la tabla de empleados (de la consulta externa) se calcula la subconsulta y se evala la condicin, por lo que utilizar una subconsulta puede en algunos casos ralentizar la consulta, en contrapartida se necesita menos memoria que una composicin de tablas. Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular tambin utilizando composiciones de tablas. Otras preguntas se pueden formular slo con subconsultas. En Transact-SQL, normalmente no hay una regla fija en cuanto a diferencias de rendimiento entre una instruccin que incluya una subconsulta y una versin semnticamente equivalente que no la incluya. Podremos utilizar una subconsulta siempre y cuando no se quiera que aparezcan en el resultado columnas de la subconsulta ya que si una tabla aparece en la subconsulta y no en la consulta externa, las columnas de esa tabla no se pueden incluir en la salida (la lista de seleccin de la consulta externa). Tenemos tres tipos de subconsultas: Prueba evaluativa de la Unidad 5

84

Las que devuelven un solo valor, aparecen en la lista de seleccin de la consulta externa o con un operador de comparacin sin modificar. Las que generan una columna de valores, aparecen con el operador IN o con un operador de comparacin modificado con ANY, SOME o ALL. Las que pueden generar cualquier nmero de columnas y filas, son utilizadas en pruebas de existencia especificadas con EXISTS.

A lo largo del tema las estudiaremos todas. Antes de terminar con la introduccin queda comentar el concepto de referencia externa muy til en las subconsultas. A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de una columna en la fila actual de la consulta externa, el nombre de columna de la consulta externa dentro de la subconsulta recibe el nombre de referencia externa, ya que hace referencia a una columna externa. En el ejemplo anterior numemp es una referencia externa, no es una columna del origen de datos de la subconsulta (pedidos), es una columna del origen de la consulta externa (empleados). Hay que tener en cuenta de cmo se ejecuta la consulta; por cada fila de la consulta externa se calcula el resultado de la subconsulta y se evala la comparacin. En el ejemplo, se coge el primer empleado (numemp= 101, por ejemplo) y se calcula la subconsulta sustituyendo numemp por el valor 101, se calcula la suma de los pedidos del rep = 101, y el resultado se compara con la cuota de ese empleado, y as se repite el proceso con todas las filas de empleados. El nombre de una columna dentro de la subconsulta se presupone del origen de datos de la subconsulta y, slo si no se encuentra en ese origen, la considera como columna externa y la busca en el origen de la consulta externa. Por ejemplo: SELECT oficina, ciudad FROM oficinas WHERE objetivo > (SELECT SUM(ventas) FROM empleados WHERE oficina = oficina); La columna oficina se encuentra en los dos orgenes (oficinas y empleados) pero esta consulta no dar error (no se nos pedir cualificar los nombres como pasara en una composicin de tablas), dentro de la subconsulta se considera oficina el campo de la tabla empleados. Con lo que comparara la oficina del empleado con la misma oficina del empleado y eso no es lo que queremos, queremos comparar la oficina del empleado con la oficina de oficinas, lo escribiremos pues as para forzar a que busque la columna en la tabla oficinas. SELECT oficina, ciudad FROM oficinas WHERE objetivo > (SELECT SUM(ventas) FROM empleados WHERE oficina = oficinas.oficina); Unidad 6. Las subconsultas (II) 6.2. Subconsultas de resultado nico

85

Existen subconsultas que deben obligatoriamente devolver un nico valor, son las que aparecen en la lista de seleccin de la consulta externa o las que aparecen en WHERE o HAVING combinadas con un operador de comparacin sin modificar. Los operadores de comparacin sin modificar son los operadores de comparacin que vimos con la clusula WHERE. Sintaxis: <expresion> {=|<>|!=|>|>=|!>|<|<=|!<} <subconsulta> En este caso la segunda expresin ser una subconsulta, con una sola columna en la lista de seleccin y deber devolver una nica fila como mucho. Ese valor nico ser el que se compare con el resultado de la primera expresin. Si la subconsulta no devuelve ninguna fila, la comparacin opera como si la segunda expresin fuese nula. Si la subconsulta devuelve ms de una fila o ms de una columna, da error. Ejemplo: SELECT nombre FROM empleados WHERE cuota <= (SELECT SUM(importe) FROM pedidos WHERE rep = numemp); La subconsulta devuelve una sola columna y como mucho una fila ya que es una consulta de resumen sin clusula GROUP BY. Para practicar puedes realizar este Ejercicio Subconsultas de resultado nico. 6.3. Subconsultas de lista de valores Otro tipo de subconsultas son las que devuelven una lista de valores en forma de una columna y cero, una o varias filas. Estas consultas aparecen en las clusulas WHERE o HAVING combinadas con el operador IN o con comparaciones modificadas. 6.4. El operador IN con subconsulta <expresion> IN subconsulta IN examina si el valor de expresion es uno de los valores incluidos en la lista de valores generados por la subconsulta. La subconsulta tiene que generar valores de un tipo compatible con la expresin. Ejemplo: SELECT * FROM empleados WHERE oficina IN (SELECT oficina FROM oficinas WHERE region = 'Este');

86

Por cada empleado se calcula la lista de las oficinas del Este (n de oficina) y se evala si la oficina del empleado est en esta lista. Obtenemos pues los empleados de oficinas del Este. numemp 101 103 104 105 106 nombre Antonio Viguer Juan Rovira Jos Gonzlez Vicente Pantalla Luis Antonio edad 45 29 33 37 52 oficina 12 23 23 13 11 titulo representante representante dir ventas representante dir general contrato 1986-10-20 1987-03-01 1987-05-19 1988-02-12 1988-06-14 jefe 104 104 106 104 NULL cuota 30000,00 27500,00 20000,00 35000,00 27500,00 ventas 30500,00 28600,00 14300,00 36800,00 29900,00

Si la subconsulta no devuelve ninguna fila: SELECT * FROM empleados WHERE oficina IN (SELECT oficina FROM oficinas WHERE region = 'Otro'); La lista generada est vaca por lo que la condicin IN devuelve FALSE y en este caso no sale ningn empleado. Muchas veces la misma pregunta se puede resolver mediante una composicin de tablas. SELECT empleados.* FROM Empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina WHERE region = 'Este'; Esta sentencia es equivalente. En el resultado no queremos ver ninguna columna de la tabla oficinas, el JOIN lo tenemos slo para la pregunta, en este caso pues se puede sustituir por una subconsulta.

Unidad 6. Las subconsultas (III) Si combinamos el operador IN con NOT obtenemos el operador NOT IN. <expresion> NOT IN subconsulta Devuelve TRUE si el valor de la expresin no est en la lista de valores devueltos por la subconsulta. SELECT * FROM empleados WHERE oficina NOT IN (SELECT oficina FROM oficinas WHERE region = 'Este'); Devuelve los empleados cuya oficina no est en la lista generada por la subconsulta, es decir empleados que trabajan en oficinas que no son del Este. OJO con NOT IN. Hay que tener especial cuidado con los valores nulos cuando utilizamos el operador NOT IN porque el resultado obtenido no siempre ser el deseado por ejemplo:

87

* En la consulta anterior no salen los empleados que no tienen oficina ya que para esos empleados la columna oficina contiene NULL por lo que no se cumple el NOT IN. * Si la subconsulta no devuelve ninguna fila, la condicin se cumplir para todas las filas de la consulta externa, en este caso todos los empleados. * Si la subconsulta devuelve algn valor NULL, la condicin NOT IN es NULL lo que nos puede ocasionar algn problema. Por ejemplo, queremos obtener las oficinas que no estn asignadas a ningn empleado. SELECT * FROM Oficinas WHERE oficina NOT IN (SELECT oficina FROM empleados); Esta consulta no devuelve ninguna fila cuando s debera ya que hay oficinas que nos estn asignadas a ningn empleado. El problema est en que la columna oficina de la tabla empleados admite nulos por lo que la subconsulta devuelve valores nulos en todos los empleados que no estn asignados a ninguna oficina. Estos valores nulos hacen que no se cumpla el NOT IN. La solucin pasa por eliminar estos valores molestos: SELECT * FROM Oficinas WHERE oficina NOT IN (SELECT oficina FROM empleados WHERE oficina IS NOT NULL); En el primer ejemplo no tenemos ese problema porque la columna oficina en oficinas no admite nulos. A diferencia de IN, NOT IN no siempre puede resolverse con una composicin: SELECT numemp AS [IN] FROM empleados WHERE numemp IN (SELECT rep FROM pedidos WHERE fab = 'ACI'); Se puede resolver con una composicin: SELECT DISTINCT empleados.numemp AS [=] FROM Empleados INNER JOIN pedidos ON numemp = rep WHERE fab = 'ACI'; En este caso, como un empleado puede tener varios pedidos hay que aadir DISTINCT para eliminar las repeticiones de empleados (si un empleado tiene varios pedidos de ACI aparecera varias veces). Sin embargo esta sentencia con NOT IN, queremos los empleados que no tienen pedidos de ACI: SELECT numemp AS [NOT IN] FROM empleados WHERE numemp NOT IN (SELECT rep FROM pedidos

88

WHERE fab = 'ACI'); No se puede resolver con una composicin: SELECT DISTINCT empleados.numemp AS [<>] FROM Empleados INNER JOIN pedidos ON numemp = rep WHERE fab <> 'ACI'; Esta consulta devuelve los empleados que tienen pedidos que no son de ACI, pero un empleado puede tener pedidos de ACI y otros de otros fabricantes y por estos otros saldra en el resultado cuando s tiene pedidos de ACI y no debera salir. Hay que tener mucho cuidado con este tipo de preguntas. Para practicar puedes realizar este Ejercicio El operador IN con subconsulta.

Unidad 6. Las subconsultas (IV) 6.5. La comparacin modificada (ANY, ALL) Los operadores de comparacin que presentan una subconsulta se pueden modificar mediante las palabras clave ALL, ANY o SOME. SOME es un equivalente del estndar de SQL-92 de ANY. Se utiliza este tipo de comparacin cuando queremos comparar el resultado de la expresin con una lista de valores y actuar en funcin del modificador empleado. El test ANY <expresion> {=|<>|!=|>|>=|!>|<|<=|!<} {ANY|SOME} subconsulta ANY significa que, para que una fila de la consulta externa satisfaga la condicin especificada, la comparacin se debe cumplir para al menos un valor de los devueltos por la subconsulta. Por cada fila de la consulta externa se evala la comparacin con cada uno de los valores devueltos por la subconsulta y si la comparacin es True para alguno de los valores ANY es verdadero, si la comparacin no se cumple con ninguno de los valores de la consulta, ANY da False a no ser que todos los valores devueltos por la subconsulta sean nulos en tal caso ANY dar NULL. Si la subconsulta no devuelve filas ANY da False incluso si expresion es nula. Ejemplo: SELECT * FROM empleados WHERE cuota > ANY (SELECT cuota FROM empleados empleados2 WHERE empleados.oficina = empleados2.oficina); Obtenemos los empleados que tienen una cuota superior a la cuota de alguno de sus compaeros de oficina, es decir los empleados que no tengan la menor cuota de su oficina.

89

En este caso hemos tenido un alias de tabla en la subconsulta (empleados2) para poder utilizar una referencia externa. Para practicar puedes realizar este Ejercicio Comparacin modificada ANY. El test ALL <expresion> {=|<>|!=|>|>=|!>|<|<=|!<} ALL subconsulta Con el modificador ALL, para que se cumpla la condicin, la comparacin se debe cumplir con cada uno de los valores devueltos por la subconsulta. Si la subconsulta no devuelve ninguna fila ALL da True. SELECT * FROM empleados WHERE cuota > ALL (SELECT cuota FROM empleados empleados2 WHERE empleados.oficina = empleados2.oficina); En el ejemplo anterior obtenemos los empleados que tengan una cuota superior a todas las cuotas de la oficina del empleado. Podramos pensar que obtenemos el empleado de mayor cuota de su oficina pero no lo es, aqu tenemos un problema, la cuota del empleado aparece en el resultado de subconsulta por lo tanto > no se cumplir para todos los valores y slo saldrn los empleados que no tengan oficina (para los que la subconsulta no devuelve filas). Para salvar el problema tendramos que quitar del resultado de la subconsulta la cuota del empleado modificando el WHERE: WHERE empleados.oficina = empleados2.oficina AND empleados.numemp <> empleados2.numemp); De esta forma saldran los empleados que tienen una cuota mayor que cualquier otro empleado de su misma oficina. O bien WHERE empleados.oficina = empleados2.oficina AND empleados.cuota <> empleados2.cuota); Para no considerar los empleados que tengan la misma cuota que el empleado. En este caso saldran los empleados con la mayor cuota de sus oficina, pero si dos empleados tienen la misma cuota superior, saldran, hecho que no sucedera con la otra versin. Cuando la comparacin es una igualdad, = ANY es equivalente a IN y <> ALL es equivalente a NOT IN (con los mismos problemas).

Unidad 6. Las subconsultas (V) 6.6. Subconsultas con cualquier nmero de columnas (EXISTS) Existe otro operador de subconsulta con el que la subconsulta puede devolver ms de una columna, el operador EXISTS. En este caso la sintaxis es algo diferente:

90

WHERE [NOT] EXISTS subconsulta No se realiza ninguna comparacin con los valores devueltos por la subconsulta, simplemente se evala si la subconsulta devuelve alguna fila, en este caso EXISTS ser True y si la subconsulta no devuelve ninguna fila, EXISTS ser False. Ejemplo: SELECT * FROM empleados WHERE EXISTS (SELECT * FROM pedidos WHERE numemp = rep and fab ='ACI'); Obtenemos los empleados que tengan un pedido del fabricante ACI. Por cada empleado, se calcula la subconsulta (obteniendo los pedidos de ese empleado y con fabricante ACI), si existe alguna fila, el empleado sale en el resultado, si no, no sale. Cuando se utiliza el operador EXISTS es muy importante aadir una referencia externa, no es obligatorio pero en la mayora de los casos ser necesario. Vemoslo con ese mismo ejemplo, si quitamos la referencia externa: SELECT * FROM empleados WHERE EXISTS (SELECT * FROM pedidos WHERE fab ='ACI'); Sea el empleado que sea, la subconsulta siempre devolver filas (si existe algn pedido cuyo fabricante sea ACI) o nunca, indistintamente del empleado que sea, por lo que se obtendrn todos los empleados o ninguno para que el resultado vare segn las filas de la consulta externa habr que incluir una referencia externa. Otra cosa a tener en cuenta es que la lista de seleccin de una subconsulta que se especifica con EXISTS casi siempre consta de un asterisco (*). No hay razn para enumerar los nombres de las columnas porque no se van a utilizar y supone un trabajo extra para el sistema. Si utilizamos NOT EXISTS el resultado ser el contrario. SELECT * FROM empleados WHERE NOT EXISTS (SELECT * FROM pedidos WHERE fab ='ACI' AND rep=numemp); Devuelve los empleados que no tienen ningn pedido de ACI. Para practicar puedes realizar este Ejercicio Subconsultas con EXISTS. Ejercicio propuesto de la Unidad 6 Prueba evaluativa de la Unidad 6

91

Unidad 7. Actualizacin de datos (I) 7.1. Introduccin Hasta ahora hemos trabajado con tablas que tenan datos introducidos y cuando nos ha hecho falta hemos aadido nuevos datos en las mismas y hemos modificado algn dato directamente desde el entorno de SSMS, en este tema veremos cmo hacerlo con instrucciones de TransactSQL. Seguimos en el DML porque las instrucciones que veremos actan sobre los datos de la base de datos no sobre su definicin y tenemos tres tipos de operaciones posibles: Insertar nuevas filas en una tabla. Modificar datos ya almacenados. Eliminar filas de una tabla.

7.2. Insertar creando una nueva tabla Una forma de insertar datos es crear una tabla que incluya los datos de otra. Esta es la sentencia SELECT... INTO. SELECT ... INTO nb_NuevaTabla FROM ...

nb_NuevaTabla es el nombre de la tabla que se va a crear, si en la base de datos ya hay una tabla con ese nombre, el sistema genera un error y no se ejecuta la sentencia.
En la nueva tabla las columnas tendrn el mismo tipo y tamao que las columnas del resultado de la SELECT, se llamarn con el nombre de alias de la columna o en su defecto con el nombre de la columna, pero no se transfiere ninguna otra propiedad del campo o de la tabla como por ejemplo las claves e ndices. Si retomamos el ejemplo del punto anterior: CREATE TABLE trabajo (col1 INT, col2 VARCHAR(20), col3 MONEY); INSERT INTO trabajo SELECT oficina, ciudad, ventas FROM oficinas WHERE region = 'Centro'; Se podra obtener el mismo resultado con una sola instruccin: SELECT oficina AS col1, ciudad AS col2, ventas AS col3 INTO trabajo FROM oficinas WHERE region = 'Centro' Si se tiene poca experiencia en esta instruccin, lo mejor es primero escribir la SELECT que permite obtener las filas a insertar y una vez la tenemos aadir la clusula INTO destino delante de FROM. Para practicar puedes realizar este Ejercicio Insertar datos creando una nueva tabla.

92

7.3. Insertar en una tabla existente INSERT INTO La insercin de nuevos datos en una tabla, se realiza aadiendo filas enteras a la tabla, la sentencia SQL que lo permite es la orden INSERT (o tambin denominada INSERT INTO). De la sentencia INSERT completa, nosotros estudiaremos la sintaxis ms utilizada y estndar: INSERT [INTO] <destino> { [(lista_columnas)] {VALUES ({DEFAULT|NULL|expresion}[ ,...n ]) |tabla_derivada } } |DEFAULT VALUES [;] <destino> ::= { [nbBaseDatos.nbEsquema. | nbEsquema.]nbTablaVista } Con esta instruccin podemos insertar una fila de valores determinados o un conjunto de filas derivadas de otra consulta.

Unidad 7. Actualizacin de datos (II) 7.4. Insertar una fila de valores Para insertar una fila de valores utilizamos la sintaxis: INSERT [INTO] <destino> [( lista_columnas)] VALUES ({DEFAULT|NULL| expresion}[ ,...n ]) [;] La palabra reservada INTO es opcional y no aade funcionalidad a la instruccin, originalmente era obligatoria. Despus de indicar que queremos insertar, debemos indicar dnde, mediante <destino>. <destino> es el nombre de la tabla donde queremos insertar, puede ser un nombre de tabla o un nombre de vista. Si utilizamos una vista, y sta tiene un origen basado en varias tablas, en su lista de seleccin debern aparecer columnas de una sola tabla (no podemos insertar datos en varias tablas a la vez). Con la clusula VALUES indicamos entre parntesis los valores a insertar, separados por comas. Cada valor se puede indicar mediante: una expresin que normalmente ser una constante, mediante la palabra reservada DEFAULT que indica valor por defecto en este caso la columna se rellenar con el valor predeterminado de la columna, si la columna no tiene DEFAULT se sustituir por el valor nulo NULL. Mediante la palabra reservada NULL valor nulo.

Delante de VALUES, de forma opcional podemos indicar una lista de columnas entre parntesis. Las columnas son columnas del destino.

93

Cuando indicamos nombres de columnas, esas columnas sern las que reciban los valores a insertar, la asignacin de valores se realiza por posicin, la primera columna recibe el primer valor, la segunda columna el segundo, y as sucesivamente. En la lista, las columnas pueden estar en cualquier orden y tambin se pueden omitir algunas columnas. Una columna que no aparezca en la lista de columnas se rellenar de acuerdo a su definicin: con con con con su valor por defecto si est definida con la clusula DEFAULT el valor de identidad incremental siguiente si tiene la propiedad IDENTITY. el valor calculado si es una columna calculada. el valor NULL , en cualquier otro caso y si la columna lo admite.

Cuando no se indica una lista de columnas el sistema asume por defecto todas las columnas de la tabla y en el mismo orden que aparecen en la definicin de la tabla, en este caso, los valores se tienen que especificar en el mismo orden que las columnas en la definicin de la tabla, y se tiene que especificar un valor por cada columna ya que los valores se rellenan por posicin, la primera columna recibe el primer valor, la segunda columna el segundo, y as sucesivamente. En cualquier caso, el nmero de valores debe coincidir con el nmero de columnas y los tipos de dato de los valores deben ser compatibles con las columnas. Aunque pueda parecer ms engorroso escribir la lista de columnas, es un hbito recomendable, hace que la sentencia sea ms fcil de leer y mantener (cuando leemos la sentencia sabemos en qu columnas asignamos los valores sin necesidad de consultar la definicin de la tabla) y evita que se tenga que cambiar la sentencia si se modifica el esquema de la tabla (si el orden de las columnas dentro de la tabla cambia). Los registros se agregan al final de la tabla. Cuando se insertan nuevas filas en una tabla, el sistema comprobar que la nueva fila no infrinja ninguna regla de integridad, por ejemplo no podremos asignar a una columna PRIMARY KEY un valor nulo o que ya exista en la tabla, a una columna UNIQUE un valor que ya exista en la tabla, a una columna NOT NULL un valor NULL, a una clave ajena (FOREIGN KEY) un valor que no exista en la tabla de referencia. De producirse alguna de las situaciones anterior, la instruccin genera un mensaje de error y la fila no se inserta. Ejemplos. INSERT INTO oficinas (oficina, ciudad) VALUES (26, 'Elx'); En este caso hemos indicado slo dos columnas y dos valores, las dems columnas se rellenan con el valor por defecto si lo tiene (DEFAULT) o con NULL. Si alguna columna no nombrada no admite nulos ni tiene clusula DEFAULT definida, la instruccin dar error. INSERT INTO oficinas VALUES (27,'Mstoles','Centro',default ,null, default) Aqu no hemos indicado una lista de columnas luego los valores se tienen que indicar en el mismo orden que las columnas dentro de la tabla, si nos equivocamos de orden, el valor se guardar en una columna errnea (si los tipos son compatibles) o generar un mensaje de error y la fila no se insertar (si los tipos no son compatibles). Para practicar puedes realizar este Ejercicio Insertar una fila de valores.

94

Unidad 7. Actualizacin de datos (III) 7.5. Insercin de varias filas Si los valores que queremos insertar los tenemos en otras tablas, podemos insertar varias filas a la vez indicando una consulta que genere las filas de valores a insertar. En este caso utilizamos la sintaxis: INSERT [INTO] <destino> [( lista_columnas)] tabla_derivada [;] <destino> y lista_columnas funcionan igual que en el punto anterior.

Tabla_derivada es cualquier instruccin SELECT vlida que devuelva filas con los datos que se van a cargar en el destino. Cada fila devuelta por la SELECT es una lista de valores que se intentar insertar como con la clusula VALUES, por lo que las columnas devueltas por la SELECT debern cumplir las mismas reglas que los valores de la lista de valores anteriores.
Ejemplo: CREATE TABLE trabajo (col1 INT, col2 VARCHAR(20), col3 MONEY); Creamos una tabla trabajo de 3 columnas INSERT INTO trabajo SELECT oficina, ciudad, ventas FROM oficinas WHERE region = 'Centro'; Insertamos en trabajo el resultado de la SELECT (el nmero de oficina, ciudad y ventas de las oficinas del Centro). En este caso no hemos incluido una lista de columnas, por lo que en la SELECT tenemos que generar los valores en el mismo orden que en trabajo. Si hubiesemos escrito: INSERT INTO trabajo SELECT ciudad, oficina, ventas FROM oficinas WHERE region = 'Centro'; Hubiese dado error porque la columna col1 es INT y el valor a asignar es texto (el nombre de la ciudad de la oficina). INSERT INTO trabajo (col2, col1) SELECT ciudad, oficina FROM oficinas WHERE region = 'Este'; En este caso hemos incluido una lista de columnas, la SELECT debe generar los valores correspondientes, y col3 que no se rellena explcitamente se rellenar con NULL porque la

95

columna col3 no est definida como columna calculada, ni con DEFAULT, ni IDENTITY y adems admite nulos. Para practicar puedes realizar este Ejercicio Insertar varias filas. 7.6. Insertar una fila de valores por defecto TRANSACT-SQL nos permite insertar una fila de valores por defecto utilizando la sintaxis: INSERT [INTO] <destino> DEFAULT VALUES [;] Hace que la nueva fila contenga los valores predeterminados definidos para cada columna. Hay que tener en cuenta una serie de aspectos al utilizar esta instruccin: Puede generar filas duplicadas en la tabla si los valores que se generan son siempre los mismos. Si la tabla tiene una clave principal, esta tendr que estar basada en una columna con la propiedad IDENTITY para que se generen valores diferentes automticamente. Si una columna est definida como NOT NULL tendr que incluir un DEFAULT o ser una columna calculada con una expresin compatible.

Unidad 7. Actualizacin de datos (IV) 7.7. Modificar datos almacenados - UPDATE La sentencia UPDATE modifica los valores de una o ms columnas en las filas seleccionadas de una nica tabla. Para modificar los datos de una tabla es necesario disponer del privilegio UPDATE sobre dicha tabla. UPDATE [ TOP ( expression ) [ PERCENT ] ] <destino> SET { nbcolumna = { expresion | DEFAULT | NULL } } [ ,...n ] [ FROM{ <origen> }] [ WHERE <condicion> ] [;] <destino> ::= { [nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista } Con <destino> indicamos la tabla que se va a actualizar. La clusula SET especifica qu columnas van a modificarse y con qu valor, el valor se puede expresar mediante una expresin, la palabra DEFAULT que equivale al valor predeterminado de la columna, o el valor nulo NULL. Las columnas de identidad no se pueden actualizar. Expresin en cada asignacin debe generar un valor del tipo de dato apropiado para la columna indicada. La expresin debe ser calculable basada en los valores de la fila actualmente en actualizacin. Si para el clculo se utiliza una columna que tambin se modifica, el valor que se utilizar es el de antes de la modificacin, lo mismo para la condicin del WHERE. Expresin tambin puede ser una subconsulta siempre y cuanto devuelva un nico valor y cumpla las condiciones anteriormente expuestas.

96

Por ejemplo: UPDATE oficinas SET ventas = 0; Actualiza todas las filas de la tabla oficinas dejando el campo ventas con el valor cero. Si el campo ventas est definido con un valor predeterminado 0, la sentencia anterior equivale a: UPDATE oficinas SET ventas = DEFAULT; Si lo que queremos es dejar el campo a nulo: UPDATE oficinas SET ventas = NULL; En una misma sentencia podemos actualizar varias columnas, slo tenemos que indicar las distintas asignaciones separadas por comas: UPDATE oficinas SET ventas = 0, objetivo = 0; Los nombres de columna pueden especificarse en cualquier orden. Si no queremos actualizar todas las filas de la tabla sino unas cuantas, utilizaremos la clusula TOP, o unas determinadas, utilizaremos la clusula WHERE. TOP ( expresion ) [ PERCENT ] Especifica el nmero o porcentaje de filas aleatorias que se van a modificar. expression debe generar un valor numrico e indica el nmero de filas a modificar empezando por el principio. Como en la SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin se refiere al porcentaje de filas a modificar sobre el total. La clusula TOP funciona casi igual que en la SELECT pero en este caso, las filas no se ordenan, y la expresin debe ir entre parntesis. Por ejemplo: UPDATE TOP (10) PERCENT oficinas SET ventas = 0; Actualiza el 10% de filas de la tabla oficinas. [ WHERE <condicion> ] Utilizamos la clusula WHERE para filtrar las filas a actualizar. Se actualizarn todas las filas que cumplan la condicin. Por ejemplo si queremos actualizar slo las oficinas del Este: UPDATE oficinas SET ventas = 0 WHERE region = 'Este'; Cuando para la condicin de la clusula WHERE necesitamos un dato de otra tabla podemos utilizar una subconsulta: UPDATE empleados SET ventas = 0 WHERE oficina IN (SELECT oficina

97

FROM oficinas WHERE region = 'Este'); Cuando el campo de la otra tabla se utiliza para la clusula SET, entonces debemos utilizar la clusula FROM. La clusula FROM permite definir un origen de datos basado en varias tablas, y ese origen ser el utilizado para realizar la actualizacin. Por ejemplo queremos actualizar el importe de los pedidos con el precio de la tabla productos. UPDATE pedidos SET importe = cant * precio FROM pedidos INNER JOIN productos ON fab = idfab AND producto = idproducto; Modificamos la tabla pedidos dejando en la columna importe el resultado de multiplicar la cantidad del pedido por el precio del producto que se encuentra en la tabla productos. Si la actualizacin de una fila infringe una restriccin o una regla, infringe la configuracin de valores NULL de la columna o si el nuevo valor es de un tipo de datos incompatible con la columna, se cancela la instruccin, se devuelve un error y no se actualiza ningn registro. Cuando una instruccin UPDATE encuentra un error aritmtico (error de desbordamiento, divisin por cero o de dominio) durante la evaluacin de la expresin, la actualizacin no se lleva a cabo. El resto del lote no se ejecuta y se devuelve un mensaje de error. Adems del permiso de UPDATE, se requieren permisos SELECT para la tabla que se actualiza si la instruccin UPDATE contiene una clusula WHERE o en el caso de que el argumento expression de la clusula SET utilice una columna de la tabla, y permisos SELECT para la tabla del origen si utilizamos una clusula FROM o un WHERE con subconsulta. Para practicar puedes realizar este Ejercicio Modificar datos con UPDATE.

Unidad 7. Actualizacin de datos (V) 7.8. Eliminar filas - DELETE La sentencia DELETE elimina filas de una tabla. Si se borran todas las filas, o se borra la nica fila de una tabla, la definicin de la tabla no desaparece, slo que la tabla se queda vaca. DELETE [ TOP ( expression ) [ PERCENT ] ] [ FROM ] <destino> [ FROM <origen>] [ WHERE < condicion>] [; ] <destino> ::= { [nbBaseDatos. nbEsquema. | nbEsquema.]nbTablaVista } Con esta instruccin podemos eliminar una o varias filas de una tabla. La palabra FROM (la primera) es opcional (originalmente era obligatorio) y no aade funcionalidad slo sirve para introducir el destino. <destino> es el nombre de la tabla de donde queremos eliminar las filas, puede ser un nombre

98

de tabla o un nombre de vista (de momento basada en una slo tabla). La segunda clusula FROM sirve para indicar un origen que permita una condicin de WHERE sobre una tabla diferente de destino. La instruccin bsica sera pues: DELETE oficinas; Equivalente a: DELETE FROM oficinas; Con esta instruccin eliminamos todas las filas de la tabla oficinas. La clusula WHERE permite eliminar determinadas filas, indica una condicin que deben cumplir las filas que se eliminan. Por ejemplo: DELETE oficinas WHERE region = Este; Elimina las oficinas del Este. TOP ( expresion ) [ PERCENT ] Especifica el nmero o porcentaje de filas aleatorias que se van a eliminar. expression debe generar un valor numrico e indica el nmero de filas a eliminar empezando por el principio. Como en la SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin se refiere al porcentaje de filas a eliminar sobre el total. La clusula TOP funciona casi igual que en la SELECT pero en este caso, las filas no se ordenan, y la expresin debe ir entre parntesis. Por ejemplo: DELETE TOP (10) PERCENT FROM oficinas; Elimina el 10% de filas de la tabla oficinas. Originalmente slo se poda indicar una tabla en la clusula FROM, pero ahora podemos indicar un origen basado en varias tablas. Si utilizamos un origen basado en varias tablas, se debe de utilizar una extensin de TRANSACT-SQL que consiste en escribir dos clusulas FROM, una indica la tabla de donde eliminamos las filas y la otra el origen que utilizamos para eliminar. Este caso se produce cuando las filas a eliminar dependen de un valor que est en otra tabla. Por ejemplo queremos eliminar los empleados de las oficinas del Este. Como la regin de la oficina no est en empleados, habra que aadir al origen la tabla oficinas para poder formular la condicin del WHERE: DELETE FROM empleados FROM empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina WHERE region = 'Este';

99

En el origen tenemos las dos tablas y en la primera FROM indicamos de qu tabla queremos borrar. Esto se poda haber resuelto, como toda la vida, mediante una subconsulta:

DELETE FROM empleados WHERE oficina IN (SELECT oficina FROM oficinas WHERE region = 'Este'); Para finalizar no debemos olvidar que para poder ejecutar un DELETE se requieren permisos DELETE en la tabla de donde vamos a eliminar, y tambin se requieren los permisos para utilizar SELECT si la instruccin contiene una clusula WHERE. Muy importante siempre que actualicemos datos en nuestras tablas, no debemos olvidar tampoco las reglas de integridad referencial. Si la tabla afectada interviene como tabla principal en una relacin con otra tabla, no se podrn eliminar sus filas que estn relacionadas con registros de la otra tabla (no se pueden eliminar padres que tengan hijos ). Si se van a eliminar varias filas y al menos una no se puede eliminar por infringir las reglas de integridad, entonces la operacin abortar y no se eliminar ninguna fila. En el ejemplo anterior, si un empleado asignado a una oficina del Este tiene pedidos, no se podr eliminar y entonces no se eliminar ningn empleado. Para practicar puedes realizar este Ejercicio Eliminar filas con DELETE.

Unidad 7. Actualizacin de datos (VI) 7.9. Borrado masivo - TRUNCATE Si queremos eliminar todas las filas de una tabla podemos utilizar tambin la instruccin TRUNCATE TABLE. TRUNCATE TABLE [nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTabla [; ] Esta sentencia quita todas las filas de una tabla sin registrar las eliminaciones individuales de filas. Desde un punto de vista funcional, TRUNCATE TABLE es equivalente a la instruccin DELETE sin una clusula WHERE; no obstante, TRUNCATE TABLE es ms rpida y utiliza menos recursos de registros de transacciones y de sistema. En comparacin con la instruccin DELETE, TRUNCATE TABLE ofrece las siguientes ventajas: Se utiliza menos espacio del registro de transacciones. La instruccin DELETE quita una a una las filas y graba una entrada en el registro de transacciones por cada fila eliminada. TRUNCATE TABLE quita los datos al cancelar la asignacin de las pginas de datos utilizadas para almacenar los datos de la tabla y slo graba en el registro de transacciones las cancelaciones de asignacin de pginas.

100

Por regla general, se utilizan menos bloqueos. Si se ejecuta la instruccin DELETE con un bloqueo de fila, se bloquea cada fila de la tabla para su eliminacin. TRUNCATE TABLE siempre bloquea la tabla y la pgina, pero no cada fila. Las pginas cero se conservan en la tabla sin excepciones. Despus de ejecutar una instruccin DELETE, la tabla puede seguir conteniendo pginas vacas. Por ejemplo, no se puede cancelar la asignacin de las pginas vacas de un montn sin un bloqueo de tabla exclusivo como mnimo. Si en la operacin de eliminacin no se utiliza un bloqueo de tabla, la tabla contiene muchas pginas vacas. En el caso de los ndices, la operacin de eliminacin puede dejar pginas vacas, aunque la asignacin de estas pginas se puede cancelar rpidamente mediante un proceso de limpieza en segundo plano.

Si la tabla contiene una columna de identidad, el contador para dicha columna se restablece al valor de inicializacin definido para ella. Si no se define ningn valor de inicializacin, se utiliza el valor predeterminado 1. Para conservar el contador de identidad, se utiliza DELETE. Pero no todo son ventajas, no se puede utilizar TRUNCATE TABLE en las siguientes tablas: Tablas a las que se hace referencia mediante una restriccin FOREIGN KEY (las tablas que entran como principales en una relacin). Tablas que participan en una vista indizada. Prueba evaluativa de la Unidad 7

Ejercicio propuesto de la Unidad 7

101

Potrebbero piacerti anche