Aunque trabajemos en modo local, la entrada a la herramienta es la
misma. Para empezar entramos a través del acceso directo
o a
través de Inicio, Programas, Microsoft SQL Server 2005, SQL Server
Management Studio.
Lo primero que deberemos hacer es establecer la conexión con el
servidor:
Seleccionamos el nombre del servidor y pulsamos el botón 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 varía según
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 Estándar.
Con las siguientes opciones:
6. Consulta de SQL
Server Mobile
1. Nueva consulta
2. Consulta de motor
Base de datos
3. Consulta MDX
Analysis Services
4. Consulta DMX
Analysis Services
5. Consulta MXLA
Analysis Services
En caso de que utilices la versión Express, es posible que no dispongas
de algunos de éstos botones.
Unidad 1. El entorno gráfico SSMS (II)
1.4. Estructura interna de una base de datos
Antes de empezar tenemos que tener claro cómo se organiza la
información 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 extensión
recomendada para los nombres de archivos de datos principales es .mdf.
de
de
de
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 extensión de nombre de archivo
recomendada para los archivos de datos secundarios es .ndf.
Además 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 información de
registro que se utiliza para recuperar la base de datos, el también
denominado registro de transacciones. Como mínimo, tiene que haber un
archivo de registro por cada base de datos, aunque puede haber varios. La
extensión 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. Sólo las bases de datos de sólo
lectura y los grupos de archivos secundarios de sólo 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 después de la carpeta Instantáneas...
Después de la instalación, 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 demás bases de datos forman también parte del diccionario de datos
y las utiliza el sistema para llevar a cabo su gestión.
Las bases de datos de los usuarios se deben crear preferentemente
fuera de la carpeta Bases de datos del sistema.
Unidad 1. El entorno gráfico SSMS (III)
Para crear una nueva base de datos de usuario nos posicionamos
sobre la carpeta Bases de datos y con el botón derecho del ratón
desplegamos el menú contextual del que elegimos la opción Nueva base
de datos…
Se abre a continuación el cuadro de diálogo donde definiremos la base
de datos que queremos crear:
Lo mínimo a introducir será el campo Nombre de la base de datos, éste
es el nombre de la base de datos lógica, 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 físicos, en la parte
inferior aparecen esos archivos. Para facilitarnos la tarea, al teclear el
nombre de la bd lógica, se rellenan automáticamente los nombres de los
archivos físicos, 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 cambiándolo.
Para cada archivo físico podemos definir una serie de parámetros como
el tipo de archivo (si es de datos o de transacciones Registro) y su
ocupación inicial (Tamaño inicial).
Si no indicamos ninguna ubicación podemos ver que los guarda en la
carpeta
del
SQL
Server/MSSQL.n/MSSQL/DATA.
n representa un número que puede variar de una instalación a otra.
Estos son los archivos mínimos en los que se almacenará la base de
datos, pero como ya vimos anteriormente se puede almacenar en más
archivos, los tenemos que definir todos en esta ventana a continuación de
los dos obligatorios.
Para añadir más archivos físicos disponemos del botón Agregar.
Al pulsar el botón Agregar se crea una nueva fila en la tabla de archivos
físicos donde deberemos escribir el nombre del archivo, su tipo
(desplegando la lista podemos elegir entre de datos o de registro) y
demás parámetros.
Al agregar un nuevo archivo se activa el botón 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 gráfico SSMS (IV)
Si nos fijamos en la zona de la izquierda, vemos que nos encontramos
en la pestaña General, podemos cambiar otros parámetros 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 físicos con los nombres que le hemos
indicado.
Unidad 1. El entorno gráfico 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, deberás adjuntar una base de datos ya existente a tu
servidor. Para ello, lo que tenemos que hacer es pegar los archivos en la
ubicación 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:
Pulsando en Agregar indicamos el archivo de datos primario en su
ubicación y automáticamente se adjuntará la base de datos lógica
asociada a este archivo.
Finalmente pulsamos en Aceptar y aparece la base de datos en
nuestro servidor.
La opción Adjuntar sólo se utiliza la primera vez, cuando todavía no
tenemos la base de datos en el disco.
Realiza el siguiente Ejercicio Adjuntar base de datos. En él adjuntarás
las bases de datos que vas a utilizar en los ejercicios que se plantearán
más 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 información a diferentes programas,
por eso sería absurdo que dejara de funcionar cuando cerramos el
programa gestor, que sólo 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 opción Poner fuera de conexión:
Aparecerá un símbolo a la izquierda de la base de datos
indicándonos 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 opción Poner
en conexión:
El caso más inmediato en el que puedes necesitar conectar y
desconectar la base de datos es copiar a un pendrive los archivos de las
bases que utilizarás en los ejercicios para poder trabajar en diferentes
ordenadores con ellos. Para aprender cómo hacerlo, visita el siguiente
Ejercicio Trasladar una base de datos a otro equipo.
En caso de que tu versión de SQL Server no tenga las opciones Poner
en conexión y Poner fuera de conexión, deberás utilizar la opción
Separar... y luego volver a adjuntarla.
Unidad 1. El entorno gráfico 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 opción Nueva tabla.
En la ventana que se abre debemos definir las columnas de la tabla:
A cada columna se le asigna un nombre, un tipo de datos, y
opcionalmente una serie de propiedades, en este tema veremos las
básicas y las demás las veremos con más detalle cuando veamos la
instrucción
SQL
CREATE
TABLE.
De momento no tenemos definida ninguna columna, al teclear un nombre
se crea una primera entrada en esta tabla con la definición de la primera
columna. En la columna Tipo de datos elegimos qué tipo de valores se
podrán almacenar en la columna.
1.9. Tipos de datos
Podemos elegir entre todos los tipos que aparecen arriba.
Algunos tipos no necesitan más, como por ejemplo el tipo entero (int), y
otros se pueden completar con una longitud, como los tipos
alfanuméricos:
En este ejemplo hemos definido una columna (Codigo) de tipo Entero
corto (Smallint), y una columna (Nombre) que almacenará hasta 20
caracteres alfanuméricos (nchar(20)), en este caso la longitud la
indicamos en la pestaña 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 precisión, los valores
que permiten definir el tamaño del campo
Unidad 1. El entorno gráfico SSMS (VII)
1.10. Valores nulos
También 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 mayoría de los
sistemas gestores de bases de datos tenemos un tipo de datos de tipo
contador, autonumérico, 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 más filas de datos en la tabla.
Las columnas de este tipo se utilizan normalmente para numerar las
filas de la tabla, como no habrán 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 numérico y definiendo la columna como columna de identidad.
En las propiedades de la columna marcamos Sí en la propiedad
(Identidad) y a continuación podemos indicar en qué valor queremos que
empiece el contador (Inicialización de identidad) y en cuánto 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 automáticamente esta función, la
tenemos que definir nosotros mismos, pero sí fuerza a que sea una
columna sin valores nulos. No se puede definir más de una columna de
identidad por tabla.
1.12. Clave primaria
Para definir una columna como clave primaria, posicionamos el puntero
del ratón sobre la columna, desplegamos el menú contextual y
seleccionamos la opción Establecer Clave principal:
Aparecerá una llave a la izquierda del nombre, símbolo 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 opción.
Para quitar una clave principal, hacemos lo mismo pero en esta ocasión
seleccionamos la opción Quitar clave principal.
También podemos utilizar el icono de la barra de herramientas.
Unidad 1. El entorno gráfico SSMS (VIII)
1.13. Añadir o eliminar columnas
Una vez definidas algunas columnas, si queremos añadir una nueva
columna entre dos, nos posicionamos en la segunda y seleccionamos la
opción Insertar columna del menú contextual.
La nueva columna se colocará delante:
Del mismo modo si queremos eliminar la definición de una columna,
nos posicionamos en la columna a eliminar y seleccionamos la opción
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 definición de una tabla
Para entrar a la ventana de definición de la tabla utilizamos la opción
Modificar de su menú contextual (También es posible que se llame
Diseño):
Se abrirá la ventana que ya conocemos para definir las columnas de la
tabla.
Unidad 1. El entorno gráfico 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 sólo tenemos que rellenar los
campos que aparecen en esa fila (la del *), al cambiar de fila los datos se
guardarán automáticamente 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 erróneo, si no lo podemos corregir
entonces sólo podemos deshacer los cambios.
1.16. Modificar datos
Para modificar un valor que ya está en una fila de la tabla sólo tenemos
que posicionarnos en el campo y rectificar el valor. En cuanto modificamos
un valor, la fila aparece con un lápiz escribiendo (ver imagen), este lápiz
nos indica que la fila se ha modificado y tiene nuevos datos por guardar.
Al salir de la fila ésta se guardará automáticamente 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 actualización pulsando la
tecla ESC.
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 opción
Eliminar.
En cualquiera de los dos casos nos aparece un mensaje de
confirmación.
1.18. Relacionar tablas
Como ya hemos visto, en una base de datos relacional, las relaciones
entre las tablas se implementan mediante la definición de claves ajenas,
que son campos que contienen valores que señalan a un registro en otra
tabla, en esta relación así creada, la tabla referenciada se considera
principal y la que contiene la clave ajena es la subordinada.
Desde el entorno gráfico del SSMS podemos definir claves ajenas
entrando en el diseño de la tabla y desplegando el menú contextual del
campo que va a ser clave ajena:
Seleccionamos la opción Relaciones y se abre la ventana:
Al pulsar el botón que se encuentra en la fila Especificación de tablas
y columnas se abre el diálogo donde definiremos la relación:
Unidad 1. El entorno gráfico SSMS (X)
En la parte derecha tenemos la tabla en la que estamos y el campo que
va a actuar como clave ajena, sólo 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 relacionarán las tablas. En nuestro caso será:
De esta forma hemos definido una relación 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 opción
correspondiente:
Si no tenemos todavía ningún diagrama creado, nos aparece un
mensaje:
Elegimos Sí y se crea digamos el soporte donde se pintará el diagrama.
A continuación 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
aparecerán en el diagrama las tablas con las relaciones que tengan
definidas en ese momento:
La llave indica la tabla principal (padre) y el símbolo infinito señala 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 básico para poder crear una base de
datos y rellenarla con tablas relacionadas entre sí y con datos, ahora
veamos cómo recuperar esos datos.
Unidad 1. El entorno gráfico SSMS (XI)
1.19. Abrir una nueva consulta
Vamos a ver ahora cómo 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
botón
de la barra de botones o si queremos realizar la
consulta sobre un servidor con el cual todavía no hemos establecido
conexión, seleccionando de la barra de menús la opción Nuevo >
Consulta de motor de base de datos:
.
En este último caso nos aparecerá el cuadro de diálogo para establecer
la conexión (el mismo que vimos al principio del tema).
A continuación se abrirá una nueva pestaña donde podremos teclear
las sentencias SQL:
Además aparece una nueva barra de botones que nos permitirá
ejecutar los comandos más útiles del modo query.
1.20. Escribir y ejecutar código TRANSACT-SQL
Sólo tenemos que teclear la sentencia a ejecutar, por ejemplo
empezaremos por crear la base de datos.
Utilizaremos la sentencia CREATE DATABASE mínima:
CREATE DATABASE ventas;
Al pulsar el botón Ejecutar se ejecuta la sentencia y aparece en la
parte inferior el resultado de la ejecución, en la pestaña Mensajes:
Si ahora desplegamos la carpeta Bases de Datos del Explorador de
Objetos, observaremos la base de datos que hemos creado:
Si la ejecución de la sentencia produce un error, el sistema nos
devolverá el mensaje de error escrito en rojo en la pestaña Mensajes.
Podemos incluir en una misma consulta varias sentencias SQL, cuando
pulsamos Ejecutar se ejecutarán todas una detrás de otra. Si tenemos
varias consultas y sólo queremos ejecutar una, la seleccionaremos antes
de ejecutarla.
Unidad 1. El entorno gráfico 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.
Fijándonos en la pestaña 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 guión 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 actúe sobre una
determinada base de datos y no nos queremos preocupar de qué base de
datos tenemos activa podemos añadir al principio de la consulta la
instrucción USE nombreBaseDatos; esto hará que todas las
instrucciones que aparezcan después, se ejecuten sobre la base de datos
indicada.
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 sesión.
Para ello, cuando vamos a conectar con el servidor:
Pulsamos en el botón Opciones >>
En la pestaña Propiedades de conexión, 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 gráfico SSMS (XIII)
1.22. El editor de texto
Para facilitarnos la redacción y corrección de las sentencias, el editor de
SQL presenta las palabras de distintos colores según su categoría 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 código se
colorea por categoría. Los colores son los mismos que se utilizan en todo
el entorno SQL Server. En esta tabla aparecen los colores más comunes.
Color
Categoría
Rojo
Cadena de caracteres
Verde oscuro
Comentario
Negro sobre fondo plateado
Comando SQLCMD
Fucsia
Función del sistema
Verde
Tabla del sistema
Azul
Palabra clave
Verde azulado
Números de línea o parámetro de plantilla
Rojo oscuro
Procedimiento almacenado de SQL Server
Gris oscuro
Operadores
1.23. Configurar un esquema de colores personalizado
En el menú Herramientas > Opciones, desplegando la opción
Entorno, Fuentes y colores, se puede ver la lista completa de colores y
sus categorías, así como configurar un esquema de colores
personalizado:
En la lista Mostrar valores para, seleccionamos el entorno que se verá
afectado.
El botón Usar predeterminados nos permite volver a la configuración
predeterminada.
Ahora sólo 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 continuación en el
apartado sobre vistas.
1.24. Las Vistas
Las consultas que hemos visto hasta ahora son trozos de código SQL
que podemos guardar en un archivo de texto y abrir y ejecutar cuando
queramos, pero si queremos que nuestra consulta de recuperación 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 lógica almacenada en memoria y lo que
se guarda en la base de datos es su definición, la instrucción SQL que
permite recuperar los datos.
Para definir una vista en el Explorador de Objetos desplegamos la
base de datos donde la guardaremos y elegimos la opción Nueva vista
del menú contextual de la carpeta Vistas, se pondrá en funcionamiento el
generador de consultas pidiéndonos las tablas en las que se basará la
vista. Pulsamos sobre la tabla a añadir al diseño de la vista y pulsamos el
botón Agregar, podemos añadir así cuántas tablas queramos.
Después de Cerrar, vemos a la derecha del Explorador de Objetos la
pestaña con la definición de la vista que puede incluir varios paneles:
La aparición de estos paneles es configurable, en la barra de
herramientas Diseñador de vistas los iconos remarcados en azul son los
correspondientes a cada panel:
Unidad 1. El entorno gráfico SSMS (XIV)
Nosotros, a lo largo del curso, crearemos las vistas desde el panel SQL
que veremos más adelante.
1.25. El panel de diagrama
Es el primero que aparece, incluye una representación gráfica 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
relación ha aparecido automáticamente al añadir la segunda tabla. Pero
se puede cambiar el tipo de relación eligiendo la opción correspondiente
en el menú contextual que aparece con el clic derecho sobre la relación:
Desde el panel diagrama podemos añadir cómodamente 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 visualizarán todas las columnas de la tabla Libros y ninguna de la
tabla
Préstamos.
Conforme vamos marcando casillas de las tablas del panel diagrama, los
cambios se ven reflejados en los demás 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 expresión cuando se trata de una columna calculada.
En Alias escribimos el nombre que tendrá la columna en la vista, también
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 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 ordenación y Tipo de orden permiten ordenar las
filas del resultado según una o más columnas. Se ordena por las columnas
que tienen algo en Tipo de orden y cuando se ordena por varias columnas
Criterio de ordenación indica que primero se ordena por la columna que
lleva el nº 1 y después por la columna que lleva el nº 2 y así sucesivamente.
En el ejemplo las filas del resultado se ordenarán primero por código de libro
y después por código de préstamo, todas las filas dentro del mismo libro se
ordenarán por código de préstamo.
Si queremos añadir unos criterios de selección tenemos las columnas
Filtro y O…
En cada celda indicamos una condición que debe cumplir la columna
correspondiente y se puede combinar varias condiciones mediante O (OR)
e Y (AND) según coloquemos las condiciones en la misma columna o en
columnas diferentes. En el ejemplo anterior tenemos la condición
compuesta: ((usuario=1) AND (Dias>5)) OR (Usuario=2).
Podemos variar el orden de aparición de las columnas arrastrando la
fila correspondiente de la rejilla hasta el lugar deseado.
También 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 más complejas como por ejemplo consultas
de resumen, pulsando sobre el botón Agrupar por de la barra de
herramientas, se añade a la rejilla una nueva columna Agrupar por con
las siguientes opciones:
Unidad 1. El entorno gráfico SSMS (XV)
1.27. El panel SQL
En él vemos la instrucción SQL generada, también 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 demás paneles.
Por defecto el generador añade a la consulta una cláusula TOP (100)
PERCENT que indica que se visualizarán el 100% de las filas. Esta
cláusula no la hemos definido nosotros sino que la añade
automáticamente 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 definición y ejecutarla, igual que con las tablas:
Modificar para modificar la definición de la vista
Abrir vista para ejecutarla y ver los datos como si fuese una tabla real.
Ejercicios unidad 1: El entorno gráfico SSMS (I)
Ejercicio 1: Crear una base de datos
Se desea implementar una base de datos para el control de una
biblioteca. Crea la base de datos con el nombre Biblioteca y las opciones
por defecto.
Puedes consultar aquí las soluciones propuestas.
Ejercicio 2: Crear y definir tablas
Crea las tablas Libros, Préstamos y Usuarios de forma que sigan el
siguiente esquema:
Tabla Libros
NOMBRE CAMPO TIPO DE DATOS
TAMAÑO
Codigo
Numérico
Byte
Nombre
Texto
60
Editorial
Texto
25
Autor
Texto
25
Genero
Texto
20
PaisAutor
Texto
20
Paginas
Numérico
Entero
AnyEdicion
Fecha/Hora
Fecha mediana
Precio
Moneda
Dias
Numérico
Entero
Tabla Préstamos
NOMBRE CAMPO
TIPO DE DATOS
TAMAÑO
Codigo
Autonumérico
Libro
Numérico
Byte
Usuario
Numérico
Byte
FSalida
Fecha/Hora
Fecha mediana
FMaxima
Fecha/Hora
Fecha mediana
FDevol
Fecha/Hora
Fecha mediana
TIPO DE DATOS
TAMAÑO
Tabla Usuarios
NOMBRE CAMPO
Codigo
Autonumérico
Nombre
Texto
15
Apellidos
Texto
25
DNI
Texto
12
Domicilio
Texto
50
Poblacion
Texto
30
Provincia
Texto
20
FNacim
Fecha/Hora
Fecha mediana
Maximo_permitido
Numérico
Entero
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 1: El entorno gráfico SSMS
Ejercicio 1: Crear una base de datos
Para crear la base de datos con el nombre Biblioteca y las opciones
por defecto:
1. Abre el SQL Server Management Studio Express que instalaste.
2. Haz clic con el botón secundario del ratón sobre la carpeta Bases de
datos del Explorador de objetos.
3. Selecciona Nueva base de datos...
4. Llámala Biblioteca y deja los nombres y características de los
archivos con su definición predeterminada. Pulsa Aceptar.
5. Despliega el contenido de la nueva carpeta Biblioteca pulsando
sobre el signo + para comprobar que se ha creado correctamente.
Ejercicio 2: Crear y definir tablas
Para crear las tablas:
1. Despliega el contenido de la base de datos Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de Tablas y escoge la opción Nueva
tabla...
3. Escribe el nombre de cada columna y escoge el tipo de datos en el
desplegable. En la zona inferior, en la pestaña Propiedades de columna,
busca el campo que define el tamaño del dato y cámbialo si es necesario.
4. Cuando hayas acabado, pulsa el botón Guardar o cierra la tabla y
dale el nombre correspondiente.
5. Repite los pasos para cada una de las tres tablas.
Ejercicio 3: Insertar datos en las tablas
Para insertar los datos en las tablas.
1. Despliega el contenido de la carpeta Tablas de Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de una de las tablas y escoge la
opción Abrir tabla. Rellena los campos.
3. Repite la operación para las otras dos tablas.
Ejercicio 4: Modificar la definición de las tablas
Para
modificar
la
definición
de
las
tablas:
Ten en cuenta que las claves primarias serán los campos codigo de
cada tabla. Además, el campo Libro de la tabla Prestamos es clave
ajena, hace referencia al Codigo de Libros. Y el campo Usuario también
es clave ajena, hace referencia al Codigo de Usuarios
1. Despliega el contenido de la carpeta Tablas de Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de la tabla que quieras modificar y
escoge la opción Diseño (o Modificar).
3. Incluye la clave primaria seleccionando la columna Codigo y
pulsando el botón en forma de llave de la barra de herramientas.
4. Si la tabla contiene una clave ajena, indícalo desplegando el menú
contextual del campo que quieres relacionar y seleccionando
Relaciones...
5. No olvides marcar o desmarcar la casilla Permite valores nulos
convenientemente.
6. Repite la operación para las otras dos tablas.
Ejercicios unidad 1: El entorno gráfico SSMS (II)
Ejercicio 3: Insertar datos en las tablas
Inserta los datos en las tablas de forma que el resultado sea el
siguiente:
Puedes consultar aquí las soluciones propuestas.
Ejercicio 4: Modificar la definición de las tablas
Observando los datos, averigua:
Claves primarias
Claves ajenas
Valores no nulos (supondremos que una columna no admite nulos si en los
datos sumnistrados no hay ningún nulo en esa columna).
Modifica la definición de las tablas para incorporar esta información.
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 1: El entorno gráfico SSMS
Ejercicio 1: Crear una base de datos
Para crear la base de datos con el nombre Biblioteca y las opciones
por defecto:
1. Abre el SQL Server Management Studio Express que instalaste.
2. Haz clic con el botón secundario del ratón sobre la carpeta Bases de
datos del Explorador de objetos.
3. Selecciona Nueva base de datos...
4. Llámala Biblioteca y deja los nombres y características de los
archivos con su definición predeterminada. Pulsa Aceptar.
5. Despliega el contenido de la nueva carpeta Biblioteca pulsando
sobre el signo + para comprobar que se ha creado correctamente.
Ejercicio 2: Crear y definir tablas
Para crear las tablas:
1. Despliega el contenido de la base de datos Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de Tablas y escoge la opción Nueva
tabla...
3. Escribe el nombre de cada columna y escoge el tipo de datos en el
desplegable. En la zona inferior, en la pestaña Propiedades de columna,
busca el campo que define el tamaño del dato y cámbialo si es necesario.
4. Cuando hayas acabado, pulsa el botón Guardar o cierra la tabla y
dale el nombre correspondiente.
5. Repite los pasos para cada una de las tres tablas.
Ejercicio 3: Insertar datos en las tablas
Para insertar los datos en las tablas.
1. Despliega el contenido de la carpeta Tablas de Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de una de las tablas y escoge la
opción Abrir tabla. Rellena los campos.
3. Repite la operación para las otras dos tablas.
Ejercicio 4: Modificar la definición de las tablas
Para
modificar
la
definición
de
las
tablas:
Ten en cuenta que las claves primarias serán los campos codigo de
cada tabla. Además, el campo Libro de la tabla Prestamos es clave
ajena, hace referencia al Codigo de Libros. Y el campo Usuario también
es clave ajena, hace referencia al Codigo de Usuarios
1. Despliega el contenido de la carpeta Tablas de Biblioteca, en el
Explorador de objetos.
2. Despliega el menú contextual de la tabla que quieras modificar y
escoge la opción Diseño (o Modificar).
3. Incluye la clave primaria seleccionando la columna Codigo y
pulsando el botón en forma de llave de la barra de herramientas.
4. Si la tabla contiene una clave ajena, indícalo desplegando el menú
contextual del campo que quieres relacionar y seleccionando
Relaciones...
5. No olvides marcar o desmarcar la casilla Permite valores nulos
convenientemente.
6. Repite la operación para las otras dos tablas.
Ejercicios unidad 3: Consultas simples
Te aconsejamos que, para realizar consultas SQL más fácilmente, te
hagas estas preguntas:
¿Dónde están los datos necesarios? La respuesta dará la FROM.
¿Qué columnas quiero que se visualicen en el listado? La respuesta dará la
lista de selección (SELECT).
¿Quiero que se ordenen por algún valor? Si la respuesta es sí, necesitarás
utilizar ORDER BY.
¿Tienen que aparecer todas las filas del resultado? Si la respuesta es NO,
deberás:
o
Utilizar TOP para quedarte con las N primeras.
o
Utilizar DISTINCT si no quieres que se muestren las repetidas.
o
O bien utilizar la cláusula WHERE para expresar la condición que
deben cumplir para ser mostradas.
Para realizar los ejercicios, deberás utilizar la base de datos
GestionSimples, en la carpeta Ejercicios del curso tienes el PDF
Tablas_Gestion para consultar en qué tablas está cada campo.
Ejercicio 1: Listas de selección
1. Listar todos los empleados.
Resultado:
Nume Nombre Eda Ofici
mp
d
na
Titulo
Contrato Jefe Cuota ventas
101
Antonio
Viguer
4
5
12
represen
tante
198610-20
00:00:0
0.000
10
4
3000
0,00
3050
0,00
102
Alvaro
Jaume
s
4
8
21
represen
tante
198612-10
00:00:0
0.000
10
8
3500
0,00
4740
0,00
103
Juan
Rovira
2
9
12
represen
tante
198703-01
00:00:0
0.000
10
4
2750
0,00
2860
0,00
104
José
Gonzál
ez
3
3
12
dir
ventas
198705-19
00:00:0
0.000
10
6
2000
0,00
1430
0,00
105
Vicente
Pantall
a
3
7
13
represen
tante
198802-12
00:00:0
10
4
3500
0,00
3680
0,00
0.000
106
Luis
Antonio
5
2
11
director
general
198806-14
00:00:0
0.000
NU
LL
2750
0,00
2990
0,00
107
Jorge
Gutiérr
ez
4
9
22
represen
tante
198811-14
00:00:0
0.000
10
8
3000
0,00
1860
0,00
108
Ana
Bustam
ante
6
2
21
dir
ventas
198910-12
00:00:0
0.000
10
6
3500
0,00
3610
0,00
109
María
Sunta
3
1
NU
LL
represen
tante
199910-12
00:00:0
0.000
10
6
3000,
00
3920
0,00
110
Juan
Victor
4
1
NU
LL
represen
tante
199001-13
00:00:0
0.000
10
4
NULL
7600,
00
111
Juan
Gris
5
0
NU
LL
represen
tante
200505-01
00:00:0
0.000
NU
LL
1000
0,00
6000
0,00
112
Julián
Martore
ll
5
0
NU
LL
represen
tante
200605-01
00:00:0
0.000
NU
LL
1000
0,00
9100
0,00
113
Juan
Gris
1
8
NU
LL
represen
tante
200701-01
00:00:0
0.000
NU
LL
1000
0,00
0,00
2. Listar todos los empleados, al igual que en el ejercicio anterior, pero
cambiando el nombre de la columna contrato por Fecha de contrato.
Puedes consultar aquí las soluciones propuestas.
Ejercicio 2: Utilizando ORDER BY
1. Listar de cada región las oficinas por orden de mejores ventas.
Resultado:
Región
Ciudad
Ventas
NULL
Elx
0,00
NULL
Valencia
NULL
centro
Aranjuez
15000,00
Centro
Móstoles
0,00
centro
Madrid
NULL
este
Alicante
73500,00
este
Valencia
69300,00
este
Castellon
36800,00
este
Valencia
2100,00
este
Valencia
0,00
norte
Pamplona
200000,00
norte
pamplona
NULL
oeste
Badajoz
84400,00
oeste
A Coruña
18600,00
2. Saber los productos que tienen un precio superior o igual al precio de la
mitad de los productos.
Resultado:
Idfab Idproducto Descripción Precio existencias
rei
2a44l
bomba l
45,00
12
rei
2a44r
bomba r
45,00
12
imm
779c
reostato 3
18,75
0
imm
775c
reostato 2
14,25
5
imm
773c
reostato
9,75
28
bic
41003
manivela
6,52
3
imm
887x
manivela
4,75
32
qsa
xk47
red
3,55
38
rei
2a44g
pas
3,50
14
fea
114
cubo
2,43
15
bic
41089
rodamiento
2,25
78
bic
41672
plato
1,80
0
fea
112
cubo
1,48
115
qsa
xk48a
red
1,48
37
Puedes consultar aquí las soluciones propuestas.
Ejercicio 2: Utilizando WHERE
1. Listar los empleados que tienen ventas pero que no han alcanzado su cuota.
Resultado:
Numemp
Nombre
Ventas
cuota
104
José González
14300,00
20000,00
107
Jorge Gutiérrez
18600,00
30000,00
2. Hallar los empleados que no están a cargo del empleado 106.
Resultado:
Numemp
101
nombre
Antonio Viguer
3.
102
Alvaro Jaumes
103
Juan Rovira
105
Vicente Pantalla
106
Luis Antonio
107
Jorge Gutiérrez
110
Juan Victor
111
Juan Gris
112
Julián Martorell
113
Juan Gris
Listar de cada jefe su código y el código y nombre de sus subordinados
ordenados por nombres.
Resultado:
Jefe Numemp
nombre
104
101
Antonio Viguer
104
103
Juan Rovira
104
110
Juan Victor
104
105
Vicente Pantalla
106
108
Ana Bustamante
106
104
José González
106
109
María Sunta
108
102
Alvaro Jaumes
108
107
Jorge Gutiérrez
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 3: Consultas simples
Ejercicio 1: Listas de selección
Para listar todos los empleados:
SELECT * FROM empleados;
Para listar todos los empleados, cambiando el nombre de la columna
contrato por Fecha de contrato: Utilizaremos un alias, y lo incluiremos
entre corchetes para que no haya errores con el caracter de espacio en
blanco:
SELECT numemp, nombre, edad, oficina, titulo, contrato
as [Fecha de contrato], jefe, cuota, ventas
FROM empleados;
Ejercicio 2: Utilizando ORDER BY
Para listar de cada región las oficinas por orden de mejores ventas:
SELECT region, ciudad, ventas
FROM oficinas
ORDER BY region, ventas DESC;
Para saber los productos que tienen un precio superior o igual al
precio de la mitad de los productos.
SELECT TOP 50 PERCENT WITH TIES *
FROM productos
ORDER BY precio DESC;
Ejercicio 2: Utilizando WHERE
Para listar los empleados que tienen ventas pero que no han
alcanzado su cuota.
SELECT numemp, nombre, ventas, cuota
FROM empleados
WHERE ventas < cuota AND ventas >0;
Para hallar los empleados que no están a cargo del empleado 106.
SELECT numemp, nombre
FROM empleados
WHERE jefe <> 106 OR jefe IS NULL;
Si no añadimos la segunda parte de la pregunta (OR jefe IS NULL) los
empleados que no tienen jefe no salen.
Para listar de cada jefe su código y el código y nombre de sus
subordinados ordenados por nombres.
SELECT jefe, numemp, nombre
FROM empleados
WHERE jefe IS NOT NULL
ORDER BY jefe, nombre;
Ejercicios unidad 4: Consultas multitabla
Para realizar los ejercicios, deberás utilizar la base de datos
GestionSimples, en la carpeta Ejercicios del curso tienes el PDF
Tablas_Gestion para consultar en qué tablas está cada campo.
Ejercicio 1: La composición de tablas
1. Listar todos los pedidos, mostrando el precio y la descripción del producto.
Resultado:
Codi Numpe Fechape Clie Re Fab Produ Ca Impo Prec descrip
go
dido
dido
p
cto nt rte
io
cion
1
11003
6
198910-12
00:00:0
0.000
21
07
1
1
0
ac
i
410
0z
9
22,
50
NU
LL
mont
2
11003
7
198910-12
00:00:0
0.000
21
17
1
0
6
rei
2a4
4l
7
31,
50
45,
00
bomb
al
3
11296
3
200805-10
00:00:0
0.000
21
03
1
0
5
ac
i
410
04
2
8
3,2
76
NU
LL
art t4
4
11296
8
199001-11
00:00:0
0.000
21
02
1
0
1
ac
i
410
04
3
4
39,
78
NU
LL
art t4
5
11297
5
200802-11
00:00:0
0.000
21
11
1
0
3
rei
2a4
4g
6
21,
00
3,5
0
pas
6
11297
9
198910-12
00:00:0
0.000
21
14
1
0
8
ac
i
410
0z
6
150
,00
NU
LL
mont
7
11298
3
200805-10
00:00:0
0.000
21
03
1
0
5
ac
i
410
04
6
7,0
2
NU
LL
art t4
8
11298
7
200801-01
00:00:0
0.000
21
03
1
0
5
ac
i
410
0y
1
1
275
,00
NU
LL
extrac
tor
9
11298
9
200812-10
00:00:0
0.000
21
01
1
0
6
fe
a
114
6
14,
58
2,4
3
cubo
10
11299
2
199004-15
00:00:0
0.000
21
18
1
0
8
ac
i
410
02
1
0
7,6
0
NU
LL
bisagr
a
11
11299
3
200803-10
00:00:0
21
06
1
0
rei
2a4
5c
2
4
18,
96
0,7
9
junta
0.000
2
12
11299
7
200804-04
00:00:0
0.000
21
24
1
0
7
bi
c
410
03
1
6,5
2
6,5
2
maniv
ela
13
11300
3
200802-05
00:00:0
0.000
21
08
1
0
9
im
m
779c
3
56,
25
18,
75
reosta
to 3
14
11300
7
200801-01
00:00:0
0.000
21
12
1
0
8
im
m
773c
3
29,
25
9,7
5
reosta
to
15
11301
2
200805-05
00:00:0
0.000
21
11
1
0
5
ac
i
410
03
3
5
37,
45
NU
LL
art t3
16
11301
3
200812-28
00:00:0
0.000
21
18
1
0
8
bi
c
410
03
1
6,5
2
6,5
2
maniv
ela
17
11302
4
200807-04
00:00:0
0.000
21
14
1
0
8
qs
a
xk47
2
0
71,
00
3,5
5
red
18
11302
7
200802-05
00:00:0
0.000
21
03
1
0
5
ac
i
410
02
5
4
450
,00
NU
LL
bisagr
a
19
11303
4
200811-05
00:00:0
0.000
21
07
1
1
0
rei
2a4
5c
8
6,3
2
0,7
9
junta
20
11304
2
200801-01
00:00:0
0.000
21
13
1
0
1
rei
2a4
4r
5
225
,00
45,
00
bomb
ar
21
11304
5
200807-02
00:00:0
0.000
21
12
1
1
0
rei
2a4
4r
1
0
450
,00
45,
00
bomb
ar
22
11304
8
200802-02
00:00:0
0.000
21
20
1
0
2
im
m
779c
2
37,
50
18,
75
reosta
to 3
23
11304
9
200804-04
00:00:0
0.000
21
18
1
0
8
qs
a
xk47
2
7,7
6
3,5
5
red
24
11305
1
200807-06
00:00:0
0.000
21
18
1
0
8
qs
a
xk47
4
14,
20
3,5
5
red
25
11305
5
200904-01
00:00:0
0.000
21
08
1
0
1
ac
i
410
0x
6
1,5
0
NU
LL
junta
26
11305
7
200811-01
00:00:0
0.000
21
11
1
0
3
ac
i
410
0x
2
4
NU
LL
NU
LL
junta
27
11305
8
198907-04
00:00:0
0.000
21
08
1
0
9
fe
a
112
1
0
14,
80
1,4
8
cubo
28
11306
2
200807-04
00:00:0
0.000
21
24
1
0
7
bi
c
410
03
1
0
24,
30
6,5
2
maniv
ela
29
11306
5
200806-03
00:00:0
0.000
21
06
1
0
2
qs
a
xk47
6
21,
30
3,5
5
red
30
11306
9
200808-01
00:00:0
21
09
1
0
im
m
773c
2
2
313
,50
9,7
5
reosta
to
0.000
7
Puedes consultar aquí las soluciones propuestas.
2. Listar los pedidos superiores a 250 euros, incluyendo el nombre del
vendedor que tomó el pedido y el nombre del cliente que lo solicitó.
Resultado:
Numped Fechape Clie Rep Fab Produ Ca Preci Client vended
ido
dido
cto
nt
o
e
or
11298
7
01/01/0
8
21
03
10
5
aci
4100
y
1
1
275,
00
Jaim
e
Llore
ns
Vicent
e
Pantal
la
11302
7
05/02/0
8
21
03
10
5
aci
4100
2
5
4
450,
00
Jaim
e
Llore
ns
Vicent
e
Pantal
la
11304
5
02/07/0
8
21
12
11
0
rei
2a44
r
1
0
450,
00
Marí
a
Silva
Juan
Victor
11306
9
01/08/0
8
21
09
10
7
im
m
773c
2
2
313,
50
Alber
to
Juan
es
Jorge
Gutiér
rez
3. Listar los pedidos superiores a 250 euros, mostrando el nombre del cliente
que solicitó el pedido y el nombre del vendedor asignado a ese cliente.
Resultado:
Codi Numpe Fechape Clie Re Fab Produ Ca Impo Clien Vended
go
dido
dido
p
cto nt rte
te
or
asignad
o
8
1129
87
200801-01
00:00:0
0.000
21
03
1
0
5
ac
i
410
0y
1
1
275
,00
Jai
me
Llor
ens
Juan
Victor
18
1130
27
200802-05
00:00:0
0.000
21
03
1
0
5
ac
i
410
02
5
4
450
,00
Jai
me
Llor
ens
Juan
Victor
21
1130
45
200807-02
00:00:0
0.000
21
12
1
1
0
rei
2a4
4r
1
0
450
,00
Mar
ía
Silv
a
Ana
Busta
mante
30
1130
69
200808-01
00:00:0
0.000
21
09
1
0
7
im
m
773
c
2
2
313
,50
Alb
erto
Jua
nes
Juan
Rovira
Puedes consultar aquí las soluciones propuestas.
4. Listar los pedidos superiores a 250 euros, mostrando además el nombre del
cliente que solicitó º el pedido y el nombre del vendedor asignado a ese
cliente y la ciudad de la oficina donde el vendedor trabaja.
Resultado:
Numpedido Clie
Rep
Cliente
Repclie
Vendedor
asignado
ciudad
112987
2103
105
Jaime
Llorens
105
Juan Victor
NULL
113027
2103
105
Jaime
Llorens
105
Juan Victor
NULL
113045
2112
110
María
Silva
110
Ana
Bustamante
Badajoz
113069
2109
107
Alberto
Juanes
107
Juan Rovira
Alicante
5. Hallar los pedidos recibidos los días en que un nuevo empleado fue
contratado.
Resultado:
Numpedid Fechapedido Rep Numem
o
p
Nombre
Contrato
110036
1989-10-12
00:00:00.00
0
11
0
108
Ana
Bustamant
e
1989-10-12
00:00:00.00
0
110037
1989-10-12
00:00:00.00
0
10
6
108
Ana
Bustamant
e
1989-10-12
00:00:00.00
0
112979
1989-10-12
00:00:00.00
0
10
8
108
Ana
Bustamant
e
1989-10-12
00:00:00.00
0
6. Hallar los empleados que realizaron su primer pedido el mismo día que
fueron contratados.
Resultado:
Numem
p
108
Nombre
Contrato
Ana
Bustamant
e
1989-10-12
00:00:00.00
0
Numpedid Rep fechapedido
o
112979
10
8
1989-10-12
00:00:00.00
0
7. Mostrar de cada empleado su código, nombre, ventas, oficina y ciudad en la
que está ubicada su oficina.
Resultado:
Numemp
Nombre
ventas
Oficina
ciudad
101
Antonio Viguer
30500,00
12
Alicante
102
Alvaro Jaumes
47400,00
21
Badajoz
103
Juan Rovira
28600,00
12
Alicante
104
José González
14300,00
12
Alicante
105
Vicente Pantalla
36800,00
13
Castellon
106
Luis Antonio
29900,00
11
Valencia
107
Jorge Gutiérrez
18600,00
22
A Coruña
108
Ana Bustamante
36100,00
21
Badajoz
109
María Sunta
39200,00
NULL
NULL
110
Juan Victor
7600,00
NULL
NULL
111
Juan Gris
60000,00
NULL
NULL
112
Julián Martorell
91000,00
NULL
NULL
113
Juan Gris
0,00
NULL
NULL
Puedes consultar aquí las soluciones propuestas.
8. Listar los empleados con una cuota superior a la de su jefe, los campos a
obtener son el número, nombre y cuota del empleado y número, nombre y
cuota de su jefe.
Resultado:
Numemp
Nombre
Cuota
Jefe
Nombre jefe Cuota jefe
101
Antonio Viguer
30000,00
104
José
González
20000,00
103
Juan Rovira
27500,00
104
José
González
20000,00
105
Vicente
Pantalla
35000,00
104
José
González
20000,00
108
Ana
Bustamante
35000,00
106
Luis Antonio
27500,00
9. Desde el entorno gráfico cambia el empleado 111, asígnale el jefe 110 y la
oficina 21. Después cambia la sentencia anterior para que salgan también
los empleados cuyo jefe no tenga cuota.
Resultado:
Numemp
Nombre
Cuota
Jefe
Nombre jefe Cuota jefe
101
Antonio Viguer
30000,00
104
José
González
20000,00
103
Juan Rovira
27500,00
104
José
González
20000,00
105
Vicente
Pantalla
35000,00
104
José
González
20000,00
108
Ana
Bustamante
35000,00
106
Luis Antonio
27500,00
111
Juan Gris
10000,00
110
Juan Victor
NULL
10. Listar los empleados que no están asignados a la misma oficina que su jefe,
queremos número, nombre y número de oficina tanto del empleado como de
su jefe.
Resultado:
Numemp
Nombre
Oficina Jefe
Nombre jefe
Oficina
jefe
104
José González
12
106
Luis Antonio
11
105
Vicente Pantalla
13
104
José González
12
107
Jorge Gutiérrez
22
108
Ana
Bustamante
21
108
Ana
Bustamante
21
106
Luis Antonio
11
11. En el punto anterior no salen los que no tienen oficina, cambiar la sentencia
para que aparezcan.
Resultado:
Numemp
Nombre
Oficina Jefe
Nombre jefe
Oficina
jefe
104
José González
12
106
Luis Antonio
11
105
Vicente Pantalla
13
104
José González
12
107
Jorge Gutiérrez
22
108
Ana
Bustamante
21
108
Ana
Bustamante
21
106
Luis Antonio
11
109
María Sunta
NULL
106
Luis Antonio
11
110
Juan Victor
NULL
104
José González
12
111
Juan Gris
21
110
Juan Victor
NULL
12. Lo mismo que la anterior pero queremos que aparezca también la ciudad de
las oficinas (tanto del empleado como de su jefe).
Resultado:
Numem
p
Nombre
Oficin Ciudad Jefe
a
Nombre
jefe
Oficin ciudad
a jefe
104
José
González
12
Alicant
e
10
6
Luis
Antonio
11
Valenc
ia
105
Vicente
Pantalla
13
Castell
on
10
4
José
González
12
Alicant
e
107
Jorge
Gutiérrez
22
A
Coruña
10
8
Ana
Bustaman
te
21
Badajo
z
108
Ana
Bustaman
te
21
Badajo
z
10
6
Luis
Antonio
11
Valenc
ia
109
María
Sunta
NUL
L
NULL
10
6
Luis
Antonio
11
Valenc
ia
110
Juan
Victor
NUL
L
NULL
10
4
José
González
12
Alicant
e
111
Juan Gris
21
Badajo
z
11
0
Juan
Victor
NUL
L
NULL
Puedes consultar aquí las soluciones propuestas.
Ejercicio 2: Comparar tablas
1. Obtener los empleados de GestionSimples que aparecen en Gestion con
otra oficina.
El resultado será que no devuelve filas.
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 4: Consultas multitabla
Ejercicio 1: La composición de tablas
1. Listar todos los pedidos, mostrando el precio y la descripción del producto.
2. SELECT pedidos.*, precio, descripcion
FROM pedidos INNER JOIN productos ON
idfab AND producto = idproducto;
fab =
3. Listar los pedidos superiores a 250 euros, incluyendo el nombre del
vendedor que tomó el pedido y el nombre del cliente que lo solicitó.
4. SELECT numpedido, CONVERT(CHAR(8),fechapedido,3)
AS fechapedido, clie, rep, fab, producto, cant,
importe,
clientes.nombre
AS
cliente,
empleados.nombre AS vendedor
5. FROM (pedidos INNER JOIN empleados ON
numemp)
6.
INNER
JOIN
clientes
ON
rep =
clie
=
numclie
WHERE importe >
250;
7. Listar los pedidos superiores a 250 euros, mostrando el nombre del cliente
que solicitó el pedido y el nombre del vendedor asignado a ese cliente.
8. SELECT pedidos.*, clientes.nombre AS cliente,
empleados.nombre AS [vendedor asignado]
9. FROM (pedidos INNER JOIN clientes ON
numclie)
10.
repclie = numemp
WHERE importe >
INNER
JOIN
clie =
empleados
ON
250;
11. Listar los pedidos superiores a 250 euros, mostrando además el nombre del
cliente que solicitó º el pedido y el nombre del vendedor asignado a ese
cliente y la ciudad de la oficina donde el vendedor trabaja.
12.
SELECT
numpedido,
clie,
clientes.nombre
AS
cliente,
empleados.nombre AS vendedor, ciudad
13.
FROM ((pedidos
clie = numclie)
INNER
14.
repclie = numemp)
INNER
JOIN
JOIN
15.
LEFT
JOIN
empleados.oficina=oficinas.oficina
WHERE importe >
rep,
repclie,
clientes
ON
empleados
ON
oficinas
ON
250;
16. Hallar los pedidos recibidos los días en que un nuevo empleado fue
contratado.
WHERE fechapedido = contrato;
22. Mostrar de cada empleado su código, nombre, ventas, oficina y ciudad en la
que está ubicada su oficina.
23.
SELECT
numemp,
nombre,empleados.ventas,empleados.oficina,ciudad
FROM
empleados
LEFT
JOIN
oficinas
empleados.oficina=oficinas.oficina;
ON
24. Listar los empleados con una cuota superior a la de su jefe, los campos a
obtener son el número, nombre y cuota del empleado y número, nombre y
cuota de su jefe.
25.
SELECT empleados.numemp, empleados.nombre,
empleados.cuota, empleados.jefe, jefes.nombre AS
[Nombre jefe], jefes.cuota AS [Cuota jefe]
FROM empleados LEFT JOIN empleados
empleados.jefe = jefes.numemp;
jefes
ON
26. Desde el entorno gráfico cambia el empleado 111, asígnale el jefe 110 y la
oficina 21. Después cambia la sentencia anterior para que salgan también
los empleados cuyo jefe no tenga cuota.
FROM empleados INNER JOIN empleados jefes
empleados.jefe = jefes.numemp
WHERE empleados.cuota > jefes.cuota
(empleados.cuota
jefes.cuota IS NULL)
IS
NOT
NULL
OR
AND
30. Listar los empleados que no están asignados a la misma oficina que su jefe,
queremos número, nombre y número de oficina tanto del empleado como de
su jefe.
31.
SELECT
e.numemp,
e.nombre,
e.oficina,
e.jefe, j.nombre as [nombre
jefe], j.oficina
AS [oficina jefe]
32.
FROM empleados e INNER JOIN empleados j ON
e.jefe = j.numemp
WHERE e.oficina <> j.oficina;
33. En el punto anterior no salen los que no tienen oficina, cambiar la sentencia
para que aparezcan.
34.
SELECT
e.numemp, e.nombre, e.oficina,
e.jefe, j.nombre as [nombre jefe], j.oficina AS
[oficina jefe]
35.
FROM empleados e INNER JOIN empleados j ON
e.jefe = j.numemp
WHERE e.oficina <> j.oficina
NULL OR j.oficina IS NULL;
OR
e.oficina
IS
36. Lo mismo que la anterior pero queremos que aparezca también la ciudad de
las oficinas (tanto del empleado como de su jefe).
37.
SELECT
e.numemp,
e.nombre,
e.oficina,
ofiemp.ciudad,
e.jefe,
j.nombre
as
[nombre
jefe],
j.oficina
AS
[oficina
jefe],
ofijefe.ciudad
38.
FROM (oficinas ofiemp RIGHT JOIN empleados
e ON ofiemp.oficina= e.oficina)
39.
INNER JOIN
JOIN
oficinas
ofijefe
ofijefe.oficina)
40.
j.numemp
(empleados j LEFT
ON
j.oficina
=
ON
WHERE e.oficina <> j.oficina
NULL OR j.oficina IS NULL;
e.jefe
OR
e.oficina
=
IS
Ejercicio 2: Comparar tablas
1. Obtener los empleados de GestionSimples que aparecen en GestionA con
otra oficina.
2. SELECT numemp, oficina
3. FROM gestionsimples.dbo.empleados
4. EXCEPT
5. SELECT numemp, oficina
FROM gestionA.dbo.empleados;
Ejercicios unidad 5: Consultas de resumen
Para realizar los ejercicios, deberás utilizar la base de datos
GestionSimples.
Ejercicio 1: Funciones de agregado
1. ¿Cuántas oficinas tenemos en Valencia?
Resultado:
Valencianas
4
2. Hallar cuántos pedidos hay de más de 250 euros.
Resultado:
Superiores a 250
4
3. ¿Cuántos títulos (cargos) de empleados se usan?
Resultado:
Cuántos títulos
3
4. ¿Entre qué cuotas se mueven los empleados?
Resultado:
Cuota mínima Cuota máxima
3000,00
35000,00
Puedes consultar aquí las soluciones propuestas.
Ejercicio 2: Agrupamiento de filas: GROUP BY
1. De cada vendedor (todos) queremos saber su nombre y el importe total
vendido. En caso de que el importe sea NULL, cambiarlo por 0,00 con la
función ISNULL().
Resultado:
numemp
nombre
Importe vendido
101
Antonio Viguer
266,28
102
Alvaro Jaumes
77,76
103
Juan Rovira
21,00
104
José González
0,00
105
Vicente Pantalla
772,746
106
Luis Antonio
46,08
107
Jorge Gutiérrez
344,32
108
Ana Bustamante
286,33
109
María Sunta
71,05
110
Juan Victor
478,82
111
Juan Gris
0,00
112
Julián Martorell
0,00
113
Juan Gris
0,00
114
Pablo Moreno
0,00
Puedes consultar aquí las soluciones propuestas.
2. De cada empleado, obtener el importe vendido a cada cliente.
Resultado:
rep Cliente Importe vendido
106
2101
14,58
101
2102
39,78
105
2103
735,296
102
2106
40,26
110
2107
28,82
101
2108
1,50
109
2108
71,05
107
2109
313,50
103
2111
21,00
105
2111
37,45
108
2112
29,25
110
2112
450,00
101
2113
225,00
108
2114
221,00
106
2117
31,50
108
2118
36,08
102
2120
37,50
107
2124
30,82
Puedes consultar aquí las soluciones propuestas.
3. Repetir la consulta anterior pero ahora deben aparecer también los
empleados que no han vendido nada.
Resultado:
rep Cliente Importe vendido
101
2102
39,78
101
2108
1,50
101
2113
225,00
102
2106
40,26
102
2120
37,50
103
2111
21,00
104
NULL
NULL
105
2103
735,296
105
2111
37,45
106
2101
14,58
106
2117
31,50
107
2109
313,50
107
2124
30,82
108
2112
29,25
108
2114
221,00
108
2118
36,08
109
2108
71,05
110
2107
28,82
110
2112
450,00
111
NULL
NULL
112
NULL
NULL
113
NULL
NULL
114
NULL
NULL
Puedes consultar aquí las soluciones propuestas.
4. Repetir la consulta pero ahora debe aparecer también el total de cuánto ha
vendido cada empleado. (Recuerda una opción de la cláusula GROUP BY)
Resultado:
rep
clie
Importe vendido
NULL
NULL
2364,386
101
NULL
266,28
101
2102
39,78
101
2108
1,50
101
2113
225,00
102
NULL
77,76
102
2106
40,26
102
2120
37,50
103
NULL
21,00
103
2111
21,00
104
NULL
NULL
104
NULL
NULL
105
NULL
772,746
105
2103
735,296
105
2111
37,45
106
NULL
46,08
106
2101
14,58
106
2117
31,50
107
NULL
344,32
107
2109
313,50
107
2124
30,82
108
NULL
286,33
108
2112
29,25
108
2114
221,00
108
2118
36,08
109
NULL
71,05
109
2108
71,05
110
NULL
478,82
110
2107
28,82
110
2112
450,00
111
NULL
NULL
111
NULL
NULL
112
NULL
NULL
112
NULL
NULL
113
NULL
NULL
113
NULL
NULL
114
NULL
NULL
114
NULL
NULL
Puedes consultar aquí las soluciones propuestas.
5. En los resultados anteriores no se distinguen bien las líneas que
corresponden a totales. Modificar la consulta para obtener este resultado:
Importe vendido
Agrupa Agrupa
clie numemp
NULL
2364,386
1
1
101
NULL
266,28
1
0
101
2102
39,78
0
0
101
2108
1,50
0
0
rep
clie
NULL
101
2113
225,00
0
0
102
NULL
77,76
1
0
102
2106
40,26
0
0
102
2120
37,50
0
0
103
NULL
21,00
1
0
103
2111
21,00
0
0
104
NULL
NULL
0
0
104
NULL
NULL
1
0
...
....
... (sigue)
...
...
6.
Puedes consultar aquí las soluciones propuestas.
7. Ahora modifica la consulta para que las filas de totales aparezcan más
claras. (Recuerda la función CASE)
Resultado:
rep
clie
Importe vendido
Agrupa clie
NULL
NULL
2364,386
Total empleado
101
NULL
266,28
Total empleado
101
2102
39,78
101
2108
1,50
101
2113
225,00
102
NULL
77,76
102
2106
40,26
102
2120
37,50
103
NULL
21,00
103
2111
21,00
Total empleado
Total empleado
Agrupa
numemp
Total final
104
NULL
NULL
104
NULL
NULL
Total empleado
...
....
... (sigue)
...
...
Puedes consultar aquí las soluciones propuestas.
8. Ahora coloca las columnas Agrupa delante de las demás columnas:
Resultado:
Agrupa
numemp
Total final
Agrupa clie
rep
clie
Total empleado
NULL
NULL
2364,386
Total empleado
101
NULL
266,28
101
2102
39,78
101
2108
1,50
101
2113
225,00
102
NULL
77,76
102
2106
40,26
102
2120
37,50
103
NULL
21,00
103
2111
21,00
104
NULL
NULL
Total empleado
104
NULL
NULL
...
...
....
...
Total empleado
Total empleado
... (sigue)
Puedes consultar aquí las soluciones propuestas.
Importe vendido
9. Ahora queremos que "Total empleado" aparezca en la columna clie. Piensa
primero en cuántas columnas quieres y luego en cada columna que tiene
que salir.
Resultado:
Agrupa
numemp
numemp
Total final
... (sigue)
clie
Importe vendido
NULL
Total empleado
2364,386
101
Total empleado
266,28
101
2102
39,78
101
2108
1,50
101
2113
225,00
102
Total empleado
77,76
102
2106
40,26
102
2120
37,50
103
Total empleado
21,00
103
2111
21,00
104
NULL
NULL
104
Total empleado
NULL
...
....
...
Puedes consultar aquí las soluciones propuestas.
10. El empleado 104 (y otros) no ha vendido a nadie y por eso sale en la
columna clie la palabra NULL, queremos que en estos casos no aparezca
nada (se deje en blanco), y el importe si es NULL que salga un cero.
Resultado:
Agrupa
numemp
numemp
clie
Importe vendido
Total final
NULL
Total empleado
2364,386
101
2102
39,78
101
2108
1,50
101
2113
225,00
101
Total empleado
266,28
102
2106
40,26
102
2120
37,50
102
Total empleado
77,76
103
2111
21,00
103
Total empleado
21,00
104
... (sigue)
0,00
104
Total empleado
0,00
...
....
...
Nota: Recuerda la función ISNULL() (para la columna importe
vendido) y la función CASE con diferentes condiciones (para la
columna
clie).
Puedes consultar aquí las soluciones propuestas.
11. Lo rematamos para que el resultado quede así:
numemp
Total final
clie
Importe vendido
...
...
2364,386
101
2102
39,78
101
2108
1,50
101
2113
225,00
101
Total empleado
266,28
102
2106
40,26
102
2120
37,50
102
Total empleado
77,76
103
2111
21,00
103
Total empleado
21,00
104
... (sigue)
0,00
104
Total empleado
0,00
...
....
...
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 5: Consultas de resumen
Ejercicio 1: Funciones de agregado
1. ¿Cuántas oficinas tenemos en Valencia?
SELECT COUNT(*) AS Valencianas
FROM oficinas
WHERE ciudad = 'Valencia';
2. Hallar cuántos pedidos hay de más de 250 euros.
SELECT COUNT(*) AS [Superiores a 250]
FROM pedidos
WHERE importe > 250;
3. ¿Cuántos títulos (cargos) de empleados se usan?
SELECT COUNT(DISTINCT titulo) AS [Cuántos títulos]
FROM empleados;
4. ¿Entre qué cuotas se mueven los empleados?
SELECT MIN(cuota)
[Cuota máxima]
AS
[Cuota
mínima],
MAX(cuota)
AS
FROM empleados;
Ejercicio 2: Agrupamiento de filas: GROUP BY
1. De cada vendedor (todos) queremos saber su nombre y el importe
total vendido. En caso de que el importe sea NULL, cámbialo por 0,00 con
la función ISNULL().
SELECT
numemp,
nombre,
[Importe vendido]
ISNULL(SUM(importe),0)
AS
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, nombre;
2. De cada empleado, obtener el importe vendido a cada cliente.
SELECT rep, clie AS Cliente, SUM(importe) AS [Importe
vendido]
FROM pedidos
GROUP BY rep, clie;
3. Repetir la consulta anterior pero ahora deben aparecer también los
empleados que no han vendido nada.
SELECT numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie
ORDER BY numemp,clie;
4. Repetir la consulta pero ahora debe aparecer también el total de
cuánto ha vendido cada empleado.
SELECT numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
5. En los resultados anteriores no se distinguen bien las líneas que
corresponden a totales. Modificar la consulta para indicar con un 1 si es
una fila de totales y con un 0 si no lo es.
SELECT numemp, clie, SUM(importe) AS [Importe vendido],
GROUPING(clie) AS [Agrupa clie], GROUPING(numemp) AS
[Agrupa numemp]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
6. Ahora modifica la consulta para que las filas de totales aparezcan
más claras, substituyendo el 1 de Agrupa clie por "Total empleado", el 1
de Agrupa numemp por Total final y el valor 0 por espacio en blanco.
SELECT numemp, clie, SUM(importe) AS [Importe vendido],
CASE GROUPING(clie) WHEN 0 THEN ' ' WHEN 1 THEN
'Total empleado' END AS [Agrupa clie],
CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total
Final' END AS [Agrupa numemp]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
7. Ahora coloca las columnas Agrupa delante de las demás
columnas.
SELECT
CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE
'Total Final' END AS [Agrupa numemp],
CASE GROUPING(clie) WHEN 0 THEN ' ' WHEN 1 THEN
'Total empleado' END AS [Agrupa clie],
numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
8. Ahora queremos que "Total empleado" aparezca en la columna
clie.
SELECT
CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE
'Total Final' END AS [Agrupa numemp],
numemp,
CASE
GROUPING(clie)
WHEN
0
THEN
CONVERT(CHAR(4),clie) WHEN 1 THEN 'Total empleado' END
AS [Clie],
SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
9. El empleado 104 (y otros) no ha vendido a nadie y por eso sale en
la columna clie la palabra NULL, queremos que en estos casos no
aparezca nada (se deje en blanco), y el importe si es NULL que salga un
cero.
SELECT
CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE
'Total Final' END AS [Agrupa numemp],
numemp,
CASE WHEN GROUPING(clie) = 1
empleado'
WHEN
clie
IS
NULL
THEN
CONVERT(CHAR(4),clie) END AS [Clie],
THEN 'Total
'
'
ELSE
ISNULL(SUM(importe),0) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
10. Lo rematamos para que la fila del Total final no muestre los
valores "NULL" ni "Total empleado". En cambio, los cambiaremos por tres
puntos. Tampoco mostraremos el encabezado "Agrupa numemp".
SELECT CASE GROUPING(numemp)
'Total Final' END AS [ ],
WHEN
0
THEN
'
'
ELSE
ISNULL(CONVERT(CHAR(3),numemp),'...
[numemp],
')
CASE
WHEN
GROUPING(numemp) = 0
1
THEN
GROUPING(clie)
'Total
=
empleado'
AS
AND
WHEN
GROUPING(clie) = 1
AND GROUPING(numemp) = 1 THEN '...'
WHEN
clie
IS
NULL
THEN
CONVERT(CHAR(4),clie) END AS [Clie],
'
'
ELSE
ISNULL(SUM(importe),0) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
Ejercicios unidad 6: Las subconsultas
Para realizar los ejercicios, deberás utilizar la base de datos
GestionSimples.
1. Listar los clientes (numclie, nombre) asignados a Juan que no han
remitido un pedido superior a 300 euros.
numclie
nombre
2107
Julian López
2107
Julian López
2121
Vicente Ríos
2125
Pepito Grillo
2. Listar los empleados (numemp, nombre) mayores de 40 años que
dirigen a un vendedor con superávit (ha vendido más que su cuota).
numemp
nombre
106
Luis Antonio
108
Ana Bustamante
110
Juan Victor
3. Listar los empleados (código de empleado) cuyo importe de pedido
medio para productos fabricados por ACI es superior al importe medio
global (de todos los pedidos de todos los empleados).
rep
105
Puedes consultar aquí las soluciones propuestas.
4. Listar los empleados (numemp, nombre, ventas) cuyas ventas son
iguales o superiores al objetivo de las oficinas de una determinada ciudad
(de todas las oficinas de esa ciudad). Las oficinas con objetivo nulo no se
deben de tener en cuenta (como si no existiesen). Y si no hay oficinas en
la ciudad no queremos que salga ningún empleado. Intentar primero
resolver la consulta utilizando >=ALL.
Probar primero con A Coruña:
numemp
nombre
ventas
102
Alvaro Jaumes
47400,00
111
Juan Gris
60000,00
112
Julián Martorell
91000,00
Ahora con Pamplona. Pamplona tiene una oficina con objetivo nulo,
en este caso no queremos que esa oficina cuente.
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
María Sunta
39200,00
111
Juan Gris
60000,00
112
Julián Martorell
91000,00
114
Pablo Moreno
37000,00
Para Barcelona. En este caso no tenemos oficinas en Barcelona por
lo que no tiene que salir ningún empleado.
Ahora para Madrid. Como en Madrid sólo hay una oficina y no tiene
objetivo no tiene que salir ningún empleado.
Intentar resolver la consulta sin utilizar ALL.
5. Listar las oficinas en donde todos los empleados tienen ventas que
superan al 50% del objetivo de la oficina.
oficina
ciudad
11
Valencia
13
Castellon
22
A Coruña
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 6: Las subconsultas
1. Listar los clientes (numclie, nombre) asignados a Juan que no han
remitido un pedido superior a 300 euros.
SELECT numclie, nombre
FROM clientes
WHERE repclie IN (SELECT numemp
FROM empleados
WHERE nombre LIKE 'Juan%')
AND NOT EXISTS (SELECT * FROM pedidos
WHERE
clie AND importe > 300);
numclie
=
2. Listar los empleados (numemp, nombre) mayores de 40 años que
dirigen a un vendedor con superávit (ha vendido más que su cuota).
SELECT numemp, nombre
FROM empleados
WHERE edad > 40
and numemp IN (SELECT jefe FROM empleados
WHERE ventas > cuota );
3. Listar los empleados (código de empleado) cuyo importe de pedido
medio para productos fabricados por ACI es superior al importe medio
global (de todos los pedidos de todos los empleados).
SELECT rep
FROM pedidos
WHERE
fab = 'ACI'
GROUP BY rep
HAVING
AVG(importe)
pedidos);
>
(SELECT
AVG(importe)
FROM
4. Listar los empleados (numemp, nombre, ventas) cuyas ventas son
iguales o superiores al objetivo de las oficinas de una determinada ciudad
(de todas las oficinas de esa ciudad). Las oficinas con objetivo nulo no se
deben de tener en cuenta (como si no existiesen). Y si no hay oficinas en
la ciudad no queremos que salga ningún empleado. Intentar primero
resolver la consulta utilizando >=ALL.
Probar primero con A Coruña:
SELECT numemp, nombre, ventas
FROM empleados
WHERE ventas >= ALL (SELECT objetivo
FROM oficinas
WHERE ciudad = 'A Coruña');
Ahora con Pamplona. Pamplona tiene una oficina con objetivo nulo,
en este caso no queremos que esa oficina cuente.
SELECT numemp, nombre, ventas
FROM empleados
WHERE ventas >= ALL (SELECT objetivo
FROM oficinas
WHERE ciudad = 'Pamplona' and objetivo
is not null);
Para Barcelona. En este caso no tenemos oficinas en Barcelona por
lo que no tiene que salir ningún empleado. Si no queremos que salgan
tendremos que añadir una condición:
SELECT numemp, nombre, ventas
FROM empleados
WHERE ventas >= ALL (SELECT objetivo
FROM oficinas
WHERE
objetivo is not null)
ciudad
=
'Barcelona'
and
AND EXISTS (SELECT *
FROM oficinas
WHERE ciudad = 'Barcelona');
Ahora para Madrid. Como en Madrid sólo hay una oficina y no tiene
objetivo no tiene que salir ningún empleado.
SELECT numemp, nombre, ventas
FROM empleados
WHERE ventas >= ALL (SELECT objetivo
FROM oficinas
WHERE ciudad = 'Madrid' and objetivo
is not null)
AND EXISTS (SELECT *
FROM oficinas
WHERE ciudad = 'Madrid' and objetivo
is not null);
Esta sería la consulta definitiva que nos serviría para cualquier
situación. Pero como se ve el modificador ALL puede darnos problemas.
Para solucionarlo, realizamos la siguiente consulta.
Intentar resolver la consulta sin utilizar ALL.
SELECT numemp, nombre, ventas
FROM empleados
WHERE ventas >=
(SELECT MAX(objetivo)
FROM oficinas
WHERE ciudad = 'Madrid');
5. Listar las oficinas en donde todos los empleados tienen ventas que
superan al 50% del objetivo de la oficina.
SELECT oficina, ciudad
FROM oficinas
WHERE (objetivo * .5) < = (SELECT MIN(ventas)
FROM
empleados
empleados.oficina = oficinas.oficina);
WHERE
Ejercicios unidad 7: Actualización de datos (I)
Para realizar los ejercicios, deberás utilizar la base de datos Gestion8.
1. Añadir a la oficina 40 otro empleado, Luis Valverde, con número de
empleado 436, con los mismos datos que el anterior pero su jefe será el
director de la oficina 40 (no sabemos qué número tiene).
2. Pasar los pedidos de octubre 1989 a diciembre 2008. (3 filas
afectadas)
3. Queremos actualizar el importe de los pedidos del mes actual con el
precio
almacenado
en
la
tabla
productos.
Ayuda: En un primer paso obtener los pedidos del mes actual obteniendo
también el precio unitario dentro del pedido y el precio del producto de la
tabla de productos.
codigo numpedido
fechapedido
cant importe
precio
pedido
precio
1
110036
2008-12-12
00:00:00.000
9
22,50
2,50
NULL
2
110037
2008-12-12
00:00:00.000
7
31,50
4,50
45,00
6
112979
2008-12-12
00:00:00.000
6
150,00
25,00
NULL
9
112989
2008-12-10
00:00:00.000
6
14,58
2,43
2,43
16
113013
2008-12-28
00:00:00.000
1
6,52
6,52
5,16
Actualizar después la tabla de pedidos cambiando los importes para
que el precio unitario corresponda con el precio del producto. Los pedidos
de los productos que no tienen precio se quedarán como estaban. (3 filas
afectadas)
codigo numpedido
fechapedido
cant importe
precio
pedido
precio
1
110036
2008-12-12
00:00:00.000
9
22,50
2,50
NULL
2
110037
2008-12-12
00:00:00.000
7
315,00
4,50
45,00
6
112979
2008-12-12
00:00:00.000
6
150,00
25,00
NULL
9
112989
2008-12-10
00:00:00.000
6
14,58
2,43
2,43
16
113013
2008-12-28
00:00:00.000
1
5,16
6,52
5,16
Puedes consultar aquí las soluciones propuestas.
4. Se ven algunos productos que no tienen precio, ahora vamos a
actualizar el precio de estos productos con el precio medio utilizado en los
pedidos
donde
aparecen.
Ayuda: Primero sacamos los productos que queremos actualizar con los
pedidos correspondientes:
Vemos que el producto ACI 41001 no se podrá actualizar porque no
tiene pedidos. Pero los demás se actualizarán con el precio medio de sus
pedidos, deberán quedar así (7 filas afectadas):
idfab idproducto precio
aci
41001
NULL
aci
41002
4,55
aci
41003
1,07
aci
41004
0,82
aci
4100x
0,25 *
aci
4100y
25,00
aci
4100z
13,75
* aci 4100x tiene 2 pedidos pero uno sin precio por lo que no cuenta
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 7: Actualización de datos (I)
1. Añadir a la oficina 40 otro empleado, Luis Valverde, con número de
empleado 436, con los mismos datos que el anterior pero su jefe será el
director de la oficina 40 (no sabemos qué número tiene).
INSERT
INTO
empleados
(numemp,
nombre,
contrato, ventas, cuota, oficina, jefe)
titulo,
SELECT 436, 'Luis Valverde','Vendedor', GETDATE(), 0,
1200.45, 40, dir
FROM oficinas WHERE oficina = 40;
2. Pasar los pedidos de octubre 1989 a diciembre 2008. (3 filas
afectadas)
UPDATE
pedidos
fechapedido=DATEADD(month,230,fechapedido)
SET
WHERE year(fechapedido)=1989 and month(fechapedido)=10;
3. Queremos actualizar el importe de los pedidos del mes actual con el
precio almacenado en la tabla productos.
SELECT
codigo,
numpedido,fechapedido,cant,
importe,importe/cant AS [precio pedido],precio
FROM pedidos inner join
producto = idproducto
productos
ON
fab=idfab
and
WHERE
YEAR(fechapedido)=YEAR(GETDATE())
MONTH(fechapedido)=MONTH(GETDATE())
and
Actualizar después la tabla de pedidos cambiando los importes para
que el precio unitario corresponda con el precio del producto. Los pedidos
de los productos que no tienen precio se quedarán como estaban. (3 filas
afectadas)
UPDATE pedidos SET importe=cant*precio
FROM pedidos inner join
producto = idproducto
productos
ON
fab=idfab
and
WHERE year(fechapedido)=2008 and month(fechapedido)=12
AND precio IS NOT NULL;
4. Se ven algunos productos que no tienen precio, ahora vamos a
actualizar el precio de estos productos con el precio medio utilizado en los
pedidos donde aparecen. La primera SELECT saca los productos que
queremos actualizar con los pedidos correspondientes.
SELECT
idfab,
idproducto,
precio,
numpedido,fechapedido,importe, importe/cant
FROM productos left
idproducto=producto
join
pedidos
on
codigo,
idfab=fab
AND
WHERE precio IS NULL;
UPDATE
productos
SET
precio
=
(SELECT
ROUND(AVG(importe/cant),2) FROM pedidos WHERE fab=idfab
AND producto=idproducto)
WHERE precio IS NULL
Ayuda ejercicios unidad 7: Actualización de datos (II)
5. Eliminar los pedidos del representante Luis Antonio. (2 filas
afectadas)
DELETE FROM pedidos
WHERE rep IN (SELECT numemp FROM empleados
WHERE nombre = 'Luis Antonio');
6. Eliminar las oficinas que no tengan empleados. (11 filas afectadas)
DELETE oficinas
WHERE NOT EXISTS (SELECT *
FROM
empleados
empleados.oficina = oficinas.oficina);
WHERE
7. Intenta eliminar el empleado 102. Te saldrá un error : "Instrucción
DELETE en conflicto con la restricción..."
DELETE empleados WHERE numemp=102;
Reflexiona sobre el error y elabora una consulta que liste los
empleados que pueden dar problemas (aquí no se trata de utilizar
operaciones aprendidas en este tema sino de practicar la integridad
referencial y de paso recordar instrucciones vistas en temas anteriores).
SELECT * from empleados
WHERE numemp IN (select jefe from empleados)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT dir FROM oficinas)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT rep FROM pedidos)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT repclie FROM clientes)
ORDER BY numemp
Elabora ahora una consulta que liste los que se pueden borrar sin
problemas.
SELECT numemp FROM empleados
EXCEPT
SELECT numemp from empleados
WHERE numemp IN (select jefe from empleados)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT dir FROM oficinas)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT rep FROM pedidos)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT repclie FROM clientes)
ORDER BY numemp
Borra el primero de la lista, éste sí lo puedes borrar.
DELETE empleados WHERE numemp=112;
8. Eliminar los pedidos de productos de ACI cuyo precio de venta en el
pedido no corresponda con el precio unitario del producto de la tabla de
productos. (4 filas afectadas)
DELETE FROM pedidos
WHERE fab = 'ACI' AND Importe/cant <> (SELECT precio
FROM productos WHERE fab = idfab AND idproducto =
producto);
9. Ahora vamos a recuperar las tablas tal cual estaban al principio, para
ello utilizaremos las copias realizadas al principio de Nuevaoficinas, etc.
Lo más cómodo será vaciar las tablas y rellenarlas de nuevo con los datos
de las tablas Nueva...
Empieza por eliminar los datos de las tablas. Utilizamos TRUNCATE
en la tabla pedidos porque no está referenciada y para que el contador
empiece desde 1 otra vez
TRUNCATE TABLE pedidos
DELETE productos
DELETE clientes
UPDATE oficinas SET dir = NULL; -- Para poder borrar
los empleados
UPDATE empleados SET oficina=NULL, jefe=NULL; -- Para
poder
borrar
las
oficinas
y
los
empleados
respectivamente.
DELETE oficinas;
DELETE empleados;
Ayuda ejercicios unidad 7: Actualización de datos (III)
Inserta los datos de las tablas Nueva.. a las tablas normales.
INSERT
INTO
oficinas
region,objetivo,ventas)
SELECT
region,objetivo,ventas
(oficina,
ciudad,
oficina,
ciudad,
FROM Nuevaoficinas;
No podemos rellenar todavía la columna Dir ya que no tenemos los
empleados dado de alta.
INSERT
INTO
empleados
(numemp,
oficina,titulo,contrato,cuota,ventas)
FROM NuevaEmpleados;
Lo mismo pasa con la columna jefe.
UPDATE empleados SET jefe=nueva.jefe
FROM empleados INNER JOIN NuevaEmpleados
empleados.numemp=nueva.numemp
nueva
Estas dos últimas sentencias se podían haber resumido en una:
INSERT INTO empleados
SELECT *
ON
FROM NuevaEmpleados;
Las hemos dejado en dos porque con otros SQLs no se podría hacer
en un sólo paso.
UPDATE
oficinas
SET
Nuevaoficinas nueva
dir
=
(SELECT
dir
FROM
WHERE
oficinas.oficina=nueva.oficina)
INSERT
INTO
(numclie,nombre,repclie,limitecredito)
clientes
SELECT numclie,nombre,repclie,limitecredito
FROM Nuevaclientes;
INSERT INTO productos
SELECT *
FROM Nuevaproductos;
INSERT
INTO
pedidos
(numpedido,fechapedido,clie,rep,fab,producto,cant,impor
te)
SELECT
numpedido,fechapedido,clie,rep,fab,producto,cant,import
e
FROM Nuevapedidos;
Ejercicios unidad 8: El DDL, Lenguaje de Definición de Datos
1. Crea una nueva base de datos Gestion2, los archivos físicos se
llamarán también Gestion2 y se creará en la misma carpeta que la base
de datos Gestion.
2. En Gestion2, crea las mismas tablas que tenemos en Gestion con
las mismas relaciones entre ellas. Este ejercicio se resuelve con varias
sentencias.
3. La tabla Productos de Gestion2 consideramos que sufre pocas
operaciones de nuevos registros o eliminación de registros y el único
campo que sufre actualizaciones frecuentes es el campo existencias; por
otro lado es frecuente consultar los productos por el campo descripcion
(aunque varios productos puedan tener la misma descripción). ¿Se podría
mejorar la base de datos? Si es que sí indica de qué forma y escribe la
instrucción correspondiente; en cualquier caso justifica la respuesta.
4. ¿Qué se puede hacer para que no puedan existir en la tabla de
clientes dos clientes con el mismo nombre?
5. En nuestro sistema vamos a efectuar muchas consultas recuperando
a la vez los pedidos y los productos asociados a cada uno de ellos, por
eso sería bueno…. Completa la frase y escribe la sentencia SQL
correspondiente.
6. Elimina la tabla clientes dejando en pedidos el campo cliente a NULL.
Este ejercicio se resuelve con varias sentencias y se puede resolver de
varias maneras. Resuélvelo de distintas formas.
7. Ahora queremos permitir que dos clientes tengan el mismo nombre.
8. Elimina la base de datos Gestion2, así podrás volver a hacer los
ejercicios.
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 8: El DDL, Lenguaje de Definición de
Datos
1. Crea una nueva base de datos Gestion2, los archivos físicos se
llamarán también Gestion2 y se creará en la misma carpeta que la base
de datos Gestion.
CREATE DATABASE Gestion2;
por defecto de SQL Server.
-- La crea en la carpeta
CREATE
DATABASE
Gestion2
ON
FILENAME='F:\SQL\Gestion2.mdf')
(NAME='Gestion2'
LOG
ON
(NAME='Gestion2_log'
FILENAME='F:\SQL\Gestion2.ldf')GO
,
,
2. En Gestion2, crea las mismas tablas que tenemos en Gestion con
las mismas relaciones entre ellas. Este ejercicio se resuelve con varias
sentencias.
USE Gestion2
CREATE TABLE
dbo.empleados(
numemp
INT NOT NULL CONSTRAINT pk_empleados
PRIMARY KEY CLUSTERED,
nombre
edad
CHAR(20) NULL,
INT NULL,
oficina
titulo
contrato
INT NULL,
CHAR(20) NULL,
datetime NULL,
jefe
INT NULL CONSTRAINT
REFERENCES dbo.empleados,
cuota
ventas
3. La tabla Productos de Gestion2 consideramos que sufre pocas
operaciones de nuevos registros o eliminación de registros y el único
campo que sufre actualizaciones frecuentes es el campo existencias; por
otro lado es frecuente consultar los productos por el campo descripcion
(aunque varios productos puedan tener la misma descripción). ¿Se podría
mejorar la base de datos? Si es que sí indica de qué forma y escribe la
instrucción correspondiente; en cualquier caso justifica la respuesta.
CREATE
INDEX
(descripcion);
IX_descripcion
ON
Productos
4. ¿Qué se puede hacer para que no puedan existir en la tabla de
clientes dos clientes con el mismo nombre?
CREATE UNIQUE INDEX
-- o
IX_nombre ON Clientes (nombre)
bien
ALTER TABLE Clientes ADD
(nombre);
CONSTRAINT IX_nombre UNIQUE
5. En nuestro sistema vamos a efectuar muchas consultas recuperando
a la vez los pedidos y los productos asociados a cada uno de ellos, por
eso sería bueno…. Completa la frase y escribe la sentencia SQL
correspondiente.
CREATE VIEW pedidos_productos AS (SELECT * FROM pedidos
INNER
JOIN
productos
ON
fab=idfab
AND
producto=idproducto);
6. Elimina la tabla clientes dejando en pedidos el campo cliente a NULL.
Este ejercicio se resuelve con varias sentencias y se puede resolver de
varias maneras. Resuélvelo de distintas formas.
ALTER TABLE pedidos ALTER COLUMN
Esto de todas formas
clie INT NULL;
--
-- Opcion 1
ALTER TABLE
pedidos DROP CONSTRAINT
FK_pedidos_clie;
ALTER TABLE pedidos ADD
CONSTRAINT FK_pedidos_clie
FOREIGN KEY (clie) REFERENCES Clientes ON
DELETE SET
NULL;
DELETE Clientes;
SELECT * FROM pedidos -- Para
comprobar el resultado;
-- Opcion 2
UPDATE pedidos SET
clie = NULL;
DELETE Clientes
SELECT * FROM pedidos;
7. Ahora queremos permitir que dos clientes tengan el mismo nombre.
DROP INDEX IX_nombre ON
--o bien (según se haya
ALTER TABLE Clientes DROP
Clientes;
resuelto el apartado 5
CONSTRAINT IX_nombre;
8. Elimina la base de datos Gestion2, así podrás volver a hacer los
ejercicios.
USE Gestion
DROP DATABASE Gestion2;
GO
Ejercicios unidad 9: Programación en TRANSACT SQL
Nota: Para realizar los ejercicios, utiliza Gestion10 que has creado en
los ejercicios paso a paso de este tema.
1. Añadir a la tabla de productos un campo StockMinimo, y rellenarlo de
tal forma que el stock mínimo valorado de cada artículo sea de 100€. El
stock mínimo valorado es el resultado de multiplicar el stock mínimo por el
precio del producto. No hace falta incluir estas sentencias en un
procedimiento ya que sólo nos sirven para preparar la tabla productos
pero redactarlas en Transact-SQL para repasar temas anteriores.
Seguidamente, escribir un procedimiento que se pueda ejecutar en
cualquier momento y que actualice una lista de productos bajo stock. Esta
lista se guarda en una tabla ProductosAPedir y contiene el código
completo del producto, su descripción, existencias y cantidad a pedir (para
que el producto supere en 5 unidades su stock mínimo). Si un producto
bajo mínimo (cuyas existencias no llegan al stock mínimo) no está en esa
tabla, insertarlo, si está actualizar el campo CantidadAPedir, y si ya no
está bajo mínimo y está en la tabla, eliminar el registro de
ProductosAPedir.
2. Obtener un listado de las oficinas de una determinada región con
ventas superiores a un determinado importe.
3. Crea un nuevo procedimiento parecido al anterior pero que nos
devuelva también el número de oficinas recuperadas. Utilizar un
parámetro de salida.
4. Crea un nuevo procedimiento parecido al anterior pero que nos
devuelva también el número de oficinas recuperadas. Sin utilizar
parámetros de salida.
5. Crea un procedimiento que muestre los n productos más caros, n es
un valor que se indicará en la llamada.
6. Crea otro procedimiento que muestre los n productos más caros con
empates y nos devuelva cuántos hay.
7. No dejar eliminar productos que tengan existencias.
8. Hacer que no se pueda insertar un pedido si no hay suficiente stock.
9. Crea un procedimiento que impida eliminar varias oficinas en una
sóla operación DELETE.
Puedes consultar aquí las soluciones propuestas.
Ayuda ejercicios unidad 9: Programación en TRANSACT SQL
(I)
Consejo: Es recomedable copiar el código en la consulta del SSMS y
tratar de entenderlo desde ahí, porque son consultas extensas y se ven
más claras con las palabras coloreadas.
1. Añadir a la tabla de productos un campo StockMinimo, y rellenarlo de
tal forma que el stock mínimo valorado de cada artículo sea de 100€. El
stock mínimo valorado es el resultado de multiplicar el stock mínimo por el
precio del producto. No hace falta incluir estas sentencias en un
procedimiento ya que sólo nos sirven para preparar la tabla productos
pero redactarlas en Transact-SQL para repasar temas anteriores.
PRINT 'Empieza el ejercicio 1'
USE Gestion10;
Alter TABLE Productos ADD
0;
StockMinimo INTEGER DEFAULT
GO
UPDATE Productos SET StockMinimo= 100/(CASE WHEN Precio
IS NULL OR Precio=0 THEN 100 ELSE Precio END);
-- Utilizamos CASE para
que si el producto no tiene
precio o un precio igual a cero que asuma StockMinimo
1.
Seguidamente, escribir un procedimiento que se pueda ejecutar en
cualquier momento y que actualice una lista de productos bajo stock. Esta
lista se guarda en una tabla ProductosAPedir y contiene el código
completo del producto, su descripción, existencias y cantidad a pedir (para
que el producto supere en 5 unidades su stock mínimo). Si un producto
bajo mínimo (cuyas existencias no llegan al stock mínimo) no está en esa
tabla, insertarlo, si está actualizar el campo CantidadAPedir, y si ya no
está bajo mínimo y está en la tabla, eliminar el registro de
ProductosAPedir.
PRINT 'Empieza el ejercicio 1 bis'
USE Gestion10
IF OBJECT_ID('ActualizaProductosAPedir','P') IS NOT
NULL DROP PROC ActualizaProductosAPedir
GO
CREATE PROC ActualizaProductosAPedir
AS
BEGIN
IF OBJECT_ID('ProductosAPedir','U') IS NULL
CREATE
DELETE FROM ProductosAPedir WHERE
EXISTS
(SELECT * FROM Productos WHERE
idfab=Afab AND
idproducto=Aproducto AND existencias >= StockMinimo)
--Borramos
los
ProductosAPedir
de
los
productos que rebasan el stock mínimo, si rebasa el
stock el producto ya no tiene que estar en la tabla
UPDATE
ProductosAPedir
Apedir=StockMinimo+5-existencias
SET
FROM ProductosAPedir INNER JOIN Productos ON
idfab=Afab AND idproducto=Aproducto
WHERE existencias <
Stockminimo
-Actualizamos
los
ProductosAPedir
productos que no llegan al stock mínimo
INSERT INTO
de
ProductosAPedir
SELECT
Idfab,Idproducto,Descripcion,existencias,StockMinimo+5existencias
FROM Productos
WHERE
existencias < Stockminimo
AND
FROM
ProductosAPedir
idproducto=Aproducto);
NOT
WHERE
EXISTS (SELECT *
idfab=Afab
AND
-- Insertamos nuevos ProductosAPedir
de
productos que no llegan al stock mínimo y que no están
ya en ProductosAPedir (para no repetirlos).
END;
GO
USE Gestion10
SELECT *
Stockminimo
FROM
Productos
WHERE
existencias
<
EXEC ActualizaProductosAPedir
SELECT * FROM ProductosAPedir
2. Obtener un listado de las oficinas de una determinada región con
ventas superiores a un determinado importe.
PRINT 'Empieza el ejercicio 2'
USE Gestion10
IF OBJECT_ID('Listado_Oficinas1','P') IS NOT NULL DROP
PROCEDURE Listado_Oficinas1
GO
CREATE
PROCEDURE
CHAR(20),@ventas MONEY
Listado_Oficinas1
@region
AS
SELECT * FROM oficinas WHERE region= @region
ventas > @ventas
3. Crear un nuevo procedimiento parecido al anterior pero que nos
devuelva también el número de oficinas recuperadas. Utilizar un
parámetro de salida.
PRINT 'Empieza el ejercicio 3'
USE Gestion10
IF OBJECT_ID('Listado_Oficinas2','P')
DROP PROCEDURE Listado_Oficinas2
IS
NOT
NULL
GO
CREATE
PROCEDURE
Listado_Oficinas2
CHAR(20),@ventas MONEY, @cuantas INT OUTPUT
@region
AS
SELECT * FROM oficinas WHERE region= @region
AND ventas > @ventas
WHERE
SET
@cuantas=(SELECT
COUNT(*) FROM oficinas
region= @region AND ventas > @ventas)
GO
DECLARE @resultado INT
EXEC Listado_Oficinas2 Este, 1000 ,@resultado OUTPUT
SELECT @resultado
EXEC
OUTPUT
Ayuda ejercicios unidad 9: Programación en TRANSACT SQL
(II)
4. Crear un nuevo procedimiento parecido al anterior pero que nos
devuelva también el número de oficinas recuperadas. Sin utilizar
parámetros de salida
PRINT 'Empieza el ejercicio 4'
USE Gestion10
IF OBJECT_ID('Listado_Oficinas3','P')
DROP PROCEDURE Listado_Oficinas3
IS
NOT
NULL
GO
CREATE
PROCEDURE
CHAR(20),@ventas MONEY
Listado_Oficinas3
@region
AS
SELECT * FROM oficinas WHERE region= @region
AND ventas > @ventas
RETURN (SELECT COUNT(*) FROM
region= @region AND ventas > @ventas)
oficinas
WHERE
GO
DECLARE @resultado INT
EXEC @resultado=Listado_Oficinas3 Este, 1000
SELECT @resultado
EXEC @resultado=Listado_Oficinas3 Este, 100000
PRINT @resultado
EXEC @resultado=Listado_Oficinas3 Norte, 0
PRINT @resultado
EXEC @resultado=Listado_Oficinas3 Norte, 10000
PRINT @resultado
5. Crea un procedimiento que muestre los n productos más caros, n es
un valor que se indicará en la llamada.
PRINT 'Empieza el ejercicio 5'
USE Gestion10
IF OBJECT_ID('ProductosMasCaros','P')
DROP PROC ProductosMasCaros
IS
NOT
NULL
GO
CREATE PROCEDURE
ProductosMasCaros @num int
AS
SELECT
TOP
Idproducto,idfab,descripcion,precio
FROM
(@num)
Productos
ORDER BY Precio DESC;
GO
EXEC ProductosMasCaros 5
EXEC ProductosMasCaros 10
6. Crear otro procedimiento que muestre los n productos más caros con
empates y nos devuelva cuántos hay.
PRINT 'Empieza el ejercicio 6'
USE Gestion10
IF OBJECT_ID('ProductosMasCaros2','P')
DROP PROC ProductosMasCaros2
IS
NOT
NULL
GO
CREATE PROCEDURE
ProductosMasCaros2 @num int
AS
SELECT
TOP
(@num)
Idproducto,idfab,descripcion,precio
FROM
ORDER
WITH
TIES
Productos
BY Precio DESC;
RETURN @@ROWCOUNT -- variable del sistema que
devuelve el número de filas de la última operación.
DECLARE @resul INT
EXEC @resul=ProductosMasCaros2 13
SELECT @resul AS Resultado
EXEC @resul=ProductosMasCaros2 10
SELECT @resul AS
Resultado
7. No dejar eliminar productos que tengan existencias.
PRINT 'Empieza el ejercicio 7'
USE Gestion10
IF OBJECT_ID('Controlexistencias','P')
DROP PROC Controlexistencias
IS
NOT
NULL
GO
CREATE TRIGGER
Controlexistencias
ON Productos INSTEAD
OF DELETE -- Tenemos que
comprobar el stock antes de que se realice el borrado
AS
BEGIN
DELETE
Productos
FROM
Productos P INNER JOIN
Deleted D
P.idfab=D.idfab AND P.idproducto=D.idproducto
ON
-- Aquí hay que utilizar alias de tablas porque los
campos se llaman igual en las 2 tablas
WHERE D.existencias <= 0
-- Si existencias > 0 el producto
borra.
tiene stock, no se
END;
GO
SELECT 'Antes',* FROM productos WHERE idfab='bic' AND
idproducto=41003; -- Para comprobar las existencias del
producto
DELETE
Productos
WHERE
idfab='bic'
AND
idproducto=41003; -- un producto que tenga existencias
-- Intentamos borrar el producto.
SELECT 'Después
DELETE',* FROM
idfab='bic' AND idproducto=41003;
productos
WHERE
-- Comprobamos que el producto sigue en la
tabla
DELETE
Productos
WHERE
idfab='bic'
AND
idproducto=41672; -- un producto que no tiene stock
(existencias=0)
-- Intentamos borrar el producto.
SELECT 'Después
DELETE',* FROM
idfab='bic' AND idproducto=41672;
productos
WHERE
-- Comprobamos que el producto ya no está en la
tabla
Ayuda ejercicios unidad 9: Programación en TRANSACT SQL
(III)
8. Hacer que no se pueda insertar un pedido si no hay suficiente stock.
PRINT 'Empieza el ejercicio 8'
USE Gestion10
IF OBJECT_ID('ControlStock','P')
PROC ControlStock
IS
NOT
NULL
DROP
GO
CREATE TRIGGER
ON pedidos
comprobar el
inserción
ControlStock
INSTEAD
OF INSERT -- Tenemos
stock antes de que se realice
que
la
AS
BEGIN
INSERT
INTO
Pedidos
(numpedido,fechapedido,rep,clie,fab,producto,cant,impor
te)
SELECT
numpedido,fechapedido,rep,clie,fab,producto,cant,import
e
FROM Productos INNER JOIN Inserted
idfab=fab AND idproducto=producto
WHERE existencias-cant
>= 0
ON
suficiente
pedido.
-- Si existencias-cant < 0 es que no hay
stock, por lo que no se insertará el
END;
GO
SELECT 'Antes',* FROM productos WHERE idfab='bic' AND
idproducto=41003; -- Para comprobar las existencias del
producto
INSERT
INTO
Pedidos
(numpedido,fechapedido,rep,fab,producto,clie,cant,impor
te)
VALUES
(010101123,GETDATE(),108,'bic',41003,2103,10,1000);
del
-- Intentamos insertar un pedido de 10 unidades
producto en cuestion (no hay suficiente stock).
SELECT 'Después
INSERT',* FROM
WHERE idfab='bic' AND idproducto=41003;
-- Comprobamos que el campo
ha reducido
productos
existencia no se
SELECT 'Después INSERT',* FROM pedidos WHERE
numpedido=010101123;
-introducido
Comprobamos
que
el
pedido
no
se
ha
INSERT
INTO
Pedidos
(numpedido,fechapedido,rep,fab,producto,clie,cant,impor
te)
VALUES
(010101123,GETDATE(),108,'bic',41003,2103,2,1000);
-- Intentamos insertar un pedido de 2 unidades
del producto en cuestion (hay suficiente stock).
SELECT 'Después
INSERT',* FROM
WHERE idfab='bic' AND idproducto=41003;
productos
-- Comprobamos que el campo existencia se ha
reducidoen 2 unidades (por el otro trigger)
SELECT 'Después INSERT',* FROM pedidos WHERE
numpedido=010101123;
-- Comprobamos que el pedido ahora sí se ha
introducido
9. Crea un procedimiento que impida eliminar varias oficinas en una
sóla operación DELETE.
PRINT 'Empieza el ejercicio 9'
USE Gestion10
IF OBJECT_ID('Borrarvarias','P')
PROC Borrarvarias
IS
NOT
NULL
DROP
GO
CREATE TRIGGER Borrarvarias
ON Oficinas INSTEAD OF
DELETE
AS
BEGIN
IF (SELECT COUNT(*) FROM Deleted)
(SELECT oficina
DELETE
Oficinas
FROM Deleted)
= 1
WHERE
oficina
IN
ELSE
PRINT 'ERROR,
varias oficinas a la vez'
no
se
pueden
eliminar
END;
GO
DELETE Oficinas WHERE
oficina
intentamos eliminar 2 oficinas
SELECT 'Después
DELETE',* FROM
IN
(31,32)
--
Oficinas;
-- Comprobamos que las oficinas siguen en la
tabla
DELETE Oficinas WHERE
eliminar 1 oficina
SELECT 'Después
oficina = 31
DELETE',* FROM
-- intentamos
Oficinas;
-- Comprobamos que la oficina ya no está
Unidad 2. Introducción al SQL. Transact-SQL (I)
2.1. Conceptos básicos 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 estándar definido, a partir
del cual cada sistema gestor ha desarrollado su versión propia.
En SQL Server la versión de SQL que se utiliza se llama TRANSACTSQL.
EL SQL en principio es un lenguaje orientado únicamente a la definición
y al acceso a los datos por lo que no se puede considerar como un
lenguaje de programación 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 también se
suele emplear embebido en programas escritos en lenguajes de
programación convencionales. En estos programas se mezclan las
instrucciones del propio lenguaje (denominado anfitrión) 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 según su propósito en tres grupos:
El DDL (Data Description Language) Lenguaje de Descripción de Datos.
El DCL (Data Control Language) Lenguaje de Control de Datos.
El DML (Data Manipulation Language) Lenguaje de Manipulación de Datos.
El DDL, es la parte del SQL dedicada a la definición 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 validación de
datos, relaciones entre las tablas, etc. Permite definir gran parte del nivel
interno de la base de datos. Por este motivo estas sentencias serán
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 asignación de privilegios de
acceso a los datos (GRANT/REVOKE).
La gestión de transacciones (COMMIT/ROLLBACK).
Una transacción 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 avión. Cuando 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 actualización de la base de
datos (crear una nueva fila en la tabla de billetes y actualizar la plaza
reservada en el vuelo, poniéndola como ocupada) estas dos operaciones
se tienen que ejecutar o todas o ninguna, si después de crear el billete no
se actualiza la plaza porque se cae el sistema, por ejemplo, la base de
datos quedaría en un estado inconsistente ya que la plaza constaría como
libre cuando realmente habría 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 transacción 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 serán utilizadas
normalmente por el administrador mientras que las otras, referentes a
proceso de transacciones serán utilizadas también 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 más utilizada, para recuperar datos de la base de datos. Veremos que
una sola instrucción de recuperación de datos es tan potente que permite
recuperar datos de varias tablas a la vez, realizar cálculos sobre estos
datos y obtener resúmenes.
El DML interactúa con el nivel externo de la base de datos por lo que
sus instrucciones son muy parecidas, por no decir casi idénticas, de un
sistema a otro, el usuario sólo indica lo que quiere recuperar no cómo se
tiene que recuperar, no influye el cómo están almacenados los datos.
Es el lenguaje que utilizan los programadores y los usuarios de la
base de datos.
A lo largo del curso se explicarán cada una de las formas de
explotación de la base de datos. Dependiendo de tu perfil profesional
(programador o administrador) o de tu interés personal te resultará más
útil un bloque u otro.
2.2. Introducción al TRANSACT-SQL
Como hemos dicho, el sistema gestor de base de datos SQL-Server
2005 utiliza su propia versión 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 más allá de un lenguaje SQL
cualquiera ya que incluye características propias de cualquier lenguaje de
programación, características que nos permiten definir la lógica necesaria
para el tratamiento de la información:
Tipos de datos.
Definición de variables.
Estructuras de control de flujo.
Gestión de excepciones.
Funciones predefinidas.
Sin embargo no permite:
Crear interfaces de usuario.
Crear aplicaciones ejecutables, sino elementos que en algún momento
llegarán al servidor de datos y serán 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 programación como
Visual Basic, C, Java, etc. Y por supuesto los lenguajes incluidos en la
plataforma .NET.
También lo podremos ejecutar directamente de manera interactiva, por
ejemplo desde el editor de consultas de SSMS (SQL Server Management
Studio) el entorno de gestión que ya conocemos. Esta es la forma en que
lo utilizaremos nosotros.
Unidad 2. Introducción al SQL. Transact-SQL (II)
2.3. Características generales del lenguaje Transact-SQL
El lenguaje SQL se creó con la finalidad de ser un lenguaje muy
potente y a la vez muy fácil de utilizar, se ha conseguido en gran medida
ya que con una sola frase (instrucción) podemos recuperar datos
complejos (por ejemplo datos que se encuentran en varias tablas,
combinándolos, calculando resúmenes), y utilizando un lenguaje muy
cercano al lenguaje hablado (¡suponiendo que hablamos inglés, claro!).
Por ejemplo:
SELECT
codigo,
nombre
localidad=’Valencia’;
FROM
Clientes
WHERE
Esta instrucción nos permite SELECCIONAR el código y nombre DE los
Clientes CUYA localidad sea Valencia.
La sencillez también radica en que lo que indicamos es lo que
queremos obtener, no el cómo lo tenemos que obtener, de eso se
encargará el sistema automáticamente.
Las sentencias SQL además siguen todas el mismo patrón:
Empiezan por un verbo que indica la acción a realizar,
completado por el objeto sobre el cual queremos realizar la acción,
seguido de una serie de cláusulas (unas obligatorias, otras opcionales) que
completan la frase, y proporcionan más detalles acerca de lo que se quiere
hacer.
Si sabemos algo de inglés nos será más fácil interpretar a la primera lo
que quiere decir la instrucción, y de lo contrario, como el número de
palabras que se emplean es muy reducido, enseguida nos las
aprenderemos.
Por ejemplo en el DDL (acciones sobre la definición de la base de
datos), tenemos 3 verbos básicos:
CREATE (Crear)
DROP (Eliminar)
ALTER (Modificar)
Completados por el tipo de objeto sobre el que actúan y el objeto
concreto:
CREATE DATABASE mibase .......;
Permite crear una base de datos llamada mibase, a continuación
escribiremos las demás cláusulas que completarán la acción, en este caso
dónde se almacenará la base de datos, cuánto ocupará, etc...
CREATE TABLE mitabla (.....);
Permite crear una nueva tabla llamada mitabla, entre paréntesis
completaremos la acción indicando la definición de las columnas de la
tabla.
CREATE INDEX miindex...;
Lo mismo para crear un índice (¿a que lo habíais 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 definición 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 cláusula dentro de una instrucción tenemos:
SELECT
codigo,
FROM
WHERE localidad=’Valencia’;
nombre
Clientes
En esta sentencia nos aparecen dos cláusulas, la cláusula FROM que
nos permite indicar de dónde hay que coger los datos y la cláusula
WHERE que permite indicar una condición de selección.
Otra característica de una sentencia SQL es que acaba con un
punto y coma (;) originalmente éste era obligatorio y servía para indicar el
fin de la instrucción, 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 propósito, 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 situación 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 afectaría también a todos los cálculos que se pueden
realizar sobre la columna nota.
Unidad 2. Introducción 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 establecía con el
parámetro sp_dbcmptlevel pero que ahora Microsoft aconseja no utilizar
ya que desaparecerá en versiones posteriores en vez de eso se tiene que
utilizar la cláusula SET COMPATIBILITY_LEVEL de la instrucción 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 número es más limitado.
El nombre debe empezar por:
o
Una letra, como aparece definida por el estándar Unicode 3.2. La
definición Unicode de letras incluye los caracteres latinos de la "a"
a la "z" y de la "A" a la "Z".
o
El carácter de subrayado ( _ ), arroba ( @ ) o número ( # ).
Ciertos símbolos al principio de un identificador tienen un significado
especial en SQL Server. Un identificador que empieza con el signo de
arroba indica un parámetro o una variable local. Un identificador que
empieza con el signo de número indica una tabla o procedimiento temporal.
Un identificador que empieza con un signo de número 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.
Si queremos utilizar un nombre que no siga estas reglas, normalmente
para poder incluir espacios en blanco, lo tenemos que escribir encerrado
entre corchetes [ ] (también se pueden utilizar las comillas pero
recomendamos utilizar los corchetes).
2.5. Tipos de datos
En SQL Server 2005, cada columna, expresión, variable y parámetro
está
asociado
a
un
tipo
de
datos.
Un tipo de datos, realmente define el conjunto de valores válidos para los
campos definidos de ese tipo. Indica si el campo puede contener: datos
numéricos, 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. También podemos
definir nuestros propios tipos de datos en Transact-SQL o Microsoft .NET
Framework.
Los tipos de datos más utilizados son:
Los numéricos: 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 específico o un símbolo que representa un
valor de dato específico. El formato de las constantes depende del tipo de
datos del valor que representan. En este apartado veremos las más
utilizadas.
Las constantes numéricas se escriben mediante una cadena de números,
con la consideración 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 sería un valor
decimal y el segundo un valor money. De forma predeterminada, los
valores serán 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 García López'.
Para indicar valores negativos y positivos añadimos el prefijo + o según sea el valor positivo o negativo. Sin prefijo se entiende que el valor
es positivo.
Si quieres ver cómo definir constantes para otros tipos de datos, visita
el siguiente avanzado
.
Unidad 2. Introducción al SQL. Transact-SQL (IV)
2.7. Las expresiones
Una expresión es una combinación de símbolos y operadores que el
motor de base de datos de SQL Server evalúa para obtener un único
valor. Una expresión simple puede ser una sola constante, variable,
columna o función escalar. Los operadores se pueden usar para combinar
dos o más expresiones simples y formar una expresión 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 implícitamente al tipo
de datos de mayor prioridad.
La función CAST puede convertir explícitamente el tipo de datos con menor
prioridad al tipo de datos con mayor prioridad o a un tipo de datos intermedio
que pueda convertirse implícitamente al tipo de datos con la mayor prioridad.
Tipos de operadores:
- Operadores numéricos:
suma
+
resta
-
multiplicación
*
división
/
módulo
(resto de una división)
%
- Operadores bit a bit: realizan manipulaciones de bits entre dos
expresiones de cualquiera de los tipos de datos de la categoría del tipo de
datos entero.
AND
&
OR
|
OR exclusivo
^
- Operadores de comparación:
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 lógicos:
Aquí sólo los nombraremos ya que en el tema de consultas simples los
veremos en detalle.
ALL
IN
AND
LIKE
ANY
NOT
BETWEEN
OR
EXISTS
SOME
- Operadores de cadenas:
Concatenación
+
Resultados de la expresión
- Si se combinan dos expresiones mediante operadores de
comparación o lógicos, 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
aritméticos, bit a bit o de cadena, el operador determina el tipo de datos
resultante.
Las expresiones complejas formadas por varios símbolos y operadores
se evalúan como un resultado formado por un solo valor. El tipo de datos,
intercalación, precisión y valor de la expresión 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 expresión
define la secuencia en que se combinan las expresiones.
Unidad 2. Introducción 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 (también llamadas funciones de columna): Operan
sobre una colección de valores y devuelven un solo valor de resumen. Por
ejemplo, la función de suma sobre la columna importe para conocer el
importe total: SUM(importe)
Funciones de categoría: Devuelven un valor de categoría para cada fila de
un conjunto de filas, por ejemplo devuelve el número de la fila, el ranking de
la fila en una determinada ordenación, etc.
Funciones escalares: Operan sobre un valor y después devuelven otro valor.
Son las funciones que estamos acostumbrados a utilizar. Las funciones
escalares se clasifican según el tipo de datos de sus operandos
Las variables
En Transact-SQL podemos definir variables, que serán de un tipo de
datos determinado, como tipos de datos podemos utilizar los propios de la
base de datos SQL-SERVER, pero también 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 instrucción DECLARE con el
siguiente formato:
DECLARE @nbvariable tipo
El nombre de la variable debe empezar por el símbolo @, este símbolo
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 asignación 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 expresión válida o algo más 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 pestaña de
resultados. También se puede usar para escribir mensajes:
PRINT 'Este es el mensaje'
Otros elementos del lenguaje
Comentarios. Como en cualquier otro lenguaje de programación,
debemos utilizar comentarios destinados a facilitar la legibilidad del
código. En SQL se insertan comentarios con los signos:
/*
*/
Varias líneas
--
Una
línea
única
/*
Esto
es
en varias líneas */
-- Esto
un
comentario
es un comentario en una única
línea.
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 instrucción, las consultas que se ejecuten a continuación se harán
sobre tablas de esa base de datos si no se indica lo contrario. Es una
instrucción útil para asegurarnos de que la consulta se ejecuta sobre la
base de datos correcta.
GO
GO no es una instrucción Transact-SQL, sino un comando reconocido
por las utilidades sqlcmd y osql, así como por el Editor de código de SQL
Server
Management
Studio.
Las utilidades de SQL Server interpretan GO como una señal 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 específicadas desde el último comando GO o desde el
comienzo de la sesión 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, después del CREATE DATABASE…; tenemos que poner
GO antes del primer CREATE TABLE para que el sistema efectúe la
primera operación 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.
Unidad 3. Consultas simples (I)
3.1. Introducción
Vamos a empezar por la instrucción que más se utiliza en SQL,
la sentencia SELECT. La sentencia SELECT es, con diferencia, la
más compleja y potente de las sentencias SQL, con ella podemos
recuperar datos de una o más tablas, seleccionar ciertos registros
e incluso obtener resúmenes de los datos almacenados en la
base de datos. Es tan compleja que la estudiaremos a lo largo de
varias unidades didácticas incorporando poco a poco nuevas
funcionalidades.
El resultado de una SELECT es una tabla lógica que alberga
las filas resultantes de la ejecución de la sentencia.
La sintaxis completa es la siguiente:
SELECT sentencia::=[WITH
[,...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 básicas para luego ir
añadiendo más cláusulas.
Empezaremos por ver las consultas más simples, basadas en
una sola tabla y nos limitaremos a la siguiente sintaxis:
SELECT [ALL|DISTINCT]
[TOP expresion [PERCENT] [WITH TIES]]
<lista_seleccion>
FROM
[WHERE
3.2. Origen de datos FROM
De la sintaxis anterior, el elemento <origen> indica de dónde
se va a extraer la información y se indica en la cláusula FROM, es
la única cláusula 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 están 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 (Lógica) y el nombre del esquema al que
pertenece la tabla dentro de la base de datos.
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 también cuando queremos combinar una
tabla consigo misma; ya volveremos sobre los alias de tabla
cuando veamos consultas multitabla.
La palabra AS no añade ninguna operatividad, está más por
estética.
Podemos escribir:
SELECT ...
FROM tabla1
tabla1
Sacamos los datos de la tabla
SELECT ...
FROM tabla1 t1
Sacamos
los datos de la
tabla tabla1 y le asignamos un alias de tabla: t1
SELECT ...
FROM tabla1 AS t1
sentencia anterior.
Es
equivalente
a
la
Si la tabla o la vista están 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 están fuera del servidor local en un servidor
vinculado, se utiliza un nombre de cuatro partes con el formato
nbservidor.catalogo.nbEsquema.nbTabla. Volveremos más
adelante sobre las conexiones remotas.
Unidad 3. Consultas simples (II)
3.3. La lista de selección
En la lista de selección <lista_seleccion> indicamos las
columnas que se tienen que visualizar en el resultado de la
consulta.
<lista_seleccion> ::=
Separamos la definición de cada columna por una coma y las
columnas del resultado aparecerán en el mismo orden que en la
lista de selección.
Para cada columna del resultado su tipo de datos, tamaño,
precisión y escala son los mismos que los de la expresión que da
origen a esa columna.
Podemos definir las columnas del resultado de varias formas,
mediante:
Una expresión simple:
o
una referencia a una función.
o
una variable local
o
una constante
o
una columna del origen de datos,
Una subconsulta escalar, que es otra instrucción SELECT
que devuelve un único valor y se evalúa para cada fila del
origen de datos (esto no lo veremos de momento).
Una expresión compleja generada al usar operadores en una
o más expresiones simples.
La palabra clave *.
La asignación de variables con el formato @variable_local =
expresión.
La palabra clave $IDENTITY.
La palabra clave $ROWGUID.
3.4. Columnas del origen de datos
Cuando queremos indicar en la lista de selección 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
más de una tabla del origen de datos.
Ejemplos de consulta simple.
Listar nombres, oficinas, y fechas de contrato de todos los
empleados:
SELECT
FROM
nombre, oficina, contrato
empleados;
El resultado sería:
nombre
oficina
contrato
Antonio Viguer
12
1986-10-20
Alvaro Jaumes
21
1986-12-10
Juan Rovira
12
1987-03-01
José González
12
1987-05-19
Vicente Pantalla
13
1988-02-12
Luis Antonio
11
1988-06-14
Jorge Gutiérrez
22
1988-11-14
Ana Bustamante
21
1989-10-12
María Sunta
11
1999-10-12
Juan Victor
NULL
1990-01-13
Listar una tarifa de productos:
SELECT
idfab,
productos.precio
FROM
idproducto,
descripcion,
productos;
Hemos cualificado la columna precio aunque no es necesario
en este caso.
El resultado sería:
Idfab
idproducto
descripcion
precio
aci
41001
arandela
0,58
aci
41002
bisagra
0,80
aci
41003
art t3
1,12
aci
41004
art t4
1,23
aci
4100x
junta
0,26
aci
4100y
extractor
28,88
aci
4100z
mont
26,25
bic
41003
manivela
6,52
bic
41089
rodamiento
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 cláusula AS. Se
escribe el nuevo texto tal cual sin comillas siguiendo las reglas de
los
identificadores.
Ejemplo:
SELECT numclie,nombre AS
FROM clientes;
El resultado será :
Numclie nombrecliente
2101
Luis García
Antón
2102
Alvaro
Rodríguez
2103
Jaime
Llorens
en vez de:
Numclie
nombre
2101
Luis García
Antón
2102
Alvaro
nombrecliente
Rodríguez
2103
Jaime
Llorens
La palabra AS es opcional.
SELECT numclie,nombre nombrecliente
FROM clientes;
Sería 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 selección y en la cláusula ORDER BY pero no en la
cláusula WHERE.
3.6. Funciones
Existen funciones que podemos utilizar en la lista de selección,
e incluso en otras cláusulas que veremos más adelante, como el
WHERE. Las principales funciones son las siguientes:
Funciones de fecha:
Función
Descripción
GETDATE
Devuelve la fecha actual.
GETUTCDATE
Devuelve la hora UTC.
DATEPART
Devuelve un entero que corresponde a la parte de la fecha
solicitada.
DAY
Devuelve el día de la fecha indicada.
MONTH
Devuelve el mes de la fecha indicada.
YEAR
Devuelve el año de la fecha indicada.
DATENAME
Devuelve una cadena de caracteres que representa el
valor de la unidad especificada de una fecha especificada.
DATEADD
Devuelve un valor datetime nuevo que resulta de sumar un
intervalo de tiempo a una fecha especificada.>
DATEDIFF
Devuelve el nº de intervalos que hay entre dos fechas.
@@DATEFIRST
Devuelve el primer día de la semana establecido con SET
DATEFIRST.
SET
DATEFIRST
Establece el primer día de la semana en un número del 1
al 7.
Unidad 3. Consultas simples (IV)
Funciones de cadena:
Función
Descripción
ASCII
Devuelve el valor de código ASCII del carácter situado más a
la izquierda de una expresión de caracteres.
CHAR
Devuelve el carácter ASCII del entero indicado.
NCHAR
Devuelve el carácter Unicode del entero indicado.
UNICODE
Devuelve el entero que se corresponde al carácter Unicode
indicado.
LEN
Devuelve el total de caracteres de una cadena, excluidos los
espacios en blanco finales.
LTRIM
Devuelve una cadena tras quitarle los espacios en blanco
iniciales.
RTRIM
Devuelve una cadena tras quitarle los espacios en blanco
finales.
LEFT
Devuelve los N últimos caracteres de una cadena.
RIGHT
Devuelve los N primeros caracteres de una cadena.
SUBSTRING
Devuelve parte de una expresión.
LOWER
Devuelve la cadena convertida a minúsculas.
UPPER
Devuelve la cadena convertida a mayúsculas.
REPLACE
Reemplaza una determinada cadena.
STUFF
Elimina el número de caracteres especificado e inserta otro
conjunto de caracteres en el punto de inicio indicado.
QUOTENAME
Devuelve una cadena Unicode con los delimitadores
agregados para convertirla en un identificador delimitado
válido de Microsoft SQL Server 2005.
SPACE
Devuelve una cadena de espacios repetidos.
STR
Devuelve una cadena de caracteres a partir de datos
numéricos.
REPLICATE
Repite una cadena N veces.
REVERSE
Devuelve una cadena invertida.
CHARINDEX
Devuelve la posición inicial de la expresión especificada en
una cadena de caracteres.
PATINDEX
Devuelve la posición inicial de la primera repetición de un
patrón en la expresión especificada, o ceros si el patrón no se
encuentra, en todos los tipos de datos de texto y caracteres.
Otras funciones:
Función
Descripción
ROUND
CAST
CONVERT
Redondea un valor a la longitud y precisión indicadas.
y
Convierten de un tipo de datos a otro de forma explícita.
CASE
Evalúa una lista de condiciones.
ISNULL
Reemplaza el valor NULL por otro especificado.
COALESCE
Devuelve la primera expresión distinta de NULL entre sus
argumentos.
Unidad 3. Consultas simples (V)
3.7. Columnas calculadas
Además de las columnas que provienen directamente de la
tabla origen, una consulta SQL puede incluir columnas calculadas
cuyos valores se evalúan a partir de una expresión.
La expresión puede contener cualquier operador válido (+, -, *,
/, &…), cualquier función válida, nombres de columnas del origen
de datos, nombres de parámetros o constantes y para combinar
varias operaciones se pueden utilizar los paréntesis.
Ejemplos de columnas calculadas:
Listar la ciudad, región y el superávit de cada oficina.
Consideraremos el superávit como el volumen de ventas que se
encuentran por encima o por debajo del objetivo de la oficina.
SELECT
ciudad,
superavit
region,
(ventas-objetivo)
AS
FROM
oficinas;
El resultado será:
ciudad
region
superavit
Valencia
este
11800,00
Alicante
este
-6500,00
Castellon
este
1800,00
Badajoz
oeste
11100,00
A Coruña
oeste
-11400,00
Madrid
centro
NULL
Madrid
centro
-10000,00
Pamplona
norte
NULL
Valencia
este
-90000,00
De cada producto queremos saber el id de fabricante, id de
producto, su descripción y el valor de sus existencias.
SELECT
idfab,idproducto,descripcion,(existencias*precio)
AS valoracion
FROM productos;
El resultado sería:
Idfab idproducto
descripcion
valoracion
aci
41001
arandela
160,66
aci
41002
bisagra
133,60
aci
41003
art t3
231,84
aci
41004
art t4
170,97
aci
4100x
junta
9,62
aci
4100y
extractor
722,00
aci
4100z
mont
735,00
bic
41003
manivela
19,56
bic
41089
rodamiento
175,50
Para practicar puedes realizar este Ejercicio Columna
calculada.
Unidad 3. Ejercicio paso a paso: Columna
calculada
Nota: Para realizar los ejercicios tienes que abrir una nueva
consulta sobre la base de datos GestionSimples. En el
Explorador de objetos selecciona la base de datos y elige Nueva
Consulta. En la carpeta Ejercicios del curso tienes el PDF
Tablas_Gestion para consultar en qué tablas está cada campo.
Objetivo
Mostrar una columna que sea el resultado de un cálculo
aritmético.
Ejercicio paso a paso
Listar de cada pedido, su número, código completo del
artículo vendido y precio unitario al que se ha vendido. No es
necesario redondear el precio.
La información precio unitario no se encuentra en la tabla,
pero sí que disponemos del importe total del pedido y la
cantidad, así que podemos calcularlo.
SELECT numpedido, fab, producto, importe/cant AS
Precio
FROM pedidos;
Si quisiéramos redondear el precio a dos decimales, por
ejemplo, podríamos englobar la operación importe/cant en la
función ROUND() de la siguiente forma: ROUND(valor,
nºdecimales) --> ROUND(importe/cant, 2)
Resultado (sin redondear):
Numpedido Fab Producto Precio
110036
aci
4100z
2,50
110037
rei
2a44l
4,50
112963
aci
41004
0,117
112968
aci
41004
1,17
112975
rei
2a44g
3,50
112979
aci
4100z
25,00
112983
aci
41004
1,17
112987
aci
4100y
25,00
112989
fea
114
2,43
112992
aci
41002
0,76
112993
rei
2a45c
0,79
112997
bic
41003
6,52
113003
imm
779c
18,75
113007
imm
773c
9,75
113012
aci
41003
1,07
113013
bic
41003
6,52
113024
qsa
xk47
3,55
113027
aci
41002
8,3333
113034
rei
2a45c
0,79
113042
rei
2a44r
45,00
113045
rei
2a44r
45,00
113048
imm
779c
18,75
113049
qsa
xk47
3,88
113051
qsa
xk47
3,55
113055
aci
4100x
0,25
113057
aci
4100x
NULL
113058
fea
112
1,48
113062
bic
41003
2,43
113065
qsa
xk47
3,55
113069
imm
773c
14,25
De cada producto queremos saber el id de fabricante, id de
producto, su descripción y el valor de sus existencias.
El valor de las existencias es un campo calculado, tendremos
que multiplicar el número de existencias por su precio para ver en
cuánto se valora el stock.
SELECT
idfab,idproducto,descripcion,(existencias*precio)
AS valoracion
FROM productos;
Resultado:
Idfab Idproducto Descripción Valoracion
aci
41001
arandela
NULL
aci
41002
bisagra
NULL
aci
41003
art t3
NULL
aci
41004
art t4
NULL
aci
4100x
junta
NULL
aci
4100y
extractor
NULL
aci
4100z
mont
NULL
bic
41003
manivela
19,56
bic
41089
rodamiento
175,50
bic
41672
plato
0,00
fea
112
cubo
170,20
fea
114
cubo
36,45
imm 773c
reostato
273,00
imm 775c
reostato 2
71,25
imm 779c
reostato 3
0,00
imm 887h
caja clavos
120,42
imm 887p
perno
6,00
imm 887x
manivela
152,00
qsa
xk47
red
134,90
qsa
xk48
red
272,02
qsa
xk48a
red
54,76
rei
2a44g
pas
49,00
rei
2a44l
bomba l
540,00
rei
2a44r
bomba r
540,00
rei
2a45c
junta
165,90
http://www.aulaclic.es/sqlserver/t_3_6.htm co9ntinuar salta este