Las cláusulas "compute" y "compute by" generan totales que aparecen en columnas extras al final del resultado.
Se usa con las funciones de agrupamiento: avg(), count(), max(), min(), sum().
select CAMPOS
from TABLA
compute FUNCION(CAMPO);
El campo que se coloque en la cláusula "compute" debe estar incluida en la lista de campos del "select".
Para ver todos los datos de los visitantes y el promedio del monto de compra de nuestra tabla "visitantes":
select edad,ciudad,montocompra
from visitantes
compute avg(edad),sum(montocompra);
"Compute by" genera cortes de control y subtotales. Se generan filas de detalle y varios valores de resumen cuando
cambian los valores del campo.
Con "compute by" se DEBE usar también la cláusula "order by" y los campos que se incluyan luego de "by" deben estar en
el "order by". Listando varios campos luego del "by" corta un grupo en subgrupos y aplica la función de agregado en cada
nivel de agrupamiento:
select nombre,ciudad,provincia
from visitantes
order by provincia
compute count(provincia)
by provincia;
select nombre,ciudad,provincia
from visitantes
order by provincia,ciudad
compute count(provincia)
by provincia,ciudad;
Los campos que aparecen luego de la cláusula "compute by" DEBEN ser idénticos a un subconjunto de los campos que
aparecen después de "order by" y estar en el mismo orden. Si la cláusula "order by" tiene los siguientes campos:
1
MANUAL DE SQL-SERVER PARTE II
o
... compute ...
by a,b...
o
... compute ...
by a,b,c...
En una misma instrucción se pueden colocar varias cláusulas "compute" combinadas con varias cláusulas "compute by":
El resultado de la consulta anterior muestra el promedio de la compra y la cantidad al final de cada subgrupo de provincia y
ciudad (compute by) y el promedio de las edades y el total del monto de compras de todos (compute).
Los tipos de datos ntext, text e image no se pueden incluir en una cláusula "compute " o "compute by".
Problema:
Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos
datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus
productos.
Eliminamos la tabla si existe:
2
MANUAL DE SQL-SERVER PARTE II
Veamos todos los datos de los visitantes y el promedio del monto de compra:
Empleamos dos cláusulas "compute" en una misma instrucción para averiguar el promedio de las
edades y el total de los montos de las compras:
select edad,ciudad,montocompra
from visitantes
compute avg(edad),sum(montocompra);
Veamos la cantidad de visitantes por provincia y ciudad empleando "compute by". Recuerde que
DEBE usarse "order by" y los campos que se incluyan luego de "by" deben estar en el "order by":
select nombre,ciudad,provincia
from visitantes
order by provincia,ciudad
compute count(provincia)
by provincia,ciudad;
Combinamos dos cláusulas "compute" con dos cláusulas "compute by" para averiguar el promedio
de la compra y la cantidad por provincia y ciudad y el promedio de las edades y el total del monto
de compras de todos los visitantes:
Primer problema:
La provincia almacena en una tabla llamada "inmuebles" los siguientes datos de los
inmuebles y sus
propietarios para cobrar impuestos:
1- Elimine la tabla si existe:
if object_id('inmuebles') is not null
drop table inmuebles;
3
MANUAL DE SQL-SERVER PARTE II
4- Muestre todos los datos y el promedio del monto empleando "compute" (1 resultado
parcial)
Inserte pantalla
6- Realice la misma consulta anterior pero empleando "compute by" para obtener
resultados parciales
por documento,barrio y ciudad.
Inserte pantalla
7- Realice la misma consulta anterior pero con resultados parciales por documento y
barrio (6
resultados parciales dobles)
Inserte pantalla
8- Realice la misma consulta anterior pero con resultados parciales por documento (4
resultados
parciales dobles)
Inserte pantalla
9- Intente realizar la misma consulta anterior pero con resultados parciales por
documento y ciudad.
Aparece un mensaje de error indicando que el subgrupo de campos listados luego del
"by" no es
correcto.
Inserte pantalla
4
MANUAL DE SQL-SERVER PARTE II
10- Combine cláusulas "compute" con "compute by" para averiguar el total de monto a
pagar por
propietario y el promedio de monto de todos (4 resultados parciales y 1 general)
Inserte pantalla
44 - Cláusula top
La palabra clave "top" se emplea para obtener sólo una cantidad limitada de registros, los
primeros n registros de una consulta.
Con la siguiente consulta obtenemos todos los datos de los primeros 2 libros de la tabla:
Es decir, luego del "select" se coloca "top" seguido de un número entero positivo y luego
se continúa con la consulta.
En la consulta anterior solicitamos los títulos y autores de los 3 primeros libros, ordenados
por autor.
Cuando se combina con "order by" es posible emplear también la cláusula "with ties". Esta
cláusula permite incluir en la seleccion, todos los registros que tengan el mismo valor del
campo por el que se ordena, que el último registro retornado si el último registro retornado
(es decir, el número n) tiene un valor repetido en el registro n+1. Es decir, si el valor del
campo por el cual se ordena del último registro retornado (el número n) está repetido en
los siguientes registros (es decir, el n+1 tiene el mismo valor que n, y el n+2, etc.), lo
incluye en la selección.
Veamos un ejemplo:
Esta consulta solicita el retorno de los primeros 3 registros; en caso que el registro
número 4 (y los posteriores), tengan el mismo valor en "autor" que el último registro
retornado (número 3), también aparecerán en la selección.
Si colocamos un valor para "top" que supera la cantidad de registros de la tabla, SQL
Server muestra todos los registros.
Problema:
5
MANUAL DE SQL-SERVER PARTE II
Creamos la tabla:
6
MANUAL DE SQL-SERVER PARTE II
Mostramos los títulos y autores de los 3 primeros libros ordenados por autor:
Realizamos la misma consulta anterior pero empleamos la cláusula "with ties", con lo cual
incluiremos en la selección, todos los registros que tengan el mismo autor que el último registro
retornado, aunque pasemos de 3:
7
MANUAL DE SQL-SERVER PARTE II
Note que retorna los 5 primeros registros porque incluye los dos siguientes que tienen el mismo
valor que el último en el campo "autor" (por el cual se ordena).
Primer problema:
Una empresa tiene registrados sus empleados en una tabla llamada "empleados".
1- Elimine la tabla si existe:
if object_id('empleados') is not null
drop table empleados;
8
MANUAL DE SQL-SERVER PARTE II
6- Realice la misma consulta anterior pero incluya todos los registros que tengan el
mismo valor en
"seccion" que el último (8 registros)
9
MANUAL DE SQL-SERVER PARTE II
7- Muestre nombre, estado civil y seccion de los primeros 4 empleados ordenados por
estado civil y
sección (4 registros)
8- Realice la misma consulta anterior pero incluya todos los valores iguales al último
registro
retornado (5 registros)
10
MANUAL DE SQL-SERVER PARTE II
Inserte pantalla
Las claves primarias pueden ser simples, formadas por un solo campo o compuestas,
más de un campo.
Recordemos que una clave primaria identifica 1 solo registro en una tabla.
Para un valor del campo clave existe solamente 1 registro. Los valores no se repiten ni
pueden ser nulos.
Existe una playa de estacionamiento que almacena cada día los datos de los vehículos
que ingresan en la tabla llamada "vehiculos" con los siguientes campos:
Necesitamos definir una clave primaria para una tabla con los datos descriptos arriba. No
podemos usar solamente la patente porque un mismo auto puede ingresar más de una
vez en el día a la playa; tampoco podemos usar la hora de entrada porque varios autos
pueden ingresar a una misma hora.
Tampoco sirven los otros campos.
Como ningún campo, por si sólo cumple con la condición para ser clave, es decir, debe
identificar un solo registro, el valor no puede repetirse, debemos usar 2 campos.
11
MANUAL DE SQL-SERVER PARTE II
Definimos una clave compuesta cuando ningún campo por si solo cumple con la condición
para ser clave.
En este ejemplo, un auto puede ingresar varias veces en un día a la playa, pero siempre
será a distinta hora.
Usamos 2 campos como clave, la patente junto con la hora de llegada, así identificamos
unívocamente cada registro.
Para establecer más de un campo como clave primaria usamos la siguiente sintaxis:
Nombramos los campos que formarán parte de la clave separados por comas.
Al ingresar los registros, SQL Server controla que los valores para los campos
establecidos como clave primaria no estén repetidos en la tabla; si estuviesen repetidos,
muestra un mensaje y la inserción no se realiza. Lo mismo sucede si realizamos una
actualización.
Problema:
Una playa de estacionamiento almacena cada día los datos de los vehículos que ingresan en la
tabla llamada "vehiculos".
Eliminamos la tabla, si existe:
12
MANUAL DE SQL-SERVER PARTE II
Si ingresamos un registro repitiendo el valor de uno de los campos que forman parte de la clave, si
lo acepta:
Recordemos que los campos que forman parte de la clave primaria no aceptan valores nulos,
aunque no se haya aclarado en la definición de la tabla:
sp_columns vehiculos;
vemos que los campos que forman parte de la clave primaria (patente y horallegada) tienen "NO"
en la columna "IS_NULLABLE", es decir, no admiten valores nulos.
Primer problema:
13
MANUAL DE SQL-SERVER PARTE II
primaria compuesta:
create table consultas(
fechayhora datetime not null,
medico varchar(30) not null,
documento char(8) not null,
paciente varchar(30),
obrasocial varchar(30),
primary key(fechayhora,medico)
);
4- Ingrese varias consultas para un mismo médico en distintas horas el mismo día.
14
MANUAL DE SQL-SERVER PARTE II
6- Intente ingresar una consulta para un mismo médico en la misma hora el mismo
día.
Primer problema:
15
MANUAL DE SQL-SERVER PARTE II
primary key(fechayhora,medico)
);
4- Ingrese varias consultas para un mismo médico en distintas horas el mismo día.
6- Intente ingresar una consulta para un mismo médico en la misma hora el mismo
día.
16
MANUAL DE SQL-SERVER PARTE II
Es importante, al diseñar una base de datos y las tablas que contiene, tener en cuenta la
integridad de los datos, esto significa que la información almacenada en las tablas debe
ser válida, coherente y exacta.
SQL Server ofrece más alternativas, además de las aprendidas, para restringir y validar
los datos, las veremos ordenadamente y al finalizar haremos un resumen de las mismas.
Las restricciones (constraints) son un método para mantener la integridad de los datos,
asegurando que los valores ingresados sean válidos y que las relaciones entre las tablas
se mantenga. Se establecen a los campos y las tablas.
Pueden definirse al crear la tabla ("create table") o agregarse a una tabla existente
(empleando "alter table") y se pueden aplicar a un campo o a varios. Se aconseja crear
las tablas y luego agregar las restricciones.
Se pueden crear, modificar y eliminar las restricciones sin eliminar la tabla y volver a
crearla.
17
MANUAL DE SQL-SERVER PARTE II
Cuando se agrega una restricción a una tabla, SQL Server comprueba los datos
existentes.
Hay varios tipos de restricciones.
48 - Restricción check
La restricción "check" especifica los valores que acepta un campo, evitando que
se ingresen valores inapropiados.
Trabajamos con la tabla "libros" de una librería que tiene los siguientes campos:
codigo, titulo, autor, editorial, preciomin (que indica el precio para los minoristas) y
preciomay (que indica el precio para los mayoristas).
Este tipo de restricción verifica los datos cada vez que se ejecuta una sentencia
"insert" o "update", es decir, actúa en inserciones y actualizaciones.
18
MANUAL DE SQL-SERVER PARTE II
O establecer que cierto campo asuma sólo los valores que se listan:
...
check (CAMPO in ('lunes','miercoles','viernes'));
Pero si establecemos una restricción "check" para un campo que entra en conflicto
con una restricción "default" establecida para el mismo campo, SQL Server lo
permite; pero al intentar ingresar un registro, aparece un mensaje de error.
Primer problema:
Una empresa tiene registrados datos de sus empleados en una tabla llamada
"empleados".
1- Elimine la tabla si existe:
if object_id('empleados') is not null
drop table empleados;
19
MANUAL DE SQL-SERVER PARTE II
5- Intente agregar otra restricción "check" al campo sueldo para asegurar que ninguno
supere el
valor 5000:
20
MANUAL DE SQL-SERVER PARTE II
7- Establezca una restricción para controlar que la fecha de nacimiento que se ingresa
no supere la
fecha actual:
alter table empleados
add constraint CK_fechanacimiento_actual
21
MANUAL DE SQL-SERVER PARTE II
Sabemos que si agregamos una restricción a una tabla que contiene datos, SQL Server
los controla para asegurarse que cumplen con la condición de la restricción, si algún
registro no la cumple, la restricción no se establecece.
Podemos hacerlo cuando agregamos la restricción "check" a una tabla para que SQL
Server acepte los valores ya almacenados que infringen la restricción. Para ello debemos
incluir la opción "with nocheck" en la instrucción "alter table":
22
MANUAL DE SQL-SERVER PARTE II
También podemos deshabilitar las restricciones para agregar o actualizar datos sin
comprobarla:
Para habilitar una restricción deshabilitada se ejecuta la misma instrucción pero con la
cláusula "check" o "check all":
Si se emplea "check constraint all" no se coloca nombre de restricciones, habilita todas las
restricciones que tiene la tabla nombrada.
Para saber si una restricción está habilitada o no, podemos ejecutar el procedimiento
almacenado "sp_helpconstraint" y fijarnos lo que informa la columna "status_enabled".
Problema:
23
MANUAL DE SQL-SERVER PARTE II
preciomin decimal(5,2),
preciomay decimal(5,2)
);
Agregamos una restricción "check" para asegurar que los valores de los campos correspondientes
a precios no puedan ser negativos:
Si intentamos ingresar un valor inválido para algún campo correspondiente al precio, que vaya en
contra de la restricción, por ejemplo el valor "-15" aparecerá un mensaje de error indicando que hay
conflicto con la restricción creada anteriormente y la inserción no se realiza. Igualmente si
intentamos actualizar un precio, que vaya en contra de la restricción.
Si intentamos agregar una restricción que no permita que el precio mayorista supere el precio
minorista, aparece un mensaje de error y la sentencia no se ejecuta, porque hay registros que no
cumplen con la restricción que intentamos establecer. Podemos modificar los datos que no
cumplen la condición de la restricción o eliminar los registros:
Ahora SQL Server si nos permite agregar la restricción "check" que impida que se ingresen valores
para "preciomay" superiores a "preciomin":
sp_helpconstraint libros;
Note que los campos correspondientes a precios admiten valores 0 y 999.99 (por el tipo de dato y
la restricción), además del valor "null".
Primer problema:
Una empresa tiene registrados datos de sus empleados en una tabla llamada
"empleados".
1- Elimine la tabla (si existe):
if object_id('empleados') is not null
drop table empleados;
24
MANUAL DE SQL-SERVER PARTE II
3- Intente agregar una restricción "check" para asegurarse que no se ingresen valores
negativos para
el sueldo:
alter table empleados
add constraint CK_empleados_sueldo_positivo
check (sueldo>=0);
No se permite porque hay un valor negativo almacenado.
25
MANUAL DE SQL-SERVER PARTE II
26
MANUAL DE SQL-SERVER PARTE II
8- Establezca una restricción "check" para "seccion" que permita solamente los valores
"Sistemas",
"Administracion" y "Contaduría":
alter table empleados
add constraint CK_empleados_seccion_lista
check (seccion in ('Sistemas','Administracion','Contaduria'));
No lo permite porque existe un valor fuera de la lista.
27
MANUAL DE SQL-SERVER PARTE II
Inserte pantalla
13- Deshabilite la restricción para poder realizar la actualización del punto precedente.
Inserte pantalla
Hemos visto las restricciones que se aplican a los campos, "default" y "check".
Ahora veremos las restricciones que se aplican a las tablas, que aseguran valores únicos
para cada registro.
Anteriormente, para establecer una clave primaria para una tabla empleábamos la
siguiente sintaxis al crear la tabla, por ejemplo:
Cada vez que establecíamos la clave primaria para la tabla, SQL Server creaba
automáticamente una restricción "primary key" para dicha tabla. Dicha restricción, a la
cual no le dábamos un nombre, recibía un nombre dado por SQL Server que comienza
con "PK" (por primary key), seguido del nombre de la tabla y una serie de letras y
números aleatorios.
Podemos agregar una restricción "primary key" a una tabla existente con la sintaxis básica
siguiente:
En el siguiente ejemplo definimos una restricción "primary key" para nuestra tabla "libros"
para asegurarnos que cada libro tendrá un código diferente y único:
28
MANUAL DE SQL-SERVER PARTE II
Con esta restricción, si intentamos ingresar un registro con un valor para el campo
"codigo" que ya existe o el valor "null", aparece un mensaje de error, porque no se
permiten valores duplicados ni nulos. Igualmente, si actualizamos.
Por convención, cuando demos el nombre a las restricciones "primary key" seguiremos el
formato "PK_NOMBRETABLA_NOMBRECAMPO".
Sabemos que cuando agregamos una restricción a una tabla que contiene información,
SQL Server controla los datos existentes para confirmar que cumplen las exigencias de la
restricción, si no los cumple, la restricción no se aplica y aparece un mensaje de error. Por
ejemplo, si intentamos definir la restricción "primary key" para "libros" y hay registros con
códigos repetidos o con un valor "null", la restricción no se establece.
Cuando establecíamos una clave primaria al definir la tabla, automáticamente SQL Server
redefinía el campo como "not null"; pero al agregar una restricción "primary key", los
campos que son clave primaria DEBEN haber sido definidos "not null" (o ser
implícitamente "not null" si se definen identity).
SQL Server permite definir solamente una restricción "primary key" por tabla, que asegura
la unicidad de cada registro de una tabla.
Un campo con una restricción "primary key" puede tener una restricción "check".
Un campo "primary key" también acepta una restricción "default" (excepto si es identity),
pero no tiene sentido ya que el valor por defecto solamente podrá ingresarse una vez; si
intenta ingresarse cuando otro registro ya lo tiene almacenado, aparecerá un mensaje de
error indicando que se intenta duplicar la clave.
Problema:
29
MANUAL DE SQL-SERVER PARTE II
sp_helpconstraint libros;
Definimos una restricción "primary key" para nuestra tabla "libros" para asegurarnos que cada libro
tendrá un código diferente y único:
sp_helpconstraint libros;
Si intentamos ingresar un registro con un valor para el campo "codigo" que ya existe, no lo permite.
Tampoco permite modificar un código colocando uno existente.
Primer problema:
Una empresa tiene registrados datos de sus empleados en una tabla llamada
"empleados".
1- Elimine la tabla si existe:
if object_id('empleados') is not null
drop table empleados;
30
MANUAL DE SQL-SERVER PARTE II
4- Intente establecer una restricción "primary key" para la tabla para que el
documento no se repita
ni admita valores nulos:
alter table empleados
add constraint PK_empleados_documento
primary key(documento);
No lo permite porque la tabla contiene datos que no cumplen con la restricción,
debemos eliminar (o modificar) el registro que tiene documento duplicado:
delete from empleados
where nombre='Carlos Fuentes';
51 - Restricción unique
31
MANUAL DE SQL-SERVER PARTE II
Hemos visto que las restricciones aplicadas a tablas aseguran valores únicos para cada
registro.
Anteriormente aprendimos la restricción "primary key", otra restricción para las tablas es
"unique".
Se emplea cuando ya se estableció una clave primaria (como un número de legajo) pero
se necesita asegurar que otros datos también sean únicos y no se repitan (como número
de documento).
Ejemplo:
Recuerde que cuando agregamos una restricción a una tabla que contiene información,
SQL Server controla los datos existentes para confirmar que cumplen la condición de la
restricción, si no los cumple, la restricción no se aplica y aparece un mensaje de error. En
el caso del ejemplo anterior, si la tabla contiene números de documento duplicados, la
restricción no podrá establecerse; si podrá establecerse si tiene valores nulos.
Problema:
32
MANUAL DE SQL-SERVER PARTE II
Creamos la tabla:
sp_helpconstraint alumnos;
Primer problema:
Una empresa de remises tiene registrada la información de sus vehículos en una tabla
llamada
"remis".
1- Elimine la tabla si existe:
if object_id('remis') is not null
drop table remis;
3- Ingrese algunos registros, 2 de ellos con patente repetida y alguno con patente
nula:
33
MANUAL DE SQL-SERVER PARTE II
4- Intente agregar una restricción "unique" para asegurarse que la patente del remis
no tomará
valores repetidos.
No se puede porque hay valores duplicados.
34
MANUAL DE SQL-SERVER PARTE II
Problema:
Creamos la tabla:
Agregamos una restricción "check" para que el campo "notafinal" admita solamente valores entre 0
y 10:
35
MANUAL DE SQL-SERVER PARTE II
sp_helpconstraint alumnos;
sp_helpconstraint alumnos;
constraint_type constraint_name status_enabled
constraint_keys
------------------------------------------------------------------------------------------
CHECK on column notafinal CK_alumos_nota Disabled ([notafinal]>=0...
Pueden eliminarse varias restricciones con una sola instrucción separándolas por comas.
Cuando eliminamos una tabla, todas las restricciones que fueron establecidas en ella, se
eliminan también.
Problema:
36
MANUAL DE SQL-SERVER PARTE II
Definimos una restricción "primary key" para nuestra tabla "libros" para asegurarnos que cada libro
tendrá un código diferente y único:
Definimos una restricción "check" para asegurarnos que el precio no será negativo:
Definimos una restricción "default" para el campo "autor" para que almacene "Desconocido":
Definimos una restricción "default" para el campo "precio" para que almacene 0:
sp_helpconstraint libros;
Vemos si se eliminaron:
sp_helpconstraint libros;
Aparecen 2 restricciones.
37
MANUAL DE SQL-SERVER PARTE II
Primer problema:
Una playa de estacionamiento almacena cada día los datos de los vehículos que
ingresan en la tabla
llamada "vehiculos".
1- Elimine la tabla, si existe:
if object_id('vehiculos') is not null
drop table vehiculos;
2- Cree la tabla:
create table vehiculos(
patente char(6) not null,
tipo char(1),--'a'=auto, 'm'=moto
horallegada datetime not null,
horasalida datetime
);
3- Establezca una restricción "check" que admita solamente los valores "a" y "m" para
el campo
"tipo":
alter table vehiculos
add constraint CK_vehiculos_tipo
check (tipo in ('a','m'));
4- Establezca una restricción "default" para el campo "tipo" que almacene el valor "a"
en caso de no
ingresarse valor para dicho campo:
alter table vehiculos
add constraint DF_vehiculos_tipo
default 'a'
for tipo;
Inserte pantalla
5- Establezca una restricción "check" para el campo "patente" para que acepte 3 letras
seguidas de 3
dígitos:
alter table vehiculos
add constraint CK_vehiculos_patente_patron
check (patente like '[A-Z][A-Z][A-Z][0-9][0-9][0-9]');
Inserte pantalla
6- Agregue una restricción "primary key" que incluya los campos "patente" y
"horallegada":
alter table vehiculos
add constraint PK_vehiculos_patentellegada
primary key(patente,horallegada);
Inserte pantalla
7- Ingrese un vehículo:
insert into vehiculos values('SDR456','a','2005/10/10 10:10',null);
Inserte pantalla
38
MANUAL DE SQL-SERVER PARTE II
Vimos que SQL Server ofrece varias alternativas para asegurar la integridad de datos,
mediante el uso de:
39
MANUAL DE SQL-SERVER PARTE II
II) DE LA TABLA (asegura un identificador único para cada registro de una tabla).
Hay 2 tipos:
a) PRIMARY KEY: identifica unívocamente cada uno de los registros; asegura que
no haya valores duplicados ni valores nulos. Se crea un índice automáticamente.
2. REGLAS (rules) y
3. VALORES PREDETERMINADOS (defaults).
Las reglas especifican los valores que se pueden ingresar en un campo, asegurando que
los datos se encuentren en un intervalo de valores específico, coincidan con una lista de
valores o sigan un patrón.
Una regla se asocia a un campo de una tabla (o a un tipo de dato definido por el usuario,
tema que veremos posteriormente).
Entonces, luego de "create rule" se coloca el nombre de la regla, luego la palabra clave
"as" seguido de una variable (a la cual la precede el signo arroba) y finalmente la
condición.
Por convención, nombraremos las reglas comenzando con "RG", el nombre del campo al
que se asocia y alguna palabra que haga referencia a la condición.
La variable puede tener cualquier nombre, pero debe estar precedido por el signo arroba
(@), dicha variable será reemplazada por el valor del campo cuando se asocie.
Creamos una regla para restringir los valores que se pueden ingresar en un campo
"sueldo" de una tabla llamada "empleados", estableciendo un intervalo de valores:
40
MANUAL DE SQL-SERVER PARTE II
Si intentamos agregar (o actualizar) un registro con valor para el campo "sueldo" que no
esté en el intervalo de valores especificado en la regla, aparece un mensaje de error
indicando que hay conflicto con la regla y la inserción (o actualización) no se realiza.
SQL Server NO controla los datos existentes para confirmar que cumplen con la regla
como lo hace al aplicar restricciones; si no los cumple, la regla se asocia igualmente; pero
al ejecutar una instrucción "insert" o "update" muestra un mensaje de error, es decir, actúa
en inserciones y actualizaciones.
La regla debe ser compatible con el tipo de datos del campo al cual se asocia; si esto no
sucede, SQL Server no lo informa al crear la regla ni al asociarla, pero al ejecutar una
instrucción "insert" o "update" muestra un mensaje de error.
No se puede crear una regla para campos de tipo text, image, o timestamp.
Si asocia una nueva regla a un campo que ya tiene asociada otra regla, la nueva regla
reeemplaza la asociación anterior; pero la primera regla no desaparece, solamente se
deshace la asociación.
La función que cumple una regla es básicamente la misma que una restricción "check",
las siguientes características explican algunas diferencias entre ellas:
- una restricción "check" se almacena con la tabla, cuando ésta se elimina, las
restricciones también se borran. Las reglas son objetos diferentes e independientes de las
tablas, si eliminamos una tabla, las asociaciones desaparecen, pero las reglas siguen
existiendo en la base de datos;
- una restricción "check" puede incluir varios campos; una regla puede asociarse a
distintos campos (incluso de distintas tablas);
- una restricción "check" puede hacer referencia a otros campos de la misma tabla, una
regla no.
41
MANUAL DE SQL-SERVER PARTE II
Un campo puede tener reglas asociadas a él y restricciones "check". Si hay conflicto entre
ellas, SQL Server no lo informa al crearlas y/o asociarlas, pero al intentar ingresar un valor
que alguna de ellas no permita, aparece un mensaje de error.
Con "sp_helpconstraint" podemos ver las reglas asociadas a los campos de una tabla.
Con "sp_help" podemos ver todos los objetos de la base de datos activa, incluyendo las
reglas, en tal caso en la columna "Object_type" aparece "rule".
Problema:
Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados".
Eliminamos la tabla si existe:
Recuerde que las reglas son objetos independientes de las tablas (no se eliminan al borrar la
tabla), así que debemos eliminarlas con las siguientes intrucciones (en el siguiente capítulo
explicaremos este tema):
42
MANUAL DE SQL-SERVER PARTE II
Ejecutamos el procedimiento almacenado del sistema "sp_help" para ver si la regla creada
anteriormente fue creada:
sp_help;
Ejecutamos el procedimiento almacenado del sistema "sp_helpconstraint" para ver si está asociada
la regla a algún campo de "empleados":
sp_helpconstraint empleados;
Si ingresamos un registro con un documento que no cumpla la regla, SQL Server lo acepta porque
la regla aún no está asociada al campo:
Note que hay un documento que no cumple la regla, pero SQL Server no controla los datos
existentes, actúa en inserciones y actualizaciones, si intentamos ingresar un valor para
"documento" en el cual incluyamos caracteres, aparecerá un mensaje de error.
sp_helpconstraint empleados;
Aparece la regla.
Creamos una regla para restringir los valores que se pueden ingresar en un campo "seccion":
Creamos una regla para restringir los valores que se pueden ingresar en el campo "fechaingreso",
para que no sea posterior a la fecha actual:
43
MANUAL DE SQL-SERVER PARTE II
Creamos una regla para restringir los valores que se pueden ingresar en el campo "hijos":
Creamos una regla para restringir los valores que se pueden ingresar en un campo "sueldo":
Si intentamos ingresar (o actualizar) un registro con el valor "6000" para "sueldo", SQL Server
muestra un mensaje de error y la acción no se realiza.
Creamos otra regla para restringir los valores que se pueden ingresar en un campo "sueldo":
La nueva regla reeemplaza la asociación anterior. Ahora podemos ingresar el valor "6000" en el
campo "sueldo":
sp_help;
sp_helpconstraint empleados;
Primer problema:
44
MANUAL DE SQL-SERVER PARTE II
Una playa de estacionamiento almacena cada día los datos de los vehículos que
ingresan en la tabla
llamada "vehiculos".
1- Elimine la tabla, si existe:
if object_id('vehiculos') is not null
drop table vehiculos;
3- Cree la tabla:
create table vehiculos(
patente char(6) not null,
tipo char(1),--'a'=auto, 'm'=moto
horallegada datetime not null,
horasalida datetime
);
5- Cree una regla para restringir los valores que se pueden ingresar en un campo
"patente" (3 letras
seguidas de 3 dígitos):
create rule RG_patente_patron
as @patente like '[A-Z][A-Z][A-Z][0-9][0-9][0-9]'
Inserte pantalla
6- Ejecute el procedimiento almacenado del sistema "sp_help" para ver que la regla
creada
anteriormente existe:
sp_help;
Inserte pantalla
45
MANUAL DE SQL-SERVER PARTE II
Note que hay una patente que no cumple la regla, SQL Server NO controla los datos
existentes, pero
si controla las inserciones y actualizaciones:
select *from empleados;
Inserte pantalla
9- Intente ingresar un registro con valor para el campo "patente" que no cumpla con la
regla.
aparece un mensaje de error indicando que hay conflicto con la regla y la inserción no
se realiza.
Inserte pantalla
10- Cree otra regla que controle los valores para el campo "tipo" para que solamente
puedan
ingresarse los caracteres "a" y "m".
Inserte pantalla
13- Cree otra regla llamada "RG_vehiculos_tipo2" que controle los valores para el
campo "tipo" para que solamente puedan ingresarse los caracteres "a", "c" y "m".
Inserte pantalla
14- Si la asociamos a un campo que ya tiene asociada otra regla, la nueva regla
reeemplaza la asociación anterior. Asocie la regla creada en el punto anterior al campo
"tipo".
Inserte pantalla
16- Cree una regla que permita fechas menores o iguales a la actual.
Inserte pantalla
18- Ingrese un registro en el cual la hora de entrada sea posterior a la hora de salida:
insert into vehiculos values ('NOP555','a','1990-02-01 10:10','1990-02-01 08:30');
Inserte pantalla
19- Intente establecer una restricción "check" que asegure que la fecha y hora de
llegada a la playa
no sea posterior a la fecha y hora de salida:
46
MANUAL DE SQL-SERVER PARTE II
22- Cree una restricción "default" que almacene el valor "b" en el campo "tipo:
alter table vehiculos
add constraint DF_vehiculos_tipo
default 'b'
for tipo;
Note que esta restricción va contra la regla asociada al campo "tipo" que solamente
permite los
valores "a", "c" y "m". SQL Server no informa el conflicto hasta que no intenta ingresar
el valor
por defecto.
Inserte pantalla
23- Intente ingresar un registro con el valor por defecto para el campo "tipo":
insert into vehiculos values ('STU456',default,'1990-02-01 10:10','1990-02-01
15:30');
No lo permite porque va contra la regla asociada al campo "tipo".
24- Vea las reglas asociadas a "empleados" y las restricciones aplicadas a la misma
tabla ejecutando
"sp_helpconstraint".
Muestra 1 restricción "check", 1 restricción "default" y 4 reglas asociadas.
Inserte pantalla
47
MANUAL DE SQL-SERVER PARTE II
Si eliminamos una tabla, las asociaciones de reglas de sus campos desaparecen, pero las
reglas siguen existiendo.
Primer problema:
Una playa de estacionamiento almacena cada día los datos de los vehículos que
ingresan en la tabla
llamada "vehiculos".
1- Elimine la tabla, si existe:
if object_id('vehiculos') is not null
drop table vehiculos;
3- Cree la tabla:
create table vehiculos(
patente char(6) not null,
tipo char(1),--'a'=auto, 'm'=moto
horallegada datetime not null,
horasalida datetime
);
4- Cree una regla para restringir los valores que se pueden ingresar en un campo
"patente" (3 letras
seguidas de 3 dígitos):
create rule RG_patente_patron
as @patente like '[A-Z][A-Z][A-Z][0-9][0-9][0-9]';
6- Intente ingresar un registro con valor para el campo "patente" que no cumpla con la
regla:
insert into vehiculos values ('FGHIJK','a','1990-02-01 18:00',null);
48
MANUAL DE SQL-SERVER PARTE II
aparece un mensaje de error indicando que hay conflicto con la regla y la inserción no
se realiza.
Inserte pantalla
7- Cree otra regla que controle los valores para el campo "tipo" para que solamente
puedan
ingresarse los caracteres "a" y "m":
create rule RG_vehiculos_tipo
as @tipo in ('a','m')
Inserte pantalla
10- Cree otra regla llamada "RG_vehiculos_tipo2" que controle los valores para el
campo "tipo" para
que solamente puedan ingresarse los caracteres "a", "c" y "m":
create rule RG_vehiculos_tipo2
as @tipo in ('a','c','m');
Inserte pantalla
11- Si la asociamos a un campo que ya tiene asociada otra regla, la nueva regla
reeemplaza la
asociación anterior. Asocie la regla creada en el punto anterior al campo "tipo".
Inserte pantalla
49
MANUAL DE SQL-SERVER PARTE II
Podemos utilizar el procedimiento almacenado "sp_help" con el nombre del objeto del
cual queremos información, en este caso el nombre de una regla:
sp_help NOMBREREGLA;
Con "sp_help", no sabemos si las reglas existentes están o no asociadas a algún campo.
"sp_helpconstraint" retorna una lista de todas las restricciones que tiene una tabla.
Podemos ver las reglas asociadas a una tabla con este procedimiento almacenado:
sp_helpconstraint NOMBRETABLA;
- constraint_type: indica que es una regla con "RULE", nombrando el campo al que está
asociada.
sp_helptext NOMBREREGLA;
También se puede consultar la tabla del sistema "sysobjects", que nos muestra el nombre
y varios datos de todos los objetos de la base de datos actual. La columna "xtype" indica
el tipo de objeto, en caso de ser una regla aparece el valor "R":
50
MANUAL DE SQL-SERVER PARTE II
Si queremos ver todas las reglas creadas por nosotros, podemos tipear:
Problema:
Una empresa registra los datos de sus empleados en una tabla llamada "empleados".
Eliminamos la tabla "empleados" (si existe) y las reglas:
Creamos la tabla:
No la asociamos.
sp_help RG_sueldo;
sp_helpconstraint empleados;
51
MANUAL DE SQL-SERVER PARTE II
retorna una lista de todas las restricciones que tiene una tabla. También las reglas asociadas.
Aparecen 2 filas: una con información de la restricción "primary key" y otra con información de la
regla asociada, esta última muestra:
- constraint_type: indica que es una regla con "RULE", nombrando el campo al que está asociada.
sp_helpconstraint empleados;
sp_helptext "RG_seccion_lista";
sp_help RG_sueldo;
52
MANUAL DE SQL-SERVER PARTE II
Sintaxis básica:
create default NOMBREVALORPREDETERMINADO
as VALORPREDETERMINADO;
- una restricción "default" se almacena con la tabla, cuando ésta se elimina, las
restricciones también. Los valores predeterminados son objetos diferentes e
53
MANUAL DE SQL-SERVER PARTE II
Con "sp_help" podemos ver todos los objetos de la base de datos activa,
incluyendo los valores predeterminados, en tal caso en la columna "Object_type"
aparece "default".
Primer problema:
54
MANUAL DE SQL-SERVER PARTE II
Una empresa registra los datos de sus clientes en una tabla llamada "clientes".
1- Elimine la tabla si existe:
if object_id ('clientes') is not null
drop table clientes;
3- Cree la tabla:
create table clientes(
legajo char(4),
nombre varchar(30),
domicilio varchar(30),
ciudad varchar(15),
provincia varchar(20) default 'Cordoba',
fechaingreso datetime
);
4- Cree una regla para establecer un patrón para los valores que se ingresen en el
campo "legajo" (2
letras seguido de 2 cifras) llamada "RG_legajo_patron":
Inserte pantalla
55
MANUAL DE SQL-SERVER PARTE II
Inserte pantalla
11- Ingrese un registro con valores por defecto para los campos "domicilio" y "ciudad"
y vea qué almacenaron.
Inserte pantalla
15- Ingrese algunos registros para ver cómo se almacenan los valores para los cuales
no se insertan datos.
Inserte pantalla
18- Cree una regla que entre en conflicto con el valor predeterminado
"VP_legajo_patron".
Inserte pantalla
20- Intente ingresar un registro con el valor "default" para el campo "legajo".
No lo permite porque al intentar ingresar el valor por defecto establecido con el valor
predeterminado entra en conflicto con la regla "RG_legajo".
Inserte pantalla
56
MANUAL DE SQL-SERVER PARTE II
sp_unbindefault 'TABLA.CAMPO';
sp_unbindefault 'empleados.sueldo';
Problema:
Una empresa registra los datos de sus empleados en una tabla llamada "empleados".
Eliminamos la tabla "empleados" si existe:
Recordemos que si eliminamos una tabla, las asociaciones de los valores predeterminados a sus
campos desaparecen, pero los valores predeterminados siguen existiendo. Si intentamos crear un
valor predeterminado con igual nombre que uno existente, aparecerá un mensaje indicándolo, por
ello, debemos eliminar los valores predeterminados (si existen) para poder crearlos nuevamente:
Creamos la tabla:
57
MANUAL DE SQL-SERVER PARTE II
sp_helpconstraint empleados;
sp_unbindefault 'empleados.barrio';
sp_helpconstraint empleados;
sp_help;
aparece en la lista.
Aun no podemos eliminarlo porque está asociado al campo "domicilio", quitamos la asociación y
luego lo eliminamos:
sp_unbindefault 'empleados.domicilio';
drop default VP_datodesconocido;
Primer problema:
Una librería almacena los datos de sus libros en una tabla llamada "libros".
1- Elimine la tabla si existe:
if object_id ('libros') is not null
drop table libros;
58
MANUAL DE SQL-SERVER PARTE II
3- Cree la tabla:
create table libros(
codigo int identity,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(20),
precio decimal(5,2),
cantidad smallint
);
4- Cree una regla para impedir que se ingresen valores negativos, llamada
"RG_positivo".
Inserte pantalla
7- Cree un valor predeterminado para que almacene el valor cero, llamado "VP_cero".
Inserte pantalla
59
MANUAL DE SQL-SERVER PARTE II
Inserte pantalla
15- Ingrese un registro con valores por defecto para todos los campos, excepto "titulo"
y vea qué se almacenó.
Inserte pantalla
16- Ingrese otro registro con valor predeterminado para el campo "precio" y vea cómo
se almacenó.
Inserte pantalla
18- Verifique que el valor predeterminado "VP_cero" existe aún en la base de datos.
Inserte pantalla
21- Verifique que ya no existe asociación de este valor predeterminado con la tabla
"libros".
4 filas.
Inserte pantalla
22- Verifique que el valor predeterminado "VP_cero" aun existe en la base de datos.
Inserte pantalla
60
MANUAL DE SQL-SERVER PARTE II
Para obtener información de los valores predeterminados podemos emplear los mismos
procedimientos almacenados que usamos para las reglas.
Si empleamos "sp_help", vemos todos los objetos de la base de datos activa (incluyendo
los valores predeterminados); en la columna "Object_type" (tipo de objeto) muestra
"default".
sp_help NOMBREVALORPREDETERMINADO;
"sp_helpconstraint" retorna una lista de todas las restricciones que tiene una tabla.
También los valores predeterminados asociados; muestra la siguiente información:
Con "sp_helptext" seguido del nombre de un valor predeterminado podemos ver el texto
de cualquier valor predeterminado:
sp_helptext NOMBREVALORPREDETERMINADO;
También se puede consultar la tabla del sistema "sysobjects", que nos muestra el nombre
y varios datos de todos los objetos de la base de datos actual. La columna "xtype" indica
el tipo de objeto, en caso de ser un valor predeterminado aparece el valor "D":
Si queremos ver todos los valores predeterminados creados por nosotros, podemos
tipear:
Problema:
Una empresa registra los datos de sus empleados en una tabla llamada "empleados".
Eliminamos la tabla "empleados" (si existe) y los valores predeterminados:
61
MANUAL DE SQL-SERVER PARTE II
Creamos la tabla:
No la asociamos.
sp_help;
Aparece una tabla con todos los objetos de la base de datos activa, incluyendo los dos valores
predeterminados creados anteriormente; se muestra el nombre, el propietario del objeto y, en caso
de los valores predeterminados, aparece "default".
Si agregamos al procedimiento almacenado "sp_help" el nombre del valor predeterminado del cual
queremos información:
sp_help VP_sueldo;
sp_helpconstraint empleados;
retorna una lista de todas las restricciones que tiene una tabla. También los valores
predeterminados asociados. Aparecen 2 filas: una con información de la restricción "primary key" y
otra con información del valor predeterminado asociado, este último muestra:
62
MANUAL DE SQL-SERVER PARTE II
Note que no aparece el valor predeterminado "VP_seccion" porque no fue asociado a la tabla.
sp_helpconstraint empleados;
sp_helptext VP_seccion;
exec sp_unbindefault'empleados.sueldo';
drop default VP_sueldo;
sp_help VP_sueldo;
60 - Indices
Los índices se emplean para facilitar la obtención de información de una tabla. El indice
de una tabla desempeña la misma función que el índice de un libro: permite encontrar
datos rápidamente; en el caso de las tablas, localiza registros.
63
MANUAL DE SQL-SERVER PARTE II
Un índice posibilita el acceso directo y rápido haciendo más eficiente las búsquedas. Sin
índice, SQL Server debe recorrer secuencialmente toda la tabla para encontrar un
registro.
Los índices más adecuados son aquellos creados con campos que contienen valores
únicos.
Es importante identificar el o los campos por los que sería útil crear un índice, aquellos
campos por los cuales se realizan búsqueda con frecuencia: claves primarias, claves
externas o campos que combinan tablas.
No se recomienda crear índices por campos que no se usan con frecuencia en consultas
o no contienen valores únicos.
Dijimos que SQL Server permite crear dos tipos de índices: 1) agrupados (clustered) y 2)
no agrupados (nonclustered).
1) Un INDICE AGRUPADO es similar a una guía telefónica, los registros con el mismo
valor de campo se agrupan juntos. Un índice agrupado determina la secuencia de
almacenamiento de los registros en una tabla.
Se utilizan para campos por los que se realizan busquedas con frecuencia o se accede
siguiendo un orden.
Una tabla sólo puede tener UN índice agrupado.
El tamaño medio de un índice agrupado es aproximadamente el 5% del tamaño de la
tabla.
64
MANUAL DE SQL-SERVER PARTE II
Es recomendable crear los índices agrupados antes que los no agrupados, porque los
primeros modifican el orden físico de los registros, ordenándolos secuencialmente.
SQL Server crea automaticamente índices cuando se crea una restricción "primary key" o
"unique" en una tabla.
Es posible crear índices en las vistas.
62 - Creación de índices
Problema:
sp_helpindex libros;
Aparecen 2 filas, uno por cada índice. Muestra el nombre del índice, si es agrupado (o no), primary
(o unique) y el campo por el cual se indexa.
Creamos una restricción "primary key" al campo "codigo" especificando que cree un índice NO
agrupado:
65
MANUAL DE SQL-SERVER PARTE II
sp_helpindex libros;
sp_helpconstraint libros;
Se creará uno no agrupado porque no especificamos el tipo, además, ya existe uno agrupado y
solamente puede haber uno por tabla.
Veamos los índices de la base de datos activa creados por nosotros podemos tipear la siguiente
consulta:
Primer problema:
Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos".
1- Elimine la tabla si existe y créela con la siguiente estructura:
if object_id('alumnos') is not null
drop table alumnos;
create table alumnos(
legajo char(5) not null,
documento char(8) not null,
apellido varchar(30),
nombre varchar(30),
notafinal decimal(4,2)
);
66
MANUAL DE SQL-SERVER PARTE II
13- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
para
"alumnos":
67
MANUAL DE SQL-SERVER PARTE II
17- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
para
"alumnos":
select name from sysindexes
where name like '%alumnos%';
5 índices.
Inserte pantalla
18- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
por usted:
select name from sysindexes
where name like 'I_%';
3 índices. Recuerde que los índices que crea SQL Server automáticamente al agregarse
una restricción
"primary" o "unique" no comienzan con "I_".
Inserte pantalla
Primer problema:
Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos".
1- Elimine la tabla si existe y créela con la siguiente estructura:
if object_id('alumnos') is not null
drop table alumnos;
create table alumnos(
legajo char(5) not null,
documento char(8) not null,
apellido varchar(30),
nombre varchar(30),
notafinal decimal(4,2)
);
68
MANUAL DE SQL-SERVER PARTE II
13- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
para
"alumnos":
select name from sysindexes
69
MANUAL DE SQL-SERVER PARTE II
17- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
para
"alumnos":
select name from sysindexes
where name like '%alumnos%';
5 índices.
Inserte pantalla
18- Consulte la tabla "sysindexes", para ver los nombres de todos los índices creados
por usted:
select name from sysindexes
where name like 'I_%';
3 índices. Recuerde que los índices que crea SQL Server automáticamente al agregarse
una restricción
"primary" o "unique" no comienzan con "I_".
Inserte pantalla
63 - Regenerar índices
Empleando la opción "drop_existing" junto con "create index" permite regenerar un índice,
con ello evitamos eliminarlo y volver a crearlo. La sintaxis es la siguiente:
También podemos modificar alguna de las características de un índice con esta opción, a
saber:
- campo: se puede cambiar el campo por el cual se indexa, agregar campos, eliminar
algún campo de un índice compuesto.
70
MANUAL DE SQL-SERVER PARTE II
- único: se puede modificar un índice para que los valores sean únicos o dejen de serlo.
En este ejemplo se crea un índice no agrupado para el campo "titulo" de la tabla "libros":
Esta opción no puede emplearse con índices creados a partir de una restricción "primary
key" o "unique".
Problema:
Veamos la información:
sp_helpindex libros;
71
MANUAL DE SQL-SERVER PARTE II
Primer problema:
Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos".
1- Elimine la tabla si existe y créela con la siguiente estructura:
if object_id('alumnos') is not null
drop table alumnos;
create table alumnos(
legajo char(5) not null,
documento char(8) not null,
apellido varchar(30),
nombre varchar(30),
notafinal decimal(4,2)
);
8- Intente modificar con "drop_existing" alguna característica del índice que se creó
automáticamente al agregar la restricción "unique":
create clustered index UQ_alumnos_documento
on alumnos(documento)
with drop_existing;
No se puede emplear "drop_existing" con índices creados a partir de una restricción.
Inserte pantalla
72
MANUAL DE SQL-SERVER PARTE II
16- Modifique el índice "I_alumnos_legajo" para que sea único y conserve todas las
otras
características.
Inserte pantalla
64 - Eliminar índices
73
MANUAL DE SQL-SERVER PARTE II
Los índices creados con "create index" se eliminan con "drop index"; la siguiente es la
sintaxis básica:
Los índices que SQL Server crea automáticamente al establecer una restricción "primary
key" o "unique" no pueden eliminarse con "drop index", se eliminan automáticamente
cuando quitamos la restricción.
Podemos averiguar si existe un índice para eliminarlo, consultando la tabla del sistema
"sysindexes":
Problema:
sp_helpindex libros;
74
MANUAL DE SQL-SERVER PARTE II
sp_helpindex libros;
Primer problema:
Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos".
1- Elimine la tabla si existe y créela con la siguiente estructura:
if object_id('alumnos') is not null
drop table alumnos;
create table alumnos(
legajo char(5) not null,
documento char(8) not null,
apellido varchar(30),
nombre varchar(30),
notafinal decimal(4,2)
);
3- Establezca una restricción "primary" para el campo "legajo" y especifique que cree
un índice
"agrupado".
75
MANUAL DE SQL-SERVER PARTE II
Hasta el momento hemos trabajado con una sola tabla, pero generalmente, se trabaja con
más de una.
Por ejemplo, los datos de nuestra tabla "libros" podrían separarse en 2 tablas, una
llamada "libros" y otra "editoriales" que guardará la información de las editoriales.
En nuestra tabla "libros" haremos referencia a la editorial colocando un código que la
identifique.
Veamos:
De esta manera, evitamos almacenar tantas veces los nombres de las editoriales en la
tabla "libros" y guardamos el nombre en la tabla "editoriales"; para indicar la editorial de
cada libro agregamos un campo que hace referencia al código de la editorial en la tabla
"libros" y en "editoriales".
76
MANUAL DE SQL-SERVER PARTE II
Cuando obtenemos información de más de una tabla decimos que hacemos un "join"
(combinación).
Veamos un ejemplo:
Hay hay tres tipos de combinaciones. En los siguientes capítulos explicamos cada una de
ellas.
Un join es una operación que relaciona dos o más tablas para obtener un resultado que
incluya datos (campos y registros) de ambas; las tablas participantes se combinan según
los campos comunes a ambas tablas.
También es posible emplear varias combinaciones en una consulta "select", incluso puede
combinarse una tabla consigo misma.
select CAMPOS
from TABLA1
join TABLA2
on CONDICIONdeCOMBINACION;
77
MANUAL DE SQL-SERVER PARTE II
Ejemplo:
- combinamos esa tabla con "join" y el nombre de la otra tabla ("editoriales"); se especifica
qué tablas se van a combinar y cómo;
La condicion de combinación, es decir, el o los campos por los que se van a combinar
(parte "on"), se especifica según las claves primarias y externas.
Entonces, si las tablas que combinamos tienen nombres de campos iguales, DEBE
especificarse a qué tabla pertenece anteponiendo el nombre de la tabla al nombre del
campo, separado por un punto (.).
Si una de las tablas tiene clave primaria compuesta, al combinarla con la otra, en la
cláusula "on" se debe hacer referencia a la clave completa, es decir, la condición
referenciará a todos los campos clave que identifican al registro.
Se puede incluir en la consulta join la cláusula "where" para restringir los registros que
retorna el resultado; también "order by", "distinct", etc..
Se emplea este tipo de combinación para encontrar registros de la primera tabla que se
correspondan con los registros de la otra, es decir, que cumplan la condición del "on". Si
un valor de la primera tabla no se encuentra en la segunda tabla, el registro no aparece.
78
MANUAL DE SQL-SERVER PARTE II
select l.codigo,titulo,autor,nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
En algunos casos (como en este ejemplo) el uso de alias es para fines de simplificación y
hace más legible la consulta si es larga y compleja, pero en algunas consultas es
absolutamente necesario.
Problema:
Una librería almacena la información de sus libros para la venta en dos tablas, "libros" y
"editoriales".
vemos que en el campo "editorial" aparece el código, pero no sabemos el nombre de la editorial.
Realizamos un join para obtener datos de ambas tablas (titulo, autor y nombre de la editorial):
79
MANUAL DE SQL-SERVER PARTE II
Mostramos el código del libro, título, autor, nombre de la editorial y el precio realizando un join y
empleando alias:
select l.codigo,titulo,autor,nombre,precio
from libros as l
join editoriales as e
on codigoeditorial=e.codigo;
Note que al listar el campo "codigo" especificamos a qué tabla pertenece; si no lo hacemos SQL
Server no sabrá si nos referimos al de la tabla "libros" o "editoriales". Los demás campos no tienen
referencia a la tabla porque tienen nombres que no se repiten.
Realizamos la misma consulta anterior agregando un "where" para obtener solamente los libros de
la editorial "Siglo XXI":
select l.codigo,titulo,autor,nombre,precio
from libros as l
join editoriales as e
on codigoeditorial=e.codigo
where e.nombre='Siglo XXI';
Obtenemos título, autor y nombre de la editorial, esta vez ordenados por título:
select titulo,autor,nombre
from libros as l
join editoriales as e
on codigoeditorial=e.codigo
order by titulo;
Primer problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también
tiene una tabla
"provincias" donde registra los nombres de las provincias.
1- Elimine las tablas "clientes" y "provincias", si existen:
if (object_id('clientes')) is not null
drop table clientes;
if (object_id('provincias')) is not null
drop table provincias;
80
MANUAL DE SQL-SERVER PARTE II
Segundo problema:
81
MANUAL DE SQL-SERVER PARTE II
documento char(8),
deporte varchar(15),
fecha datetime
);
5- Obtenga el nombre, deporte y las fechas de inasistencias de todos los inscriptos que
pagaron la
matrícula(4 registros)
Inserte pantalla
Vimos que una combinación interna (join) encuentra registros de la primera tabla que se
correspondan con los registros de la segunda, es decir, que cumplan la condición del "on"
y si un valor de la primera tabla no se encuentra en la segunda tabla, el registro no
aparece.
82
MANUAL DE SQL-SERVER PARTE II
Las combinaciones externas combinan registros de dos tablas que cumplen la condición,
más los registros de la segunda tabla que no la cumplen; es decir, muestran todos los
registros de las tablas relacionadas, aún cuando no haya valores coincidentes entre ellas.
Este tipo de combinación se emplea cuando se necesita una lista completa de los datos
de una de las tablas y la información que cumple con la condición. Las combinaciones
externas se realizan solamente entre 2 tablas.
Hay tres tipos de combinaciones externas: "left outer join", "right outer join" y "full outer
join"; se pueden abreviar con "left join", "right join" y "full join" respectivamente.
Se emplea una combinación externa izquierda para mostrar todos los registros de la tabla
de la izquierda. Si no encuentra coincidencia con la tabla de la derecha, el registro
muestra los campos de la segunda tabla seteados a "null".
select titulo,nombre
from editoriales as e
left join libros as l
on codigoeditorial = e.codigo;
El resultado mostrará el título y nombre de la editorial; las editoriales de las cuales no hay
libros, es decir, cuyo código de editorial no está presente en "libros" aparece en el
resultado, pero con el valor "null" en el campo "titulo".
Entonces, un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con
otra tabla (derecha); si un valor de la tabla de la izquierda no encuentra coincidencia en la
tabla de la derecha, se genera una fila extra (una por cada valor no encontrado) con todos
los campos correspondientes a la tabla derecha seteados a "null". La sintaxis básica es la
siguiente:
select CAMPOS
from TABLAIZQUIERDA
left join TABLADERECHA
on CONDICION;
select titulo,nombre
from libros as l
left join editoriales as e
on codigoeditorial = e.codigo;
83
MANUAL DE SQL-SERVER PARTE II
El resultado mostrará el título del libro y el nombre de la editorial; los títulos cuyo código
de editorial no está presente en "editoriales" aparecen en el resultado, pero con el valor
"null" en el campo "nombre".
Un "left join" puede tener clausula "where" que restringa el resultado de la consulta
considerando solamente los registros que encuentran coincidencia en la tabla de la
derecha, es decir, cuyo valor de código está presente en "libros":
select titulo,nombre
from editoriales as e
left join libros as l
on e.codigo=codigoeditorial
where codigoeditorial is not null;
También podemos mostrar las editoriales que NO están presentes en "libros", es decir,
que NO encuentran coincidencia en la tabla de la derecha:
select titulo,nombre
from editoriales as e
left join libros as l
on e.codigo=codigoeditorial
where codigoeditorial is null;
Primer problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también
tiene una tabla
"provincias" donde registra los nombres de las provincias.
1- Elimine las tablas "clientes" y "provincias", si existen y cree las tablas:
if (object_id('clientes')) is not null
drop table clientes;
if (object_id('provincias')) is not null
drop table provincias;
84
MANUAL DE SQL-SERVER PARTE II
Vimos que una combinación externa izquierda (left join) encuentra registros de la tabla
izquierda que se correspondan con los registros de la tabla derecha y si un valor de la
85
MANUAL DE SQL-SERVER PARTE II
Una combinación externa derecha ("right outer join" o "right join") opera del mismo modo
sólo que la tabla derecha es la que localiza los registros en la tabla izquierda.
select titulo,nombre
from libros as l
right join editoriales as e
on codigoeditorial = e.codigo;
El resultado mostrará el título y nombre de la editorial; las editoriales de las cuales no hay
libros, es decir, cuyo código de editorial no está presente en "libros" aparece en el
resultado, pero con el valor "null" en el campo "titulo".
Es FUNDAMENTAL tener en cuenta la posición en que se colocan las tablas en los "outer
join". En un "left join" la primera tabla (izquierda) es la que busca coincidencias en la
segunda tabla (derecha); en el "right join" la segunda tabla (derecha) es la que busca
coincidencias en la primera tabla (izquierda).
En la siguiente consulta empleamos un "left join" para conseguir el mismo resultado que el
"right join" anterior":
select titulo,nombre
from editoriales as e
left join libros as l
on codigoeditorial = e.codigo;
Note que la tabla que busca coincidencias ("editoriales") está en primer lugar porque es
un "left join"; en el "right join" precedente, estaba en segundo lugar.
Un "right join" hace coincidir registros en una tabla (derecha) con otra tabla (izquierda); si
un valor de la tabla de la derecha no encuentra coincidencia en la tabla izquierda, se
genera una fila extra (una por cada valor no encontrado) con todos los campos
correspondientes a la tabla izquierda seteados a "null". La sintaxis básica es la siguiente:
select CAMPOS
from TABLAIZQUIERDA
right join TABLADERECHA
on CONDICION;
Un "right join" también puede tener cláusula "where" que restringa el resultado de la
consulta considerando solamente los registros que encuentran coincidencia en la tabla
izquierda:
select titulo,nombre
from libros as l
86
MANUAL DE SQL-SERVER PARTE II
select titulo,nombre
from libros as l
rightjoin editoriales as e
on e.codigo=codigoeditorial
where codigoeditorial is null;
Primer problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también
tiene una
tabla "provincias" donde registra los nombres de las provincias.
1- Elimine las tablas "clientes" y "provincias", si existen y cree las tablas:
if (object_id('clientes')) is not null
drop table clientes;
if (object_id('provincias')) is not null
drop table provincias;
87
MANUAL DE SQL-SERVER PARTE II
4- Obtenga la misma salida que la consulta anterior pero empleando un "left join".
Inserte pantalla
5- Empleando un "right join", muestre solamente los clientes de las provincias que
existen en
"provincias" (5 registros)
Inserte pantalla
Vimos que una combinación externa izquierda (left join) encuentra registros de la tabla
izquierda que se correspondan con los registros de la tabla derecha y si un valor de la
tabla izquierda no se encuentra en la tabla derecha, el registro muestra los campos
correspondientes a la tabla de la derecha seteados a "null".
Una combinación externa derecha ("right outer join" o "right join") opera del mismo modo
sólo que la tabla derecha es la que localiza los registros en la tabla izquierda.
select titulo,nombre
from libros as l
right join editoriales as e
on codigoeditorial = e.codigo;
El resultado mostrará el título y nombre de la editorial; las editoriales de las cuales no hay
libros, es decir, cuyo código de editorial no está presente en "libros" aparece en el
resultado, pero con el valor "null" en el campo "titulo".
Es FUNDAMENTAL tener en cuenta la posición en que se colocan las tablas en los "outer
join". En un "left join" la primera tabla (izquierda) es la que busca coincidencias en la
segunda tabla (derecha); en el "right join" la segunda tabla (derecha) es la que busca
coincidencias en la primera tabla (izquierda).
En la siguiente consulta empleamos un "left join" para conseguir el mismo resultado que el
"right join" anterior":
select titulo,nombre
from editoriales as e
88
MANUAL DE SQL-SERVER PARTE II
Note que la tabla que busca coincidencias ("editoriales") está en primer lugar porque es
un "left join"; en el "right join" precedente, estaba en segundo lugar.
Un "right join" hace coincidir registros en una tabla (derecha) con otra tabla (izquierda); si
un valor de la tabla de la derecha no encuentra coincidencia en la tabla izquierda, se
genera una fila extra (una por cada valor no encontrado) con todos los campos
correspondientes a la tabla izquierda seteados a "null". La sintaxis básica es la siguiente:
select CAMPOS
from TABLAIZQUIERDA
right join TABLADERECHA
on CONDICION;
Un "right join" también puede tener cláusula "where" que restringa el resultado de la
consulta considerando solamente los registros que encuentran coincidencia en la tabla
izquierda:
select titulo,nombre
from libros as l
right join editoriales as e
on e.codigo=codigoeditorial
where codigoeditorial is not null;
select titulo,nombre
from libros as l
rightjoin editoriales as e
on e.codigo=codigoeditorial
where codigoeditorial is null;
Primer problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también
tiene una
tabla "provincias" donde registra los nombres de las provincias.
1- Elimine las tablas "clientes" y "provincias", si existen y cree las tablas:
if (object_id('clientes')) is not null
drop table clientes;
if (object_id('provincias')) is not null
drop table provincias;
89
MANUAL DE SQL-SERVER PARTE II
primary key(codigo)
);
4- Obtenga la misma salida que la consulta anterior pero empleando un "left join".
Inserte pantalla
5- Empleando un "right join", muestre solamente los clientes de las provincias que
existen en
"provincias" (5 registros)
Inserte pantalla
Vimos que un "left join" encuentra registros de la tabla izquierda que se correspondan con
los registros de la tabla derecha y si un valor de la tabla izquierda no se encuentra en la
tabla derecha, el registro muestra los campos correspondientes a la tabla de la derecha
seteados a "null". Aprendimos también que un "right join" opera del mismo modo sólo que
la tabla derecha es la que localiza los registros en la tabla izquierda.
Una combinación externa completa ("full outer join" o "full join") retorna todos los registros
de ambas tablas. Si un registro de una tabla izquierda no encuentra coincidencia en la
tabla derecha, las columnas correspondientes a campos de la tabla derecha aparecen
90
MANUAL DE SQL-SERVER PARTE II
Veamos un ejemplo:
select titulo,nombre
from editoriales as e
full join libros as l
on codigoeditorial = e.codigo;
La salida del "full join" precedente muestra todos los registros de ambas tablas,
incluyendo los libros cuyo código de editorial no existe en la tabla "editoriales" y las
editoriales de las cuales no hay correspondencia en "libros".
Problema:
Una librería almacena la información de sus libros para la venta en dos tablas, "libros" y
"editoriales".
Eliminamos ambas tablas, si existen y las creamos:
Realizamos una combinación externa completa para obtener todos los registros de ambas tablas,
incluyendo los libros cuyo código de editorial no existe en la tabla "editoriales" y las editoriales de
las cuales no hay correspondencia en "libros":
select titulo,nombre
from editoriales as e
full join libros as l
on codigoeditorial = e.codigo;
91
MANUAL DE SQL-SERVER PARTE II
Primer problema:
4- Empleando un "left join" con "deportes" obtenga todos los datos de los inscriptos (7
registros)
Inserte pantalla
92
MANUAL DE SQL-SERVER PARTE II
6- Muestre los deportes para los cuales no hay inscriptos, empleando un "left join" (1
registro)
Inserte pantalla
8- Emplee un "full join" para obtener todos los datos de ambas tablas, incluyendo las
inscripciones
a deportes inexistentes en "deportes" y los deportes que no tienen inscriptos (8
registros)
Inserte pantalla
Las combinaciones cruzadas (cross join) muestran todas las combinaciones de todos los
registros de las tablas combinadas. Para este tipo de join no se incluye una condición de
enlace. Se genera el producto cartesiano en el que el número de filas del resultado es
igual al número de registros de la primera tabla multiplicado por el número de registros de
la segunda tabla, es decir, si hay 5 registros en una tabla y 6 en la otra, retorna 30 filas.
select CAMPOS
from TABLA1
cross join TABLA2;
Si necesitamos conocer todas las combinaciones posibles para un menú, cada comida
con cada postre, empleamos un "cross join":
La salida muestra cada plato combinado con cada uno de los postres.
Como cualquier tipo de "join", puede emplearse una cláusula "where" que condicione la
salida.
93
MANUAL DE SQL-SERVER PARTE II
Problema:
Un pequeño restaurante tiene almacenados los nombres y precios de sus comidas en una tabla
llamada "comidas" y en una tabla denominada "postres" los mismos datos de sus postres.
Eliminamos las tablas, si existen:
El restaurante quiere combinar los registros de ambas tablas para mostrar los distintos menúes que
ofrece. Lo hacemos usando un "cross join":
La salida muestra cada plato combinado con cada uno de los postres, agregamos una columna
que calcula el precio total de cada menú. Se obtienen 8 registros.
Primer problema:
94
MANUAL DE SQL-SERVER PARTE II
domicilio varchar(30),
edad int
);
create table varones(
nombre varchar(30),
domicilio varchar(30),
edad int
);
3- La agencia necesita la combinación de todas las personas de sexo femenino con las
de sexo
masculino. Use un "cross join" (12 registros)
Inserte pantalla
5- Forme las parejas pero teniendo en cuenta que no tengan una diferencia superior a
10 años (8
registros)
Inserte pantalla
71 - Autocombinación
Un pequeño restaurante tiene almacenadas sus comidas en una tabla llamada "comidas"
que consta de los siguientes campos:
- nombre varchar(20),
- precio decimal (4,2) y
- rubro char(6)-- que indica con 'plato' si es un plato principal
y 'postre' si es postre.
Podemos obtener la combinación de platos empleando un "cross join" con una sola tabla:
95
MANUAL DE SQL-SERVER PARTE II
from comidas as c1
cross join comidas as c2;
En la consulta anterior se empleó un "where" que especifica que se combine "plato" con
"postre".
En una autocombinación se combina una tabla con una copia de si misma. Para ello
debemos utilizar 2 alias para la tabla. Para evitar que aparezcan filas duplicadas,
debemos emplear un "where".
Primer problema:
Una agencia matrimonial almacena la información de sus clientes en una tabla llamada
"clientes".
1- Elimine la tabla si existe y créela:
if object_id('clientes') is not null
drop table clientes;
96
MANUAL DE SQL-SERVER PARTE II
3- La agencia necesita la combinación de todas las personas de sexo femenino con las
de sexo
masculino. Use un "cross join" (12 registros)
Inserte pantalla
5- Realice la misma autocombinación que el punto 3 pero agregue la condición que las
parejas no
tengan una diferencia superior a 5 años (5 registros)
Inserte pantalla
97