Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1.
2.
3.
4.
5.
6.
7.
Operadores relacionales.................................................................................. 13
8.
9.
10. Comentarios.................................................................................................. 17
11. Valores null (is null)........................................................................................ 18
12. Clave primaria............................................................................................... 20
13. Campo con atributo Identity............................................................................22
14. Otras caractersticas del atributo Identity.........................................................24
15. Truncate table............................................................................................... 26
16. Otros tipos de datos en SQL Server...................................................................27
17. Tipo de dato (texto)....................................................................................... 28
18. Tipo de dato (numrico)................................................................................. 30
19. Tipo de dato (fecha y hora)............................................................................. 32
20. Ingresar algunos campos (insert into)................................................................33
21. Valores por defecto (default)...........................................................................34
22. Columnas calculadas (operadores aritmticos y de concatenacin)......................36
23. Alias............................................................................................................. 38
24. Funciones...................................................................................................... 39
25. Funciones para el manejo de cadenas...............................................................41
26. Funciones matemticas................................................................................... 46
27. Funciones para el uso de fechas y horas............................................................48
Cada campo con su tipo debe separarse con comas de los siguientes, excepto el ltimo.
Cuando se crea una tabla debemos indicar su nombre y definir al menos un campo con su tipo de
dato. En esta tabla "usuarios" definimos 2 campos:
Cada usuario ocupar un registro de esta tabla, con su respectivo nombre y clave.
Para nombres de tablas, se puede utilizar cualquier caracter permitido para nombres de
directorios, el primero debe ser un caracter alfabtico y no puede contener espacios. La longitud
mxima es de 128 caracteres.
Si intentamos crear una tabla con un nombre ya existente (existe otra tabla con ese nombre),
mostrar un mensaje indicando que ya hay un objeto llamado 'usuarios' en la base de datos y la
sentencia no se ejecutar. Esto es muy importante ya que cuando haga los ejercicios en este sitio
puede haber otra persona que haya creado una tabla con el nombre que usted especifique.
Para ver la estructura de una tabla usamos el procedimiento almacenado "sp_columns" junto al
nombre de la tabla:
sp_columns usuarios;
aparece mucha informacin que no analizaremos en detalle, como el nombre de la tabla, su
propietario, los campos, el tipo de dato de cada campo, su longitud, etc.:
...COLUMN_NAME TYPE_NAME
LENGHT
_______________________________________
nombre
varchar
30
clave
varchar
10
Para eliminar una tabla usamos "drop table" junto al nombre de la tabla a eliminar:
drop table usuarios;
Si intentamos eliminar una tabla que no existe, aparece un mensaje de error indicando tal
situacin y la sentencia no se ejecuta. Para evitar este mensaje podemos agregar a la instruccin
lo siguiente:
if object_id('usuarios') is not null
drop table usuarios;
En la sentencia precedente especificamos que elimine la tabla "usuarios" si existe.
Problema Resuelto:
Vamos a crear una tabla llamada "usuarios". En primer lugar vamos a eliminar la tabla "usuarios"
averiguando si existe (a esto vamos a repetirlo siempre porque puede haber otro usuario que
haya creado una tabla con el mismo nombre):
if object_id('usuarios') is not null
drop table usuarios;
Recordar que debemos finalizar cada comando con un punto y coma.
La tabla "usuarios" contendr los siguientes campos:
- nombre: varchar de 30 caracteres de longitud,
- clave: varchar de 10 caracteres de longitud.
Ahora si creamos la tabla:
create table usuarios (
nombre varchar(30),
clave varchar(10)
);
aparece un mensaje indicando que el comando se complet exitosamente.
Veamos las tablas existentes:
sp_tables @table_owner='dbo';
Veamos la estructura de la tabla "usuarios":
sp_columns usuarios;
aparece mucha informacin que no analizaremos en detalle, como el nombre de la tabla, su
propietario, los campos y sus tipos de datos, su longitud, etc.:
...COLUMN_NAME TYPE_NAME
LENGHT
_______________________________________
nombre
varchar
30
clave
varchar
10
Intentemos crear una tabla con el mismo nombre, mostrar un mensaje indicando que ya hay un
objeto llamado 'usuarios' en la base de datos y la sentencia no se ejecutar:
TABLE_OWNER
TABLE_NAME
wi121505_scratchya
dbo
usuarios
TABLE_TYPE REMARKS
TABLE
sp_columns usuarios;
TABLE_Q TABLE TABL COLU DAT TYPE PRE LE SC RA NUL REM COLU SQL_D SQL_DAT CHAR_OC ORDINA IS_N SS_DA
UALIFIE _OWN E_NA MN_N A_TY _NA CISI NG AL DI LAB ARK MN_D ATA_TY ETIME_S TET_LEN L_POSIT ULLA TA_TY
R
ER
ME
AME
PE
ME ON TH E X LE S
EF
PE
UB
GTH
ION
BLE PE
wi12150
5_scratc
hya
dbo
usuar nombr
ios
e
12
varc
har
30
30
12
30
YES
39
wi12150
5_scratc
hya
dbo
usuar
clave
ios
12
varc
har
10
10
12
10
YES
39
Problemas Propuestos
Problema 01:
Necesita almacenar los datos de sus amigos en una tabla. Los datos que guardar sern: apellido,
nombre, domicilio y telfono.
1. Elimine la tabla "agenda" si existe:
if object_id('agenda') is not null
drop table agenda;
Problema 02:
Necesita almacenar informacin referente a los libros de su biblioteca personal. Los datos que
guardar sern: ttulo del libro, nombre del autor y nombre de la editorial.
1. Elimine la tabla "libros", si existe:
if object_id('libros') is not null
drop table libros;
2. Verifique que la tabla "libros" no existe en la base de datos activa (sp_tables
@table_owner='dbo').
3. Cree una tabla llamada "libros". Debe definirse con los siguientes campos: titulo,varchar(20);
autor, varchar(30) y editorial, varchar(15).
4. Intente crearla nuevamente. Aparece mensaje de error.
5. Visualice las tablas existentes.
6. Visualice la estructura de la tabla "libros".
7. Elimine la tabla.
8. Intente eliminar la tabla nuevamente.
En el siguiente ejemplo se colocan los valores en distinto orden en que se nombran los campos, el
valor de la clave (la cadena "Boca") se guardar en el campo "nombre" y el valor del nombre (la
cadena "Luis") en el campo "clave":
insert into usuarios (nombre,clave) values ('Boca','Luis');
varchar: se usa para almacenar cadenas de caracteres. Una cadena es una secuencia de
caracteres. Se coloca entre comillas (simples); ejemplo: 'Hola', 'Juan Perez'. El tipo "varchar"
define una cadena de longitud variable en la cual determinamos el mximo de caracteres
entre parntesis. Puede guardar hasta 8000 caracteres. Por ejemplo, para almacenar
cadenas de hasta 30 caracteres, definimos un campo de tipo varchar(30), es decir, entre
parntesis, junto al nombre del campo colocamos la longitud.
Si asignamos una cadena de caracteres de mayor longitud que la definida, la cadena no se
carga, aparece un mensaje indicando tal situacin y la sentencia no se ejecuta.
Por ejemplo, si definimos un campo de tipo varchar(10) e intentamos asignarle la cadena
'Buenas tardes', aparece un mensaje de error y la sentencia no se ejecuta.
integer: se usa para guardar valores numricos enteros, de -2000000000 a 2000000000 aprox.
Definimos campos de este tipo cuando queremos representar, por ejemplo, cantidades.
float: se usa para almacenar valores numricos con decimales. Se utiliza como separador el
punto (.). Definimos campos de este tipo para precios, por ejemplo.
Antes de crear una tabla debemos pensar en sus campos y optar por el tipo de dato adecuado
para cada uno de ellos.
Por ejemplo, si en un campo almacenaremos nmeros enteros, el tipo "float" sera una mala
eleccin; si vamos a guardar precios, el tipo "float" es ms adecuado, no as "integer" que no
tiene decimales. Otro ejemplo, si en un campo vamos a guardar un nmero telefnico o un
nmero de documento, usamos "varchar", no "integer" porque si bien son dgitos, con ellos no
realizamos operaciones matemticas.
7. Operadores relacionales
Los operadores son smbolos que permiten realizar operaciones matemticas, concatenar
cadenas, hacer comparaciones.
SQL Server tiene 4 tipos de operadores:
1.
2.
3.
4.
relacionales (o de comparacin)
aritmticos
de concatenacin
lgicos.
Igual
Distinto
Mayor
Menor
Mayor o igual
menor o igual
Podemos seleccionar los registros cuyo autor sea diferente de "Borges", para ello usamos la
condicin:
select * from libros
where autor<>'Borges';
Podemos comparar valores numricos. Por ejemplo, queremos mostrar los ttulos y precios de los
libros cuyo precio sea mayor a 20 pesos:
10.Comentarios
Para aclarar algunas instrucciones, en ocasiones, necesitamos agregar comentarios.
Es posible ingresar comentarios en la lnea de comandos, es decir, un texto que no se ejecuta;
para ello se emplean dos guiones (--) al comienzo de la lnea:
select * from libros --mostramos los registros de libros;
En la lnea anterior, todo lo que est luego de los guiones (hacia la derecha) no se ejecuta.
Para agregar varias lneas de comentarios, se coloca una barra seguida de un asterisco (/*) al
comienzo del bloque de comentario y al finalizarlo, un asterisco seguido de una barra (*/).
select titulo, autor
/*mostramos ttulos y
nombres de los autores*/
from libros;
Todo lo que est entre los smbolos "/*" y "*/" no se ejecuta.
12.Clave primaria
Una clave primaria es un campo (o varios) que identifica un solo registro (fila) en una tabla.
Para un valor del campo clave existe solamente un registro.
Veamos un ejemplo, si tenemos una tabla con datos de personas, el nmero de documento puede
establecerse como clave primaria, es un valor que no se repite; puede haber personas con igual
apellido y nombre, incluso el mismo domicilio (padre e hijo por ejemplo), pero su documento
ser siempre distinto.
Si tenemos la tabla "usuarios", el nombre de cada usuario puede establecerse como clave
primaria, es un valor que no se repite; puede haber usuarios con igual clave, pero su nombre de
usuario ser siempre diferente.
Podemos establecer que un campo sea clave primaria al momento de crear la tabla o luego que
ha sido creada. Vamos a aprender a establecerla al crear la tabla. Hay 2 maneras de hacerlo, por
ahora veremos la sintaxis ms sencilla.
Tenemos nuestra tabla "usuarios" definida con 2 campos ("nombre" y "clave").
La sintaxis bsica y general es la siguiente:
create table NOMBRETABLA(
CAMPO TIPO,
...
primary key (NOMBRECAMPO)
);
En el siguiente ejemplo definimos una clave primaria, para nuestra tabla "usuarios" para
asegurarnos que cada usuario tendr un nombre diferente y nico:
create table usuarios(
nombre varchar(20),
clave varchar(10),
primary key(nombre)
);
Lo que hacemos agregar luego de la definicin de cada campo, "primary key" y entre parntesis,
el nombre del campo que ser clave primaria.
Una tabla slo puede tener una clave primaria. Cualquier campo (de cualquier tipo) puede ser
clave primaria, debe cumplir como requisito, que sus valores no se repitan ni sean nulos. Por ello,
al definir un campo como clave primaria, automticamente SQL Server lo convierte a "not null".
Luego de haber establecido un campo como clave primaria, al ingresar los registros, SQL Server
controla que los valores para el campo establecido como clave primaria no estn repetidos en la
15.Truncate table
Aprendimos que para borrar todos los registro de una tabla se usa "delete" sin condicin "where".
Tambin podemos eliminar todos los registros de una tabla con "truncate table".
Por ejemplo, queremos vaciar la tabla "libros", usamos:
truncate table libros;
La sentencia "truncate table" vaca la tabla (elimina todos los registros) y conserva la estructura
de la tabla.
La diferencia con "drop table" es que esta sentencia borra la tabla, "truncate table" la vaca.
La diferencia con "delete" es la velocidad, es ms rpido "truncate table" que "delete" (se nota
cuando la cantidad de registros es muy grande) ya que ste borra los registros uno a uno.
Otra diferencia es la siguiente: cuando la tabla tiene un campo "identity", si borramos todos los
registros con "delete" y luego ingresamos un registro, al cargarse el valor en el campo de
identidad, contina con la secuencia teniendo en cuenta el valor mayor que se haba guardado; si
usamos "truncate table" para borrar todos los registros, al ingresar otra vez un registro, la
secuencia del campo de identidad vuelve a iniciarse en 1.
Por ejemplo, tenemos la tabla "libros" con el campo "codigo" definido "identity", y el valor ms
alto de ese campo es "2", si borramos todos los registros con "delete" y luego ingresamos un
registro, ste guardar el valor de cdigo "3"; si en cambio, vaciamos la tabla con "truncate
table", al ingresar un nuevo registro el valor del cdigo se iniciar en 1 nuevamente.
Si ingresamos un valor numrico (omitiendo las comillas), lo convierte a cadena y lo ingresa como
tal.
Por ejemplo, si en un campo definido como varchar(5) ingresamos el valor 12345, lo toma como si
hubisemos tipeado '12345', igualmente, si ingresamos el valor 23.56, lo convierte a '23.56'. Si el
valor numrico, al ser convertido a cadena supera la longitud definida, aparece un mensaje de
error y la sentencia no se ejecuta.
Es importante elegir el tipo de dato adecuado segn el caso, el ms preciso.
Para almacenar cadenas que varan en su longitud, es decir, no todos los registros tendrn la
misma longitud en un campo determinado, se emplea "varchar" en lugar de "char".
Por ejemplo, en campos que guardamos nombres y apellidos, no todos los nombres y apellidos
tienen la misma longitud.
Para almacenar cadenas que no varan en su longitud, es decir, todos los registros tendrn la
misma longitud en un campo determinado, se emplea "char".
Por ejemplo, definimos un campo "codigo" que constar de 5 caracteres, todos los registros
tendrn un cdigo de 5 caracteres, ni ms ni menos.
Para almacenar valores superiores a 8000 caracteres se debe emplear "text".
Tipo
Bytes de almacenamiento
_______________________________________
varchar(x)
0 a 8K
char(x)
0 a 8K
text
0 a 2GB
nvarchar(x)
nchar(x)
ntext
0 a 8K
0 a 8K
0 a 2GB
smallint: Puede contener hasta 5 dgitos. Su rango va desde 32000 hasta 32000 aprox.
Para almacenar valores numricos EXACTOS con decimales, especificando la cantidad de cifras
a la izquierda y derecha del separador decimal, utilizamos:
2. decimal o numeric (t,d): Pueden tener hasta 38 dgitos, guarda un valor exacto. El
primer argumento indica el total de dgitos y el segundo, la cantidad de decimales.
Por ejemplo, si queremos almacenar valores entre -99.99 y 99.99 debemos definir el
campo como tipo "decimal(4,2)". Si no se indica el valor del segundo argumento, por
defecto es "0". Por ejemplo, si definimos "decimal(4)" se pueden guardar valores entre
-9999 y 9999.
El rango depende de los argumentos, tambin los bytes que ocupa.
Se utiliza el punto como separador de decimales.
Si ingresamos un valor con ms decimales que los permitidos, redondea al ms cercano;
por ejemplo, si definimos "decimal(4,2)" e ingresamos el valor "12.686", guardar "12.69",
redondeando hacia arriba; si ingresamos el valor "12.682", guardar "12.67", redondeando
hacia abajo.
5. money: Puede tener hasta 19 digitos y slo 4 de ellos puede ir luego del separador
decimal; entre 900000000000000.5808 aprox y 900000000000000.5807.
6. smallmoney: Entre 200000.3648 y 200000.3647 aprox.
2 a 17
float
real
4u8
4a8
money
smallmoney
8
4
los
valores
de
tipo
"datetime"
se
muestran
en
formato
"ao-mes-da
Tipo
Bytes de almacenamiento
_______________________________________
datetime
8
smalldatetime 4
la lista de campos debe coincidir en cantidad y tipo de valores con la lista de valores luego
de "values". Si se listan ms (o menos) campos que los valores ingresados, aparece un
mensaje de error y la sentencia no se ejecuta.
si ingresamos valores para todos los campos podemos obviar la lista de campos.
podemos omitir valores para los campos que NO hayan sido declarados "not null", es decir,
que permitan valores nulos (se guardar "null"); si omitimos el valor para un campo "not
null", la sentencia no se ejecuta.
se DEBE omitir el valor para el campo"identity". Salvo que identity_insert est en on.
se pueden omitir valores para campos declarados "not null" siempre que tengan definido un
valor por defecto con la clusula "default" (tema que veremos a continuacin).
Si todos los campos de una tabla tienen valores predeterminados (ya sea por ser "identity",
permitir valores nulos o tener un valor por defecto), se puede ingresar un registro de la siguiente
manera:
insert into libros default values;
La sentencia anterior almacenar un registro con los valores predetermiandos para cada uno de
sus campos.
Entonces, la clusula "default" permite especificar el valor por defecto de un campo. Si no se
explicita, el valor por defecto es "null", siempre que el campo no haya sido declarado "not null".
Los campos para los cuales no se ingresan valores en un "insert" tomarn los valores por defecto:
si est declarado explcitamente "not null", no tiene valor "default" y no tiene el atributo
"identity", no hay valor por defecto, as que causar un error y el "insert" no se ejecutar.
para campos de tipo fecha y hora, si omitimos la parte de la fecha, el valor predeterminado
para la fecha es "1900-01-01" y si omitimos la parte de la hora, "00:00:00".
Un campo slo puede tener un valor por defecto. Una tabla puede tener todos sus campos con
valores por defecto. Que un campo tenga valor por defecto no significa que no admita valores
nulos, puede o no admitirlos.
23.Alias
Una manera de hacer ms comprensible el resultado de una consulta consiste en cambiar los
encabezados de las columnas.
Por ejemplo, tenemos la tabla "agenda" con un campo "nombre" (entre otros) en el cual se
almacena el nombre y apellido de nuestros amigos; queremos que al mostrar la informacin de
dicha tabla aparezca como encabezado del campo "nombre" el texto "nombre y apellido", para
ello colocamos un alias de la siguiente manera:
select nombre as NombreYApellido,
domicilio,telefono
from agenda;
Para reemplazar el nombre de un campo por otro, se coloca la palabra clave "as" seguido del
texto del encabezado.
Si el alias consta de una sola cadena las comillas no son necesarias, pero si contiene ms de una
palabra, es necesario colocarla entre comillas simples:
select nombre as 'Nombre y apellido',
domicilio,telefono
from agenda;
Un alias puede contener hasta 128 caracteres.
Tambin se puede crear un alias para columnas calculadas.
La palabra clave "as" es opcional en algunos casos, pero es conveniente usarla.
Entonces, un "alias" se usa como nombre de un campo o de una expresin. En estos casos, son
opcionales, sirven para hacer ms comprensible el resultado; en otros casos, que veremos ms
adelante, son obligatorios.
24.Funciones
Una funcin es un conjunto de sentencias que operan como una unidad lgica.
Una funcin tiene un nombre, retorna un parmetro de salida y opcionalmente acepta
parmetros de entrada. Las funciones de SQL Server no pueden ser modificadas, las funciones
definidas por el usuario si.
SQL Server ofrece varios tipos de funciones para realizar distintas operaciones. Se pueden
clasificar de la siguiente manera:
1) de agregado: realizan operaciones que combinan varios valores y retornan un nico valor.
Son "count", "sum", "min" y "max".
2) escalares: toman un solo valor y retornan un nico valor. Pueden agruparse de la
siguiente manera:
texto e imagen: realizan operaciones con valor de entrada de tipo text o image y
retornan informacin referente al mismo.
len(cadena): retorna la longitud de la cadena enviada como argumento. "len" viene de length,
que significa longitud en ingls. Ejemplo:
select len('Hola');
devuelve 4.
char(x): retorna un caracter en cdigo ASCII del entero enviado como argumento. Ejemplo:
select char(65);
retorna "A".
ltrim(cadena): retorna la cadena con los espacios de la izquierda eliminados. Trim significa
recortar. Ejemplo:
select ltrim('
Hola
');
Hola
');
replace(cadena,cadenareemplazo,cadenareemplazar):
retorna
la
cadena
con
todas
las
retorna 7.
select patindex('%or%', 'Jorge Luis Borges');
retorna 2.
select patindex('%ar%', 'Jorge Luis Borges');
retorna 0.
space(cantidad): retorna una cadena de espacios de longitud indicada por "cantidad", que debe
ser un valor positivo. Ejemplo:
select 'Hola'+space(1)+'que tal';
retorna "Hola que tal".
Se pueden emplear estas funciones enviando como argumento el nombre de un campo de tipo
carcter.
26.Funciones matemticas
Las funciones matemticas realizan operaciones con expresiones numricas y retornan un
resultado, operan con tipos de datos numricos.
Microsoft SQL Server tiene algunas funciones para trabajar con nmeros. Aqu presentamos
algunas.
select power(2,3);
retorna 8.
select month(getdate());
order by titulo,editorial;
Incluso, podemos ordenar en distintos sentidos, por ejemplo, por "titulo" en sentido ascendente y
"editorial" en sentido descendente:
select *from libros
order by titulo asc, editorial desc;
Debe aclararse al lado de cada campo, pues estas palabras claves afectan al campo
inmediatamente anterior.
Es posible ordenar por un campo que no se lista en la seleccin.
Se permite ordenar por valores calculados o expresiones.
La clusula "order by" no puede emplearse para campos text, ntext e image.
significa y
significa y/o
significa no, invierte el resultado
parntesis
Los registros recuperados en una sentencia en la cual aparece el operador "not", no cumplen con
la condicin a la cual afecta el "NOT".
Los parntesis se usan para encerrar condiciones, para que se evalen como una sola expresin.
Cuando explicitamos varias condiciones con diferentes operadores lgicos (combinamos "and",
"or") permite establecer el orden de prioridad de la evaluacin; adems permite diferenciar las
expresiones ms claramente.
Por ejemplo, las siguientes expresiones devuelven un resultado diferente:
select*from libros
where (autor='Borges') or
(editorial='Paidos' and precio<20);
Note que el smbolo "%" ya no est al comienzo, con esto indicamos que el ttulo debe tener como
primera letra la "M" y luego, cualquier cantidad de caracteres.
Para seleccionar todos los libros que NO comiencen con "M":
select *from libros
where titulo not like 'M%';
As como "%" reemplaza cualquier cantidad de caracteres, el guin bajo "_" reemplaza un
caracter, es otro caracter comodn. Por ejemplo, queremos ver los libros de "Lewis Carroll" pero
no recordamos si se escribe "Carroll" o "Carrolt", entonces tipeamos esta condicin:
select *from libros
where autor like "%Carrol_";
Otro caracter comodn es [] reemplaza cualquier carcter contenido en el conjunto especificado
dentro de los corchetes.
Para seleccionar los libros cuya editorial comienza con las letras entre la "P" y la "S" usamos la
siguiente sintaxis:
select titulo,autor,editorial
from libros
where editorial like '[P-S]%';
Ejemplos:
...
...
...
...
like
like
like
like
Tambin se puede agrupar por ms de un campo, en tal caso, luego del "group by" se listan los
campos, separados por comas. Todos los campos que se especifican en la clusula "group by"
deben estar en la lista de seleccin.
select CAMPO1, CAMPO2, FUNCIONDEAGREGADO
from NOMBRETABLA
group by CAMPO1,CAMPO2;
Para obtener la cantidad libros con precio no nulo, de cada editorial utilizamos la funcin
"count()" envindole como argumento el campo "precio", agregamos "group by" y el campo por el
que deseamos que se realice el agrupamiento (editorial):
select editorial, count(precio)
from libros
group by editorial;
Como resultado aparecen los nombres de las editoriales y la cantidad de registros de cada una,
sin contar los que tienen precio nulo.
Recuerde la diferencia de los valores que retorna la funcin "count()" cuando enviamos como
argumento un asterisco o el nombre de un campo: en el primer caso cuenta todos los registros
incluyendo los que tienen valor nulo, en el segundo, los registros en los cuales el campo
especificado es no nulo.
Para conocer el total en dinero de los libros agrupados por editorial:
select editorial, sum(precio)
from libros
group by editorial;
Para saber el mximo y mnimo valor de los libros agrupados por editorial:
select editorial,
max(precio) as mayor,
min(precio) as menor
from libros
group by editorial;
Para calcular el promedio del valor de los libros agrupados por editorial:
select editorial, avg(precio)
from libros
group by editorial;
Es posible limitar la consulta con "where".
Si incluye una clusula "where", slo se agrupan los registros que cumplen las condiciones.
Vamos a contar y agrupar por editorial considerando solamente los libros cuyo precio sea menor a
30 pesos:
select editorial, count(*)
from libros
where precio<30
group by editorial;
Note que las editoriales que no tienen libros que cumplan la condicin, no aparecen en la salida.
Para que aparezcan todos los valores de editorial, incluso los que devuelven cero o "null" en la
columna de agregado, debemos emplear la palabra clave "all" al lado de "group by":
select editorial, count(*)
from libros
where precio<30
group by all editorial;
Entonces, usamos "group by" para organizar registros en grupos y obtener un resumen de dichos
grupos. SQL Server produce una columna de valores por cada grupo, devolviendo filas por cada
grupo especificado.
selecciona todos los registros, los agrupa para contarlos y finalmente rechaza fila con la cuenta
correspondiente a la editorial "Planeta".
No debemos confundir la clusula "where" con la clusula "having"; la primera establece
condiciones para la seleccin de registros de un "select"; la segunda establece condiciones para la
seleccin de registros de una salida "group by".
Veamos otros ejemplos combinando "where" y "having". Queremos la cantidad de libros, sin
considerar los que tienen precio nulo, agrupados por editorial, sin considerar la editorial
"Planeta":
select editorial, count(*) from libros
where precio is not null
group by editorial
having editorial<>'Planeta';
Aqu, selecciona los registros rechazando los que no cumplan con la condicin dada en "where",
luego los agrupa por "editorial" y finalmente rechaza los grupos que no cumplan con la condicin
dada en el "having".
Se emplea la clusula "having" con funciones de agrupamiento, esto no puede hacerlo la clusula
"where". Por ejemplo queremos el promedio de los precios agrupados por editorial, de aquellas
editoriales que tienen ms de 2 libros:
select editorial, avg(precio) from libros
group by editorial
having count(*) > 2;
En una clusula "having" puede haber hasta 128 condiciones. Cuando utilice varias condiciones,
tiene que combinarlas con operadores lgicos (and, or, not).
Podemos encontrar el mayor valor de los libros agrupados y ordenados por editorial y seleccionar
las filas que tengan un valor menor a 100 y mayor a 30:
select editorial, max(precio) as 'mayor'
from libros
group by editorial
having min(precio)<100 and
min(precio)>30
order by editorial;
Entonces, usamos la clasula "having" para restringir las filas que devuelve una salida "group by".
Va siempre despus de la clusula "group by" y antes de la clusula "order by" si la hubiere.
valor, con la columna correspondiente al segundo campo por el que se agrupa ("sexo" en este
ejemplo) conteniendo "null", y 1 fila extra mostrando el total de todos los visitantes (con las
columnas correspondientes a ambos campos conteniendo "null"). Es decir, por cada agrupacin,
aparece una fila extra con el/ los campos que no se consideran, seteados a "null".
Con "rollup" se puede agrupar hasta por 10 campos.
Es posible incluir varias funciones de agrupamiento, por ejemplo, queremos la cantidad de
visitantes y la suma de sus compras agrupados por ciudad y sexo:
select ciudad,sexo,
count(*) as cantidad,
sum(montocompra) as total
from visitantes
group by ciudad,sexo
with rollup;
Entonces, "rollup" es un modificador para "group by" que agrega filas extras mostrando resultados
de resumen de los subgrupos. Si se agrupa por 2 campos SQL Server genera tantas filas extras
como valores existen del primer campo (con el segundo campo seteado a "null") y una fila extra
con ambos campos conteniendo "null".
Con "rollup" se puede emplear "where" y "having", pero no es compatible con "all".
Si se emplea "cube":
select sexo,estadocivil,seccion,
count(*) from empleados
group by sexo,estadocivil,seccion
with cube;
retorna ms filas extras adems de las anteriores:
-
seteado a "null"),
seteado a "null"),
seteados a "null") y
seteados a "null"),
Es decir, "cube" genera filas de resumen de subgrupos para todas las combinaciones posibles de
los valores de los campos por los que agrupamos.
Se pueden colocar hasta 10 campos en el "group by".
Con "cube" se puede emplear "where" y "having", pero no es compatible con "all".
41.Funcin grouping
La funcin "grouping" se emplea con los operadores "rollup" y "cube" para distinguir los valores de
detalle y de resumen en el resultado. Es decir, permite diferenciar si los valores "null" que
aparecen en el resultado son valores nulos de las tablas o si son una fila generada por los
operadores "rollup" o "cube".
Con esta funcin aparece una nueva columna en la salida, una por cada "grouping"; retorna el
valor 1 para indicar que la fila representa los valores de resumen de "rollup" o "cube" y el valor 0
para representar los valores de campo.
Slo se puede emplear la funcin "grouping" en los campos que aparecen en la clusula "group
by".
Si tenemos una tabla "visitantes" con los siguientes registros almacenados:
Nombre
sexo
----------------------------------Susana Molina
f
Marcela Mercado f
Roberto Perez
f
Alberto Garcia
m
Teresa Garcia
f
ciudad
Cordoba
Cordoba
null
Cordoba
Alta Gracia
y contamos la cantidad agrupando por ciudad (note que hay un valor nulo en dicho campo)
empleando "rollup":
select ciudad,
count(*) as cantidad
from visitantes
group by ciudad
with rollup;
aparece la siguiente salida:
ciudad
cantidad
-------------------------NULL
1
Alta Gracia
1
Cordoba
3
NULL
5
La ltima fila es la de resumen generada por "rollup", pero no es posible distinguirla de la primera
fila, en la cual "null" es un valor del campo. Para diferenciarla empleamos "grouping":
select ciudad,
count(*) as cantidad,
grouping(ciudad) as resumen
from visitantes
group by ciudad
with rollup;
aparece la siguiente salida:
ciudad
cantidad
-----------------------------------NULL
1
Alta Gracia
1
Cordoba
3
NULL
5
resumen
0
0
0
1
La ltima fila contiene en la columna generada por "grouping" el valor 1, indicando que es la fila
de resumen generada por "rollup"; la primera fila, contiene en dicha columna el valor 0, que
indica que el valor "null" es un valor del campo "ciudad".
Entonces, si emplea los operadores "rollup" y "cube" y los campos por los cuales agrupa admiten
valores nulos, utilice la funcin "grouping" para distinguir los valores de detalle y de resumen en
el resultado.
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 clusula "compute by" DEBEN ser idnticos a un subconjunto
de los campos que aparecen despus de "order by" y estar en el mismo orden. Si la clusula "order
by" tiene los siguientes campos:
... order by a,b,c...
la clusula "compute by" puede incluir los siguientes subconjuntos de campos:
Tambin puede utilizarse con "group by" para contar los diferentes autores por editorial:
select editorial, count(distinct autor)
from libros
group by editorial;
La clusula "distinct" afecta a todos los campos presentados. Para mostrar los ttulos y editoriales
de los libros sin repetir ttulos ni editoriales, usamos:
select distinct titulo,editorial
from libros
order by titulo;
Note que los registros no estn duplicados, aparecen ttulos iguales pero con editorial diferente,
cada registro es diferente.
La palabra clave "distinct" no est permitida con las clusulas "compute" y "compute by".
Entonces, "distinct" elimina registros duplicados.
44.Clusula top
La palabra clave "top" se emplea para obtener slo 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:
select top 2 *from libros;
Es decir, luego del "select" se coloca "top" seguido de un nmero entero positivo y luego se
contina con la consulta.
Se puede combinar con "order by":
select top 3 titulo,autor
from libros
order by autor;
En la consulta anterior solicitamos los ttulos y autores de los 3 primeros libros, ordenados por
autor.
Cuando se combina con "order by" es posible emplear tambin la clusula "with ties". Esta
clusula 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
nmero 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 nmero 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 seleccin.
Veamos un ejemplo:
select top 3 with ties
*from libros
order by autor;
Esta consulta solicita el retorno de los primeros 3 registros; en caso que el registro nmero 4 (y
los posteriores), tengan el mismo valor en "autor" que el ltimo registro retornado (nmero 3),
tambin aparecern en la seleccin.
Si colocamos un valor para "top" que supera la cantidad de registros de la tabla, SQL Server
muestra todos los registros.
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 ms de una vez en el
da 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 ningn campo, por si slo cumple con la condicin para ser clave, es decir, debe identificar
un solo registro, el valor no puede repetirse, debemos usar 2 campos.
Definimos una clave compuesta cuando ningn campo por si solo cumple con la condicin para ser
clave.
En este ejemplo, un auto puede ingresar varias veces en un da a la playa, pero siempre ser a
distinta hora.
Usamos 2 campos como clave, la patente junto con la hora de llegada, as identificamos
unvocamente cada registro.
Para establecer ms de un campo como clave primaria usamos la siguiente sintaxis:
create table vehiculos(
patente char(6) not null,
tipo char(1),--'a'=auto, 'm'=moto
horallegada datetime,
horasalida datetime,
primary key(patente,horallegada)
);
Nombramos los campos que formarn 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 estn repetidos en la tabla; si estuviesen repetidos, muestra un mensaje y la
insercin no se realiza. Lo mismo sucede si realizamos una actualizacin.
Entonces, si un solo campo no identifica unvocamente un registro podemos definir una clave
primaria compuesta, es decir formada por ms de un campo.
47.Restriccin default
La restriccin "default" especifica un valor por defecto para un campo cuando no se inserta
explcitamente en un comando "insert".
Anteriormente, para establecer un valor por defecto para un campo emplebamos la clusula
"default" al crear la tabla, por ejemplo:
create table libros(
...
autor varchar(30) default 'Desconocido',
...
);
Cada vez que establecamos un valor por defecto para un campo de una tabla, SQL Server creaba
automticamente una restriccin "default" para ese campo de esa tabla.
Dicha restriccin, a la cual no le dbamos un nombre, reciba un nombre dado por SQL Server que
consiste "DF" (por default), seguido del nombre de la tabla, el nombre del campo y letras y
nmeros aleatorios.
Podemos agregar una restriccin "default" a una tabla existente con la sintaxis bsica siguiente:
alter table NOMBRETABLA
add constraint NOMBRECONSTRAINT
default VALORPORDEFECTO
for CAMPO;
En la sentencia siguiente agregamos una restriccin "default" al campo autor de la tabla existente
"libros", que almacena el valor "Desconocido" en dicho campo si no ingresamos un valor en un
"insert":
alter table libros
add constraint DF_libros_autor
default 'Desconocido'
for autor;
Por convencin, cuando demos el nombre a las restricciones "default" emplearemos un formato
similar al que le da SQL Server: "DF_NOMBRETABLA_NOMBRECAMPO".
Solamente se permite una restriccin "default" por campo y no se puede emplear junto con la
propiedad "identity". Una tabla puede tener varias restricciones "default" para sus distintos
campos.
La restriccin "default" acepta valores tomados de funciones del sistema, por ejemplo, podemos
establecer que el valor por defecto de un campo de tipo datetime sea "getdate()".
Podemos ver informacin referente a las restriciones de una tabla con el procedimiento
almacenado "sp_helpcontraint":
sp_helpconstraint libros;
aparecen varias columnas con la siguiente informacin:
48.Restriccin check
La restriccin "check" especifica los valores que acepta un campo, evitando que se ingresen
valores inapropiados.
La sintaxis bsica es la siguiente:
alter table NOMBRETABLA
add constraint NOMBRECONSTRAINT
check CONDICION;
Trabajamos con la tabla "libros" de una librera 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).
Los campos correspondientes a los precios (minorista y mayorista) se definen de tipo
decimal(5,2), es decir, aceptan valores entre -999.99 y 999.99. Podemos controlar que no se
ingresen valores negativos para dichos campos agregando una restriccin "check":
alter table libros
add constraint CK_libros_precio_positivo
check (preciomin>=0 and preciomay>=0);
Este tipo de restriccin verifica los datos cada vez que se ejecuta una sentencia "insert" o
"update", es decir, acta en inserciones y actualizaciones.
Si la tabla contiene registros que no cumplen con la restriccin que se va a establecer, la
restriccin no se puede establecer, hasta que todos los registros cumplan con dicha restriccin.
La condicin puede hacer referencia a otros campos de la misma tabla. Por ejemplo, podemos
controlar que el precio mayorista no sea mayor al precio minorista:
alter table libros
add constraint CK_libros_preciominmay
check (preciomay<=preciomin);
Por convencin, cuando demos el nombre a las restricciones "check" seguiremos la misma
estructura: comenzamos con "CK", seguido del nombre de la tabla, del campo y alguna palabra
con la cual podamos identificar fcilmente de qu se trata la restriccin, por si tenemos varias
restricciones "check" para el mismo campo.
Un campo puede tener varias restricciones restricciones "check" y una restriccin "check" puede
incluir varios campos.
Las condiciones para restricciones "check" tambin pueden pueden incluir un patrn o una lista de
valores. Por ejemplo establecer que cierto campo conste de 4 caracteres, 2 letras y 2 dgitos:
...
check (CAMPO like '[A-Z][A-Z][0-9][0-9]');
O establecer que cierto campo asuma slo los valores que se listan:
...
check (CAMPO in ('lunes','miercoles','viernes'));
No se puede aplicar esta restriccin junto con la propiedad "identity".
Si un campo permite valores nulos, "null" es un valor aceptado aunque no est incluido en la
condicin de restriccin.
Si intentamos establecer una restriccin "check" para un campo que entra en conflicto con otra
restriccin "check" establecida al mismo campo, SQL Server no lo permite.
Pero si establecemos una restriccin "check" para un campo que entra en conflicto con una
restriccin "default" establecida para el mismo campo, SQL Server lo permite; pero al intentar
ingresar un registro, aparece un mensaje de error.
Si se emplea "check constraint all" no se coloca nombre de restricciones, habilita todas las
restricciones que tiene la tabla nombrada.
Para habilitar o deshabilitar restricciones la comprobacin de datos en inserciones o
actualizaciones, la sintaxis bsica es:
alter table NOMBRETABLA
OPCIONdeRESTRICCION constraint NOMBRERESTRICCION;
Para saber si una restriccin est habilitada o no, podemos ejecutar el procedimiento
almacenado "sp_helpconstraint" y fijarnos lo que informa la columna "status_enabled".
Entonces, las clusulas "check" y "nocheck" permiten habilitar o deshabilitar restricciones "check"
(tambin las restricciones "foreign key" que veremos ms adelante), a las dems se las debe
eliminar ("default" y las que veremos posteriormente).
Sabemos que cuando agregamos una restriccin a una tabla que contiene informacin, SQL Server
controla los datos existentes para confirmar que cumplen las exigencias de la restriccin, si no
los cumple, la restriccin no se aplica y aparece un mensaje de error. Por ejemplo, si intentamos
definir la restriccin "primary key" para "libros" y hay registros con cdigos repetidos o con un
valor "null", la restriccin no se establece.
Cuando establecamos una clave primaria al definir la tabla, automticamente SQL Server
redefina el campo como "not null"; pero al agregar una restriccin "primary key", los campos que
son clave primaria DEBEN haber sido definidos "not null" (o ser implcitamente "not null" si se
definen identity).
SQL Server permite definir solamente una restriccin "primary key" por tabla, que asegura la
unicidad de cada registro de una tabla.
Si ejecutamos el procedimiento almacenado "sp_helpconstraint" junto al nombre de la tabla,
podemos ver las restricciones "primary key" (y todos los tipos de restricciones) de dicha tabla.
Un campo con una restriccin "primary key" puede tener una restriccin "check".
Un campo "primary key" tambin acepta una restriccin "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.
51.Restriccin unique
Hemos visto que las restricciones aplicadas a tablas aseguran valores nicos para cada registro.
Anteriormente aprendimos la restriccin "primary key", otra restriccin para las tablas es
"unique".
La restriccin "unique" impide la duplicacin de claves alternas (no primarias), es decir,
especifica que dos registros no puedan tener el mismo valor en un campo. Se permiten valores
nulos. Se pueden aplicar varias restricciones de este tipo a una misma tabla, y pueden aplicarse a
uno o varios campos que no sean clave primaria.
Se emplea cuando ya se estableci una clave primaria (como un nmero de legajo) pero se
necesita asegurar que otros datos tambin sean nicos y no se repitan (como nmero de
documento).
La sintaxis general es la siguiente:
alter table NOMBRETABLA
add constraint NOMBRERESTRICCION
unique (CAMPO);
Ejemplo:
alter table alumnos
add constraint UQ_alumnos_documento
unique (documento);
En el ejemplo anterior se agrega una restriccin "unique" sobre el campo "documento" de la tabla
"alumnos", esto asegura que no se pueda ingresar un documento si ya existe. Esta restriccin
permite valores nulos, asi que si se ingresa el valor "null" para el campo "documento", se acepta.
Por convencin, cuando demos el nombre a las restricciones "unique" seguiremos la misma
estructura: "UQ_NOMBRETABLA_NOMBRECAMPO". Quiz parezca innecesario colocar el nombre de
la tabla, pero cuando empleemos varias tablas ver que es til identificar las restricciones por
tipo, tabla y campo.
Recuerde que cuando agregamos una restriccin a una tabla que contiene informacin, SQL
Server controla los datos existentes para confirmar que cumplen la condicin de la restriccin, si
no los cumple, la restriccin no se aplica y aparece un mensaje de error. En el caso del ejemplo
anterior, si la tabla contiene nmeros de documento duplicados, la restriccin no podr
establecerse; si podr establecerse si tiene valores nulos.
SQL Server controla la entrada de datos en inserciones y actualizaciones evitando que se ingresen
valores duplicados.
delete_action: solamente es aplicable para restricciones de tipo "foreign key" (la veremos
posteriormente).
update_action: slo es aplicable para restricciones de tipo "foreign key" (la veremos
posteriormente).
status_enabled: solamente es aplicable para restricciones de tipo "check" y "foreign key". Indica
si est habilitada (Enabled) o no (Disabled). Indica "n/a" en cualquier restriccin para la que
no se aplique.
DE LOS CAMPOS (hace referencia a los valores vlidos para un campo determinado).
Pueden ser:
a) DEFAULT: especifica un valor por defecto para un campo cuando no se inserta
explcitamente en un comando "insert".
b) CHECK: especifica un rango de valores que acepta un campo, se emplea en
inserciones y actualizaciones ("insert" y "update").
II) DE LA TABLA (asegura un identificador nico para cada registro de una tabla). Hay 2
tipos:
a) PRIMARY KEY: identifica unvocamente cada uno de los registros; asegura que no
haya valores duplicados ni valores nulos. Se crea un ndice automticamente.
b) UNIQUE: impide la duplicacin de claves alternas (no primarias). Se permiten
valores nulos. Se crea un ndice automticamente.
III) REFERENCIAL: lo veremos ms adelante.
2. REGLAS (rules) y
3. VALORES PREDETERMINADOS (defaults).
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 condicin.
Por convencin, nombraremos las reglas comenzando con "RG", el nombre del campo al que se
asocia y alguna palabra que haga referencia a la condicin.
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.
La condicin se refiere a los valores permitidos para inserciones y actualizaciones y puede
contener cualquier expresin vlida para una clusula "where"; no puede hacer referencia a los
campos de una tabla.
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:
create rule RG_sueldo_intervalo
as @sueldo between 100 and 1000
Luego de crear la regla, debemos asociarla a un campo ejecutando un procedimiento almacenado
del sistema empleando la siguiente sintaxis bsica:
exec sp_bindrule NOMBREREGLA, 'TABLA.CAMPO';
Asociamos la regla creada anteriormente al campo "sueldo" de la tabla "empleados":
exec sp_bindrule RG_sueldo_intervalo, 'empleados.sueldo';
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 insercin (o actualizacin) 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
instruccin "insert" o "update" muestra un mensaje de error, es decir, acta 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 instruccin "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 asociacin anterior; pero la primera regla no desaparece, solamente se deshace la asociacin.
La sentencia "create rule" no puede combinarse con otras sentencias en un lote.
La funcin que cumple una regla es bsicamente la misma que una restriccin "check", las
siguientes caractersticas explican algunas diferencias entre ellas:
podemos definir varias restricciones "check" sobre un campo, un campo solamente puede
tener una regla asociada a l;
una restriccin "check" se almacena con la tabla, cuando sta se elimina, las restricciones
tambin 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 restriccin "check" puede incluir varios campos; una regla puede asociarse a distintos
campos (incluso de distintas tablas);
una restriccin "check" puede hacer referencia a otros campos de la misma tabla, una regla
no.
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".
No es posible eliminar una regla si est asociada a un campo. Si intentamos hacerlo, aparece un
mensaje de error y la eliminacin no se realiza.
Con la instruccin "drop rule" eliminamos la regla:
drop rule NOMBREREGLA;
Quitamos la asociacin de la regla "RG_sueldo_intervalo" con el campo "sueldo" de la tabla
"empleados" tipeando:
exec sp_unbindrule 'empleados.sueldo';
Luego de quitar la asociacin la eliminamos:
drop rule RG_sueldo_100a1000;
Si eliminamos una tabla, las asociaciones de reglas de sus campos desaparecen, pero las reglas
siguen existiendo.
constraint_type: indica que es una regla con "RULE", nombrando el campo al que est asociada.
La funcin que cumple un valor predeterminado es bsicamente la misma que una restriccin
"default", las siguientes caractersticas explican algunas semejanzas y diferencias entre ellas:
un campo solamente puede tener definida UNA restriccin "default", un campo solamente puede
tener UN valor predeterminado asociado a l,
una restriccin "default" se almacena con la tabla, cuando sta se elimina, las restricciones
tambin. Los valores predeterminados son objetos diferentes e independientes de las tablas,
si eliminamos una tabla, las asociaciones desaparecen, pero los valores predeterminados
siguen existiendo en la base de datos.
una restriccin "default" se establece para un solo campo; un valor predeterminado puede
asociarse a distintos campos (inclusive, de diferentes tablas).
una restriccin "default" no puede establecerse sobre un campo "identity", tampoco un valor
predeterminado.
No se puede asociar un valor predeterminado a un campo que tiene una restriccin "default".
Un campo con un valor predeterminado asociado 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.
La sentencia "create default" no puede combinarse con otra sentencia en un mismo lote.
Si asocia a un campo que ya tiene asociado un valor predeterminado otro valor predeterminado,
la nueva asociacin reemplaza a la anterior.
Veamos otros ejemplos.
Creamos un valor predeterminado que inserta el valor "0" en un campo de tipo numrico:
create default VP_cero
as 0;
En el siguiente creamos un valor predeterminado que inserta ceros con el formato vlido para un
nmero de telfono:
create default VP_telefono
as '(0000)0-000000';
Con "sp_helpconstraint" podemos ver los valores predeterminados asociados a los campos de una
tabla.
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".
60.Indices
SQL Server accede a los datos de dos maneras:
1. recorriendo las tablas; comenzando el principio y extrayendo los
registros que cumplen las condiciones de la consulta.
2. empleando ndices; recorriendo la estructura de rbol del ndice para
localizar los registros y extrayendo los que cumplen las condiciones de la
consulta.
Los ndices se emplean para facilitar la obtencin de informacin de una tabla.
El indice de una tabla desempea la misma funcin que el ndice de un libro:
permite encontrar datos rpidamente; en el caso de las tablas, localiza
registros.
Una tabla se indexa por un campo (o varios).
Un ndice posibilita el acceso directo y rpido haciendo ms eficiente las
bsquedas. Sin ndice, SQL Server debe recorrer secuencialmente toda la tabla
para encontrar un registro.
El objetivo de un indice es acelerar la recuperacin de informacin. La
indexacin es una tcnica que optimiza el acceso a los datos, mejora el
rendimiento acelerando las consultas y otras operaciones. Es til cuando la
tabla contiene miles de registros, cuando se realizan operaciones de
ordenamiento y agrupamiento y cuando se combinan varias tablas (tema que
veremos ms adelante).
La desventaja es que consume espacio en el disco en disco y genera costo de
mantenimiento (tiempo y recursos).
Los ndices ms adecuados son aquellos creados con campos que contienen
valores nicos.
Es importante identificar el o los campos por los que sera til crear un ndice,
aquellos campos por los cuales se realizan bsqueda 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.
SQL Server permite crear dos tipos de ndices: 1) agrupados y 2) no agrupados.
62.Creacin de ndices
Para crear ndices empleamos la instruccin "create index".
La sintaxis bsica es la siguiente:
create TIPODEINDICE index NOMBREINDICE
on TABLA(CAMPO);
"TIPODEINDICE" indica si es agrupado (clustered) o no agrupado (nonclustered). Si no
especificamos crea uno No agrupado. Independientemente de si es agrupado o no, tambin se
puede especificar que sea "unique", es decir, no haya valores repetidos. Si se intenta crear un
ndice unique para un campo que tiene valores duplicados, SQL Server no lo permite.
En este ejemplo se crea un ndice agrupado nico para el campo "codigo" de la tabla "libros":
create unique clustered index I_libros_codigo
on libros(codigo);
Para identificar los ndices fcilmente, podemos agregar un prefijo al nombre del ndice, por
ejemplo "I" y luego el nombre de la tabla y/o campo.
En este ejemplo se crea un ndice no agrupado para el campo "titulo" de la tabla "libros":
create nonclustered index I_libros_titulo
on libros(titulo);
Un ndice puede tener ms de un campo como clave, son ndices compuestos. Los campos de un
ndice compuesto tienen que ser de la misma tabla (excepto cuando se crea en una vista - tema
que veremos posteriormente).
Creamos un ndice compuesto para el campo "autor" y "editorial":
create index I_libros_autoreditorial
on libros(autor,editorial);
SQL Server crea automticamente ndices cuando se establece una restriccin "primary key" o
"unique" en una tabla. Al crear una restriccin "primary key", si no se especifica, el ndice ser
agrupado (clustered) a menos que ya exista un ndice agrupado para dicha tabla. Al crear una
restriccin "unique", si no se especifica, el ndice ser no agrupado (non-clustered).
Ahora podemos entender el resultado del procedimiento almacenado "sp_helpconstraint" cuando
en la columna "constraint_type" mostraba el tipo de ndice seguido de las palabras "clustered" o
"non_clustered".
Puede especificarse que un ndice sea agrupado o no agrupado al agregar estas restricciones.
Agregamos una restriccin "primary key" al campo "codigo" de la tabla "libros" especificando que
cree un ndice NO agrupado:
alter table libros
add constraint PK_libros_codigo
primary key nonclustered (codigo);
Para ver los indices de una tabla:
sp_helpindex libros;
Muestra el nombre del ndice, si es agrupado (o no), primary (o unique) y el campo por el cual se
indexa.
Todos los ndices de la base de datos activa se almacenan en la tabla del sistema "sysindexes",
podemos consultar dicha tabla tipeando:
select name from sysindexes;
Para ver todos los ndices de la base de datos activa creados por nosotros podemos tipear la
siguiente consulta:
select name from sysindexes
where name like 'I_%';
63.Regenerar ndices
Vimos que para crear ndices empleamos la instruccin "create index".
Empleando la opcin "drop_existing" junto con "create index" permite regenerar un ndice, con
ello evitamos eliminarlo y volver a crearlo. La sintaxis es la siguiente:
create TIPODEINDICE index NOMBREINDICE
on TABLA(CAMPO)
with drop_existing;
Tambin podemos modificar alguna de las caractersticas de un ndice con esta opcin, a saber:
tipo: cambindolo de no agrupado a agrupado (siempre que no exista uno agrupado para la misma
tabla). No se puede convertir un ndice agrupado en No agrupado.
campo: se puede cambiar el campo por el cual se indexa, agregar campos, eliminar algn campo
de un ndice compuesto.
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":
create nonclustered index I_libros
on libros(titulo);
Regeneramos el ndice "I_libros" y lo convertimos a agrupado:
create clustered index I_libros
on libros(titulo)
with drop_existing;
Agregamos un campo al ndice "I_libros":
create clustered index I_libros
on libros(titulo,editorial)
with drop_existing;
Esta opcin no puede emplearse con ndices creados a partir de una restriccin "primary key" o
"unique".
64.Eliminar ndices
Los ndices creados con "create index" se eliminan con "drop index"; la siguiente es la sintaxis
bsica:
drop index NOMBRETABLA.NOMBREINDICE;
Eliminamos el ndice "I_libros_titulo":
drop index libros.I_libros_titulo;
Los ndices que SQL Server crea automticamente al establecer una restriccin "primary key" o
"unique" no pueden eliminarse con "drop index", se eliminan automticamente cuando quitamos
la restriccin.
Podemos averiguar si existe un ndice para eliminarlo, consultando la tabla del sistema
"sysindexes":
if exists (select name from sysindexes
where name = 'NOMBREINDICE')
drop index NOMBRETABLA.NOMBREINDICE;
Eliminamos el ndice "I_libros_titulo" si existe:
if exists (select *from sysindexes
where name = 'I_libros_titulo')
drop index libros.I_libros_titulo;
Veamos un ejemplo:
select *from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo;
Resumiendo: si distribuimos la informacin en varias tablas evitamos la redundancia de datos y
ocupamos menos espacio fsico en el disco. Un join es una operacin que relaciona dos o ms
tablas para obtener un resultado que incluya datos (campos y registros) de ambas; las tablas
participantes se combinan segn los campos comunes a ambas tablas.
Hay hay tres tipos de combinaciones. En los siguientes captulos explicamos cada una de ellas.
combinamos esa tabla con "join" y el nombre de la otra tabla ("editoriales"); se especifica
qu tablas se van a combinar y cmo;
"on" hace coincidir registros de ambas tablas basndose en el valor de tal campo, en el
ejemplo, el campo "codigoeditorial" de "libros" y el campo "codigo" de "editoriales" son los
que enlazarn ambas tablas. Se emplean campos comunes, que deben tener tipos de datos
iguales o similares.
La condicion de combinacin, es decir, el o los campos por los que se van a combinar (parte "on"),
se especifica segn las claves primarias y externas.
Note que en la consulta, al nombrar el campo usamos el nombre de la tabla tambin. Cuando las
tablas referenciadas tienen campos con igual nombre, esto es necesario para evitar confusiones y
ambiguedades al momento de referenciar un campo. En el ejemplo, si no especificamos
"editoriales.codigo" y solamente tipeamos "codigo", SQL Server no sabr si nos referimos al campo
"codigo" de "libros" o de "editoriales" y mostrar un mensaje de error indicando que "codigo" es
ambiguo.
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 clusula "on"
se debe hacer referencia a la clave completa, es decir, la condicin referenciar a todos los
campos clave que identifican al registro.
Se puede incluir en la consulta join la clusula "where" para restringir los registros que retorna el
resultado; tambin "order by", "distinct", etc..
Se emplea este tipo de combinacin para encontrar registros de la primera tabla que se
correspondan con los registros de la otra, es decir, que cumplan la condicin del "on". Si un valor
de la primera tabla no se encuentra en la segunda tabla, el registro no aparece.
Para simplificar la sentencia podemos usar un alias para cada tabla:
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 simplificacin y hace
ms legible la consulta si es larga y compleja, pero en algunas consultas es absolutamente
necesario.
select CAMPOS
from TABLAIZQUIERDA
left join TABLADERECHA
on CONDICION;
En el siguiente ejemplo solicitamos el ttulo y el nombre la editorial, la sentencia es similar a la
anterior, la diferencia est en el orden de las tablas:
select titulo,nombre
from libros as l
left join editoriales as e
on codigoeditorial = e.codigo;
El resultado mostrar el ttulo del libro y el nombre de la editorial; los ttulos cuyo cdigo 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 cdigo 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;
Tambin podemos mostrar las editoriales que NO estn 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;
on CONDICION;
Un "right join" tambin puede tener clusula "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;
Mostramos las editoriales que NO estn presentes en "libros", es decir, que NO encuentran
coincidencia en la tabla de la derecha empleando un "right join":
select titulo,nombre
from libros as l
rightjoin editoriales as e
on e.codigo=codigoeditorial
where codigoeditorial is null;
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 condicin de enlace. Se genera
el producto cartesiano en el que el nmero de filas del resultado es igual al nmero de registros
de la primera tabla multiplicado por el nmero de registros de la segunda tabla, es decir, si hay 5
registros en una tabla y 6 en la otra, retorna 30 filas.
La sintaxis bsica es sta:
select CAMPOS
from TABLA1
cross join TABLA2;
Veamos un ejemplo. Un pequeo restaurante almacena los nombres y precios de sus comidas en
una tabla llamada "comidas" y en una tabla denominada "postres" los mismos datos de sus postres.
Si necesitamos conocer todas las combinaciones posibles para un men, cada comida con cada
postre, empleamos un "cross join":
select c.nombre as 'plato principal', p.nombre as 'postre'
from comidas as c
cross join postres as p;
La salida muestra cada plato combinado con cada uno de los postres.
Como cualquier tipo de "join", puede emplearse una clusula "where" que condicione la salida.
71.Autocombinacin
Dijimos que es posible combinar una tabla consigo misma.
Un pequeo 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 combinacin de platos empleando un "cross join" con una sola tabla:
select c1.nombre as 'plato principal',
c2.nombre as postre,
c1.precio+c2.precio as total
from comidas as c1
cross join comidas as c2;
En la consulta anterior aparecen filas duplicadas, para evitarlo debemos emplear un "where":
select c1.nombre as 'plato principal',
c2.nombre as postre,
c1.precio+c2.precio as total
from comidas as c1
cross join comidas as c2
where c1.rubro='plato' and
c2.rubro='postre';
En la consulta anterior se emple un "where" que especifica que se combine "plato" con "postre".
En una autocombinacin 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".
Tambin se puede realizar una autocombinacin con "join":
select c1.nombre as 'plato principal',
c2.nombre as postre,
c1.precio+c2.precio as total
from comidas as c1
join comidas as c2
on c1.codigo<>c2.codigo
where c1.rubro='plato' and
c2.rubro='postre';
Para que no aparezcan filas duplicadas se agrega un "where".
En consultas en las cuales empleamos varios "join" es importante tener en cuenta el orden de las
tablas y los tipos de "join"; recuerde que la tabla resultado del primer join es la que se combina
con el segundo join, no la segunda tabla nombrada. En el ejemplo anterior, el "left join" no se
realiza entre las tablas "libros" y "editoriales" sino entre el resultado del "right join" y la tabla
"editoriales".
75.Clave fornea
Un campo que no es clave primaria en una tabla y sirve para enlazar sus valores con otra tabla en
la cual es clave primaria se denomina clave fornea, externa o ajena.
En el ejemplo de la librera en que utilizamos las tablas "libros" y "editoriales" con estos campos:
libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio y
editoriales: codigo (clave primaria), nombre.
el campo "codigoeditorial" de "libros" es una clave fornea, se emplea para enlazar la tabla
"libros" con "editoriales" y es clave primaria en "editoriales" con el nombre "codigo".
Las claves forneas y las claves primarias deben ser del mismo tipo para poder enlazarse. Si
modificamos una, debemos modificar la otra para que los valores se correspondan.
Cuando alteramos una tabla, debemos tener cuidado con las claves forneas. Si modificamos el
tipo, longitud o atributos de una clave fornea, sta puede quedar inhabilitada para hacer los
enlaces.
Entonces, una clave fornea es un campo (o varios) empleados para enlazar datos de 2 tablas,
para establecer un "join" con otra tabla en la cual es clave primaria.
Para agregar una restriccin "foreign key" al campo "codigoeditorial" de "libros", tipeamos:
"no action": indica que si intentamos eliminar o actualizar un valor de la clave primaria de la
tabla referenciada (TABLA2) que tengan referencia en la tabla principal (TABLA1), se genere
un error y la accin no se realice; es la opcin predeterminada.
Veamos un ejemplo. Definimos una restriccin "foreign key" a la tabla "libros" estableciendo el
campo "codigoeditorial" como clave fornea que referencia al campo "codigo" de la tabla
"editoriales". La tabla "editoriales" tiene como clave primaria el campo "codigo". Especificamos la
accin en cascada para las actualizaciones y eliminaciones:
alter table libros
add constraint FK_libros_codigoeditorial
foreign key (codigoeditorial)
references editoriales(codigo)
on update cascade
on delete cascade;
Si luego de establecer la restriccin anterior, eliminamos una editorial de "editoriales" de las
cuales hay libros, se elimina dicha editorial y todos los libros de tal editorial. Y si modificamos el
valor de cdigo de una editorial de "editoriales", se modifica en "editoriales" y todos los valores
iguales de "codigoeditorial" de libros tambin se modifican.
Para habilitar una restriccin deshabilitada se ejecuta la misma instruccin pero con la clusula
"check" o "check all":
alter table libros
check constraint FK_libros_codigoeditorial;
Si se emplea "check constraint all" no se coloca nombre de restricciones, habilita todas las
restricciones que tiene la tabla nombrada ("check" y "foreign key").
Para saber si una restriccin est habilitada o no, podemos ejecutar el procedimiento
almacenado "sp_helpconstraint" y entenderemos lo que informa la columna "status_enabled".
Entonces, las clusulas "check" y "nocheck" permiten habilitar o deshabilitar restricciones "foreign
key" (y "check"). Pueden emplearse para evitar la comprobacin de datos existentes al crear la
restriccin o para deshabilitar la comprobacin de datos al ingresar, actualizar y eliminar algn
registro que infrinja la restriccin.
Podemos eliminar una restriccin "foreign key" con "alter table". La sintaxis bsica es la misma
que para cualquier otra restriccin:
alter table TABLA
drop constraint NOMBRERESTRICCION;
Eliminamos la restriccin de "libros":
alter table libros
drop constraint FK_libros_codigoeditorial;
No se puede eliminar una tabla si una restriccin "foreign key" hace referencia a ella.
Cuando eliminamos una tabla que tiene una restriccin "foreign key", la restriccin tambin se
elimina.
update_action: slo es aplicable para restricciones de tipo "foreign key". Indica si la accin
de actualizacin es: No Action, Cascade, or n/a. Indica "n/a" en cualquier restriccin para la
que no se aplique.
una restriccin "primary key" con ndice agrupado para el campo "codigo" (a nivel de tabla);
una restriccin "unique" con ndice no agrupado (por defecto) para los campos "titulo" y
"codigoautor" (a nivel de tabla);
una restriccin "foreign key" para establecer el campo "codigoeditorial" como clave externa
que haga referencia al campo "codigo" de "editoriales y permita actualizaciones en cascada y
no eliminaciones (por defecto "no action");
una restriccin "foreign key" para establecer el campo "codigoautor" como clave externa que
haga referencia al campo "codigo" de "autores" y permita actualizaciones en cascada y no
eliminaciones;
una restriccin "check" para el campo "precio" que no admita valores negativos;
Si definimos una restriccin "foreign key" al crear una tabla, la tabla referenciada debe existir.
82.Unin
El operador "union" combina el resultado de dos o ms instrucciones "select" en un nico
resultado.
Se usa cuando los datos que se quieren obtener pertenecen a distintas tablas y no se puede
acceder a ellos con una sola consulta.
Es necesario que las tablas referenciadas tengan tipos de datos similares, la misma cantidad de
campos y el mismo orden de campos en la lista de seleccin de cada consulta. No se incluyen las
filas duplicadas en el resultado, a menos que coloque la opcin "all".
Se deben especificar los nombres de los campos en la primera instruccin "select".
Puede emplear la clusula "order by".
Puede dividir una consulta compleja en varias consultas "select" y luego emplear el operador
"union" para combinarlas.
Una academia de enseanza almacena los datos de los alumnos en una tabla llamada "alumnos" y
los datos de los profesores en otra denominada "profesores".
La academia necesita el nombre y domicilio de profesores y alumnos para enviarles una tarjeta
de invitacin.
Para obtener los datos necesarios de ambas tablas en una sola consulta necesitamos realizar una
unin:
select nombre, domicilio from alumnos
union
select nombre, domicilio from profesores;
El primer "select" devuelve el nombre y domicilio de todos los alumnos; el segundo, el nombre y
domicilio de todos los profesores.
Los encabezados del resultado de una unin son los que se especifican en el primer "select".
campos que son parte de ndices o tienen restricciones, a menos que el cambio no afecte al
ndice o a la restriccin, por ejemplo, se puede ampliar la longitud de un campo de tipo
caracter.
campos que afecten a los datos existentes cuando una tabla contiene registros (ejemplo: un
campo contiene valores nulos y se pretende redefinirlo como "not null"; un campo int guarda
un valor 300 y se pretende modificarlo a tinyint, etc.).
86.Campos calculados
Un campo calculado es un campo que no se almacena fsicamente en la tabla. SQL Server emplea
una frmula que detalla el usuario al definir dicho campo para calcular el valor segn otros
campos de la misma tabla.
Un campo calculado no puede:
insertarse ni actualizarse.
Puede ser empleado como llave de un ndice o parte de restricciones "primary key" o "unique" si
la expresin que la define no cambia en cada consulta.
Creamos un campo calculado denominado "sueldototal" que suma al sueldo bsico de cada
empleado la cantidad abonada por los hijos (100 por cada hijo):
create table empleados(
documento char(8),
nombre varchar(10),
domicilio varchar(30),
sueldobasico decimal(6,2),
cantidadhijos tinyint default 0,
sueldototal as sueldobasico + (cantidadhijos*100)
);
Tambin se puede agregar un campo calculado a una tabla existente:
alter table NOMBRETABLA
add NOMBRECAMPOCALCULADO as EXPRESION;
alter table empleados
add sueldototal as sueldo+(cantidadhijos*100);
Los campos de los cuales depende el campo calculado no pueden eliminarse, se debe eliminar
primero el campo calculado.
Creamos un tipo de datos definido por el usuario llamado "tipo_documento" que admite valores
nulos:
exec sp_addtype tipo_documento, 'char(8)', 'null';
Ejecutando el procedimiento almacenado "sp_help" junto al nombre del tipo de dato definido por
el usuario se obtiene informacin del mismo (nombre, el tipo de dato en que se basa, la longitud,
si acepta valores nulos, si tiene valor por defecto y reglas asociadas).
Tambin podemos consultar la tabla "systypes" en la cual se almacena informacin de todos los
tipos de datos:
select name from systypes;
almacenado
91.Subconsultas
Una subconsulta (subquery) es una sentencia "select" anidada en otra sentencia "select", "insert",
"update" o "delete" (o en otra subconsulta).
Las subconsultas se emplean cuando una consulta es muy compleja, entonces se la divide en
varios pasos lgicos y se obtiene el resultado con una nica instruccin y cuando la consulta
depende de los resultados de otra consulta.
Generalmente, una subconsulta se puede reemplazar por combinaciones y estas ltimas son ms
eficientes.
Las subconsultas se DEBEN incluir entre parntesis.
Puede haber subconsultas dentro de subconsultas, se admiten hasta 32 niveles de anidacin.
Se pueden emplear subconsultas:
en lugar de una expresin, siempre que devuelvan un solo valor o una lista de valores.
que retornen un conjunto de registros de varios campos en lugar de una tabla o para obtener
el mismo resultado que una combinacin (join).
si el "where" de la consulta exterior incluye un campo, este debe ser compatible con el
campo en la lista de seleccin de la subconsulta.
las subconsultas luego de un operador de comparacin (que no es seguido por "any" o "all")
no pueden incluir clusulas "group by" ni "having".
una subconsulta puede estar anidada dentro del "where" o "having" de una consulta externa o
dentro de otra subconsulta.
93.Subconsultas con in
Vimos que una subconsulta puede reemplazar una expresin. Dicha subconsulta debe devolver un
valor escalar o una lista de valores de un campo; las subconsultas que retornan una lista de
valores reemplazan a una expresin en una clusula "where" que contiene la palabra clave "in".
El resultado de una subconsulta con "in" (o "not in") es una lista. Luego que la subconsulta retorna
resultados, la consulta exterior los usa.
La sintaxis bsica es la siguiente:
...where EXPRESION in (SUBCONSULTA);
Este ejemplo muestra los nombres de las editoriales que ha publicado libros de un determinado
autor:
select nombre
from editoriales
where codigo in
(select codigoeditorial
from libros
where autor='Richard Bach');
La subconsulta (consulta interna) retorna una lista de valores de un solo campo (codigo) que la
consulta exterior luego emplea al recuperar los datos.
Podemos reemplazar por un "join" la consulta anterior:
select distinct nombre
select distinct nombre
from editoriales as e
join libros
on codigoeditorial=e.codigo
where autor='Richard Bach';
Una combinacin (join) siempre puede ser expresada como una subconsulta; pero una
subconsulta no siempre puede reemplazarse por una combinacin que retorne el mismo
resultado. Si es posible, es aconsejable emplear combinaciones en lugar de subconsultas, son ms
eficientes.
Se recomienda probar las subconsultas antes de incluirlas en una consulta exterior, as puede
verificar que retorna lo necesario, porque a veces resulta difcil verlo en consultas anidadas.
Tambin podemos buscar valores No coincidentes con una lista de valores que retorna una
subconsulta; por ejemplo, las editoriales que no han publicado libros de un autor especfico:
select nombre
from editoriales
where codigo not in
(select codigoeditorial
from libros
where autor='Richard Bach');
95.Subconsultas correlacionadas
Un almacn almacena la informacin de sus ventas en una tabla llamada "facturas" en la cual
guarda el nmero de factura, la fecha y el nombre del cliente y una tabla denominada "detalles"
en la cual se almacenan los distintos items correspondientes a cada factura: el nombre del
artculo, el precio (unitario) y la cantidad.
Se necesita una lista de todas las facturas que incluya el nmero, la fecha, el cliente, la cantidad
de artculos comprados y el total:
select f.*,
(select count(d.numeroitem)
from Detalles as d
where f.numero=d.numerofactura) as cantidad,
(select sum(d.preciounitario*cantidad)
from Detalles as d
where f.numero=d.numerofactura) as total
from facturas as f;
El segundo "select" retorna una lista de valores de una sola columna con la cantidad de items por
factura (el nmero de factura lo toma del "select" exterior); el tercer "select" retorna una lista de
valores de una sola columna con el total por factura (el nmero de factura lo toma del "select"
exterior); el primer "select" (externo) devuelve todos los datos de cada factura.
A este tipo de subconsulta se la denomina consulta correlacionada. La consulta interna se evala
tantas veces como registros tiene la consulta externa, se realiza la subconsulta para cada registro
de la consulta externa. El campo de la tabla dentro de la subconsulta (f.numero) se compara con
el campo de la tabla externa.
En este caso, especficamente, la consulta externa pasa un valor de "numero" a la consulta
interna. La consulta interna toma ese valor y determina si existe en "detalles", si existe, la
consulta interna devuelve la suma. El proceso se repite para el registro de la consulta externa, la
consulta externa pasa otro "numero" a la consulta interna y SQL Server repite la evaluacin.
96.Exists y No Exists
Los operadores "exists" y "not exists" se emplean para determinar si hay o no datos en una lista de
valores.
Estos operadores pueden emplearse con subconsultas correlacionadas para restringir el resultado
de una consulta exterior a los registros que cumplen la subconsulta (consulta interior). Estos
operadores retornan "true" (si las subconsultas retornan registros) o "false" (si las subconsultas no
retornan registros).
Cuando se coloca en una subconsulta el operador "exists", SQL Server analiza si hay datos que
coinciden con la subconsulta, no se devuelve ningn registro, es como un test de existencia; SQL
Server termina la recuperacin de registros cuando por lo menos un registro cumple la condicin
"where" de la subconsulta.
La sintaxis bsica es la siguiente:
... where exists (SUBCONSULTA);
En este ejemplo se usa una subconsulta correlacionada con un operador "exists" en la clusula
"where" para devolver una lista de clientes que compraron el artculo "lapiz":
select cliente,numero
from facturas as f
where exists
(select *from Detalles as d
where f.numero=d.numerofactura
and d.articulo='lapiz');
Puede obtener el mismo resultado empleando una combinacin.
Podemos buscar los clientes que no han adquirido el artculo "lapiz" empleando "if not exists":
select cliente,numero
from facturas as f
where not exists
(select *from Detalles as d
where f.numero=d.numerofactura
and d.articulo='lapiz');
Por cada valor de l1, se evala la subconsulta, si el precio es mayor que el promedio.