Apunte de SQL
Apunte de SQL
2 - show databases
Una base de datos es un conjunto de tablas.
Para que el servidor nos muestre las bases de datos existentes, se lo solicitamos
enviando la instrucción:
show databases;
Nos mostrará los nombres de las bases de datos, debe aparecer en este sitio
"administracion".
1
3 - Creación de una tabla y mostrar sus campos (create table - show tables -
describe - drop table)
Una tabla es una estructura de datos que organiza los datos en columnas y filas;
cada columna es un campo (o atributo) y cada fila, un registro. La intersección de
una columna con una fila, contiene un dato específico, un solo valor.
Cada campo (columna) debe tener un nombre. El nombre del campo hace
referencia a la información que almacenará.
Cada campo (columna) también debe definir el tipo de dato que almacenará.
Nombre clave
MarioPerez Marito
MariaGarcia Mary
DiegoRodriguez z8080
show tables;
Deben aparecer todas las tablas que han creado los visitantes al sitio
mysqlya.com.ar
Al crear una tabla debemos resolver qué campos (columnas) tendrá y que tipo de
datos almacenarán cada uno de ellos, es decir, su estructura.
La tabla debe ser definida con un nombre que la identifique y con el cual
accederemos a ella.
2
Creamos una tabla llamada "usuarios", tipeamos:
Si intentamos crear una tabla con un nombre ya existente (existe otra tabla con
ese nombre), mostrará un mensaje de error indicando que la acción no se realizó
porque ya existe una tabla con el mismo nombre.
Para ver las tablas existentes en una base de datos tipeamos nuevamente:
show tables;
Cuando se crea una tabla debemos indicar su nombre y definir sus campos 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 ver la estructura de una tabla usamos el comando "describe" junto al nombre
de la tabla:
describe usuarios;
Aparece lo siguiente:
3
Para eliminar una tabla usamos "drop table". Tipeamos:
Si tipeamos nuevamente:
Ejemplo:
Crear la tabla usuarios con los campos nombre y clave. Previamente borrar la
tabla usuarios si ya existe en el servidor. Finalmente mostrar la estructura de la
tabla usuarios que acabamos de crear.
Problemas:
I)
2- Cree una tabla llamada "agenda", debe tener los siguientes campos:
nombre varchar(20), domicilio varchar(30) y teléfono varchar(11)
4
telefono varchar(11)
);
II)
5
Al ingresar los datos de cada registro debe tenerse en cuenta la cantidad y el
orden de los campos.
Ahora vamos a agregar un registro a la tabla:
Usamos "insert into". Especificamos los nombres de los campos entre paréntesis y
separados por comas y luego los valores para cada campo, también entre
paréntesis y separados por comas.
Nombre clave
MarioPerez Marito
Aparece un registro.
El comando "select" recupera los registros de una tabla. Luego del comando select
indicamos los nombres de los campos a rescatar.
Ejemplo
Insertar tres registros en la tabla usuarios y luego mostrar todos los registros de la
tabla.
Primeramente eliminamos la tabla, si existe:
Creamos la tabla:
6
Insertamos 3 registros:
Problema:
2- Cree una tabla llamada "agenda". Debe tener los siguientes campos:
nombre (cadena de 20), domicilio (cadena de 30) y teléfono (cadena de 11).
7
4- Visualice la estructura de la tabla "agenda". (describe).
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 números enteros, el tipo "float" sería una mala elección; si vamos
8
a guardar precios, el tipo "float" es correcto, no así "integer" que no tiene
decimales.
Ejemplo :
Al crear la tabla, entonces, elegimos el tipo de dato más adecuado para cada
campo:
describe libros;
9
Es una forma resumida de indicar que seleccione todos los campos de la tabla.
Problema:
10
insert into peliculas (nombre, actor, duracion, cantidad)
values ('Elsa y Fred','China Zorrilla',90,2);
El comando "select" recupera los registros de una tabla. Con el asterisco (*)
indicamos que seleccione todos los campos de la tabla que nombramos.
Ejemplo
Trabajamos con la tabla "libros" que almacena los datos de los libros de una
librería.
11
cantidad integer
);
describe libros;
Ingresamos algunos registros:
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('El aleph','Borges','Emece',45.50,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('Alicia en el pais de las maravillas','Lewis Carroll','Planeta',25,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('Matematica estas ahi','Paenza','Planeta',15.8,200);
Con el asterisco (*) indicamos que seleccione todos los campos de la tabla.
Para ver solamente el título, autor y editorial de todos los libros especificamos los
nombres de los campos separados por comas:
La siguiente sentencia nos mostrará los títulos y precios de todos los libros:
12
select titulo,precio from libros;
select editorial,cantidad from libros;
Problema:
2- Cree la tabla:
describe peliculas;
13
7 - Recuperación de registros específicos (select - where)
El comando "select" recupera los registros de una tabla. Detallando los nombres
de los campos separados por comas, indicamos que seleccione todos los campos
de la tabla que nombramos.
Existe una cláusula, "where" que es opcional, con ella podemos especificar
condiciones para la consulta "select". Es decir, podemos recuperar algunos
registros, sólo los que cumplan con ciertas condiciones indicadas con la cláusula
"where". Por ejemplo, queremos ver el usuario cuyo nombre es "MarioPerez", para
ello utilizamos "where" y luego de ella, la condición:
Ejemplo:
Creamos la tabla:
describe usuarios;
14
insert into usuarios (nombre, clave) values ('Leonardo','payaso');
insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','bocajunior');
insert into usuarios (nombre, clave) values ('Gustavo','bocajunior');
describe usuarios;
15
Problema:
Otros problemas:
16
'El aleph','Borges','Planeta';
'Martin Fierro','Jose Hernandez','Emece';
'Aprenda PHP','Mario Molina','Emece';
'Cervantes','Borges','Paidos';
5- Seleccione todos los datos de los registros cuyo nombre sea "impresora".
17
8 - Operadores Relacionales = <> < <= > >=
Hemos aprendido a especificar condiciones de igualdad para seleccionar registros
de una tabla; por ejemplo:
Los operadores relacionales vinculan un campo con un valor para que MySQL
compare cada registro (el campo especificado) con el valor dado.
= igual
<> distinto
> mayor
< menor
>= mayor o igual
<= menor o igual
Podemos seleccionar los registros cuyo autor sea diferente de 'Borges', para ello
usamos la condición:
Podemos comparar valores numéricos. Por ejemplo, queremos mostrar los libros
cuyos precios sean mayores a 20 pesos:
Ejemplo:
18
La creamos con la siguiente estructura:
Note que al ingresar valores numéricos (en este caso float) no se utilizan comillas
y para el separador de decimales se usa el punto(.).
Note que al comparar valores numéricos (en este caso de tipo float) no se utilizan
comillas.
19
drop table if exists libros;
Problema:
20
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (4,'teclado','ingles Biswal',100,50);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (5,'teclado','español Biswal',90,50);
Otros problemas:
21
insert into peliculas (titulo, actor, duracion, cantidad)
values ('Mujer bonita','Julia R.',90,3);
insert into peliculas (titulo, actor, duracion, cantidad)
values ('Elsa y Fred','China Zorrilla',90,2);
6- Seleccione todas las películas en las que el actor no sea 'Tom Cruise':
select * from peliculas
where actor<>'Tom Cruise';
B) Trabaje con la tabla "agenda" en la que registra los datos de sus amigos.
2- Cree la tabla, con los siguientes campos: apellido (cadena de 30), nombre
(cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11).
22
9 - Borrado de registros de una tabla (delete)
La ejecución del comando indicado en la línea anterior borra TODOS los registros
de la tabla.
Si queremos eliminar uno o varios registros debemos indicar cuál o cuáles, para
ello utilizamos el comando "delete" junto con la clausula "where" con la cual
establecemos la condición que deben cumplir los registros a borrar. Por ejemplo,
queremos eliminar aquel registro cuyo nombre de usuario es 'Leonardo':
Ejemplo:
Creamos la tabla:
23
delete from usuarios where nombre='Leonardo';
24
Problema:
Trabaje con la tabla "agenda" que registra la información referente a sus amigos.
2- Cree la tabla con los siguientes campos: apellido (cadena de 30), nombre
(cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11).
Mores,Alberto,Colon 123,4234567,
Torres,Juan,Avellaneda 135,4458787,
Lopez,Mariana,Urquiza 333,4545454,
Lopez,Jose,Urquiza 333,4545454,
Peralta,Susana,Gral. Paz 1234,4123456.
Otros problemas:
1- Elimine la tabla.
El aleph,Borges,Planeta,15.00;
Martin Fierro,Jose Hernandez,Emece,25.50;
25
Aprenda PHP,Mario Molina,Emece,26.80;
Cervantes y el quijote,Borges,Paidos,45.50;
Matematica estas ahi, Paenza, Paidos,50.00;
6- Elimine los registros cuyo autor sea igual a 'Paenza'. (1 registro eliminado)
7- Nuevamente, elimine los registros cuyo autor sea igual a 'Paenza'. (ningún
registro afectado)
9- Borre los registros que cuyo precio sea mayor o igual a 40 pesos.
26
6- Elimine los artículos cuyo precio sea mayor o igual a 500.
Por ejemplo, en nuestra tabla "usuarios", queremos cambiar los valores de todas
las claves, por "RealMadrid":
27
Para ello colocamos "update", el nombre de la tabla, "set" junto al nombre del
campo y el nuevo valor y separado por coma, el otro nombre del campo con su
nuevo valor.
Ejemplo:
Creamos la tabla:
Para actualizar los valores de todas las claves, por 'RealMadrid' tipeamos:
Verificamos el cambio:
28
Cambiamos el valor correspondiente al nombre de usuario 'Gustavo' por
'GustavoGarcia':
Problema:
Trabaje con la tabla "agenda" que almacena los datos de sus amigos.
2- Cree la tabla:
create table agenda(
apellido varchar(30),
nombre varchar(20),
domicilio varchar(30),
29
telefono varchar(11)
);
5- Modifique el registro cuyo nombre sea "Juan" por "Juan Jose"(update- where):
update agenda set nombre='Juan Jose'
where nombre='Juan';
6- Actualice los registros cuyo número telefónico sea igual a '4545454' por
'4445566':
update agenda set telefono='4445566'
where telefono='4545454';
7- Actualice los registros que tengan en el campo "nombre" el valor "Juan" por
"Juan Jose" (ningún registro afectado porque ninguno cumple con la condición
del "where"):
update agenda set nombre='Juan Jose'
where nombre='Juan';
Otros problemas:
1- Elimine la tabla.
30
5- Muestre todos los registros.
6- Modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza".
(1 registro afectado)
9- Actualice el valor del campo "editorial" por "Emece S.A.", para todos los
registros cuya editorial sea igual a "Emece".
5- Actualice el precio a "400" del artículo cuya descripción sea "Epson Stylus C45":
update articulos set precio=400
where descripcion='Epson Stylus C45';
31
6- Actualice la cantidad a 100 de todas los teclados:
update articulos set cantidad=100
where nombre='teclado';
11 - Clave primaria.
Una clave primaria es un campo (o varios) que identifica 1 solo registro (fila) en
una tabla.
Para un valor del campo clave existe solamente 1 registro. Los valores no se
repiten ni pueden ser nulos.
Para definir un campo como clave primaria agregamos "primary key" luego de la
definición de todos los campos y entre paréntesis colocamos el nombre del campo
que queremos como clave.
32
Si visualizamos la estructura de la tabla con "describe" vemos que el campo
"nombre" es clave primaria y no acepta valores nulos(más adelante explicaremos
esto detalladamente).
Una tabla sólo puede tener una clave primaria. Cualquier campo (de cualquier
tipo) puede ser clave primaria, debe cumplir como requisito, que sus valores no se
repitan.
Eljemplo:
Creamos la tabla:
33
Vemos la estructura de la tabla:
describe usuarios;
Note que en la columna "KEY" del campo "nombre" aparece "PRI", esto significa
que ese campo es clave primaria.
describe usuarios;
Problema:
34
create table libros(
codigo integer,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key(codigo)
);
Otros problemas:
A) Una empresa almacena los datos de sus clientes en una tabla llamada
"clientes".
35
4- Ingrese los siguientes registros:
insert into clientes (documento,apellido,nombre,domicilio, telefono)
values('22345678','Perez','Marcos','Colon 123','4545454');
insert into clientes (documento,apellido,nombre,domicilio, telefono)
values('23222222','Garcia','Ana','Avellaneda 1345','4252652');
insert into clientes (documento,apellido,nombre,domicilio, telefono)
values('20454545','Lopez','Susana','Urquiza 344','4522525');
insert into clientes (documento,apellido,nombre,domicilio, telefono)
values('35454545','Lopez','Susana','Urquiza 344','4522525');
Note que hay 2 registros con todos los datos iguales excepto el documento.
36
4- Seleccione todos los registros.
Sólo puede haber un campo "auto_increment" y debe ser clave primaria (o estar
indexado).
37
insert into libros (titulo,autor,editorial)
values('El aleph','Borges','Planeta');
Para que este atributo funcione correctamente, el campo debe contener solamente
valores positivos; más adelante trataremos este tema.
Problema:
38
codigo integer auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);
describe libros;
Note que al detallar los campos para los cuales ingresaremos valores hemos
omitido "codigo"; cuando un campo es "auto_increment" no es necesario ingresar
valor para él, porque se genera automáticamente. Recuerde que si es obligatorio
ingresar los datos de todos los campos que se detallan y en el mismo orden.
39
Vemos que el código, dato que no ingresamos, se cargó automáticamente
siguiendo la secuencia de autoincremento.
El siguiente registro insertado tomará el valor más alto para seguir la secuencia
(en este caso 16):
40
drop table if exists libros;
describe libros;
41
Problema:
42
Otros problemas:
8- Elimine todas las películas cuya duración sea igual a 120 minutos.
43
12- Intente ingresar un registro con valor de clave repetida.
También podemos eliminar todos los registros de una tabla con "truncate table".
Por ejemplo, queremos vaciar la tabla "libros", usamos:
La sentencia "truncate table" vacía la tabla (elimina todos los registros) y vuelve a
crear la tabla con la misma estructura.
La diferencia con "drop table" es que esta sentencia borra la tabla, "truncate table"
la vacía.
44
Ejemplo:
Creamos la tabla:
Veamos el resultado:
45
Veamos el resultado:
Para el campo "codigo" se guardó el valor 6 porque el valor más alto de ese
campo, antes de eliminar todos los registros era "5".
Veamos qué sucede si ingresamos otro registro sin valor para el código:
Ejecutamos entonces:
46
Problema:
5- Ingrese 2 registros:
insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Sertal','Roche',5.2,100);
insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Amoxidal 500','Bayer',15.60,100);
6- Vea los registros para verificar que continuó la secuencia al generar el valor
para "codigo":
select * from medicamentos;
7- Vacíe la tabla:
truncate table medicamentos;
47
9- Vea los registros para verificar que al cargar el código reinició la secuencia en
1.
Otros problemas:
7- Vea los registros para verificar que al generar el valor para "codigo" continuó la
secuencia:
select *from peliculas;
48
values('Elsa y Fred','China Zorrilla',90);
14 - Valores null.
La tercera columna "Key", muestra los campos que son clave primaria; en el
campo "codigo" aparece "PRI" (es clave primaria) y los otros están vacíos, porque
no son clave primaria.
La cuarta columna "Default", muestra los valores por defecto, esto es, los valores
que MySQL ingresa cuando omitimos un dato o colocamos un valor inválido; para
todos los campos, excepto para el que es clave primaria, el valor por defecto es
"null".
49
nulos. Por ejemplo, en nuestra tabla de libros, podemos tener valores nulos en el
campo "precio" porque es posible que para algunos libros no le hayamos
establecido el precio para la venta.
Imaginemos que ingresamos los datos de un libro, para el cual aún no hemos
definido el precio:
Los campos establecidos como clave primaria no aceptan valores nulos. Nuestro
campo clave primaria, está definido "auto_increment"; si intentamos ingresar el
valor "null" para este campo, no lo tomará y seguirá la secuencia de incremento.
El campo "titulo", no debería aceptar valores nulos, para establecer este atributo
debemos crear la tabla con la siguiente sentencia:
Explicamos que "null" no es lo mismo que una cadena vacía o un valor 0 (cero).
Para recuperar los registros que contengan el valor "null" en el campo "precio" no
podemos utilizar los operadores relacionales vistos anteriormente: = (igual) y <>
50
(distinto); debemos utilizar los operadores "is null" (es igual a null) y "is not null"
(no es null):
Con la primera sentencia veremos los libros cuyo precio es igual a "null"
(desconocido); con la segunda, los libros cuyo precio es 0.
Con la primera sentencia veremos los libros cuya editorial es igual a "null", con la
segunda, los libros cuya editorial guarda una cadena vacía.
Ejemplo:
51
Field Type Null Key Default Extra
__________________________________________________________
codigo int(11) 7 b.. NO PRI (NULL) auto_increment
titulo varchar(20) 11 b.. NO
autor varchar(30) 11 b.. YES (NULL)
editorial varchar(15) 11 b.. YES (NULL)
precio float 5 b.. YES (NULL)
Vemos que el campo "codigo" y el campo "titulo" no permiten valores nulos. Y que
el campo "codigo" es clave primaria y "auto_increment". Los demás campos
permiten valores nulos.
ingresamos "null" para el precio, campo que permite valores nulos. Note que el
valor "null" no se coloca entre comillas porque no es una cadena de caracteres.
Si intentamos ingresar el valor "null" para el campo "codigo", que es clave primaria
y "auto_increment", no lo tomará y seguirá la secuencia de incremento:
Podemos ingresar valores nulos en los campos que lo permiten, por ejemplo, en
"editorial":
Ingresemos otros valores que nos servirán luego para verificar que los valores
"null" son diferentes de 0 y de cadenas vacías.
52
Para recuperar los registros que contengan el valor "null" en el campo "precio"
tipeamos:
Con la primera sentencia recuperamos los libros cuya editorial es "null"; con la
segunda, los libros cuya editorial guarda una cadena vacía.
53
Problema:
7- Recupere los registros que contengan valor "null" en el campo "precio", luego
los que tengan el valor 0 en el mismo campo. Note que el resultado es diferente:
select * from medicamentos where precio is null;
select * from medicamentos where precio=0;
54
8- Intente ingresar el siguiente registro con valor "null" para el campo "nombre":
insert into medicamentos (nombre, laboratorio,precio,cantidad)
values(null,'Bayer',10.20,100);
Aparece un mensaje de error.
8- Intente ingresar el siguiente registro con valor "null" para el campo "cantidad":
insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Benadryl comprimidos','Bayer',10.20,null);
Aparece un mensaje de error.
10- Recupere los registros cuyo precio sea distinto de 0, luego los que
sean distintos de "null":
select * from medicamentos where precio<>0;
select * from medicamentos where precio is not null;
Note que la salida de la primera sentencia no muestra los registros con valor 0 y
tampoco los que tienen valor nulo; el resultado de la segunda sentencia muestra
los registros con valor para el campo precio (incluso el valor 0). Esto es porque los
valores "null" no pueden compararse con operadores relacionales.
11- Recupere los registros en los cuales el laboratorio no contenga una cadena
vacía, luego los que sean distintos de "null":
select * from medicamentos where laboratorio<>'';
select * from medicamentos where laboratorio is not null;
Note que la primera sentencia solicita los registros que no tengan cadena vacía,
es decir, los que guardan una cadena, como "null" no es una cadena, no retorna
los registros con valor nulo.
El resultado de la segunda sentencia solicita que no muestre los valores nulos, es
decir, que muestre cualquier cadena, incluso vacía.
Otros problemas:
Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".
1- Elimine la tabla.
55
-titulo (cadena de 30, not null),
-actor (cadena de 20),
-duracion (entero),
-clave primaria (codigo).
5- Recupere todos los registros para verificar la carga automática de los códigos.
Verifique que acepta el registro pero pasa por alto el dato ingresado para el código
colocando en su lugar el valor siguiente de la secuencia.
7- Intente ingresar un registro con valor nulo para el campo "titulo". Verifique que
no realiza la acción.
8- Ingrese un registro con valor nulo para los campos "actor" y "duracion":
insert into peliculas (titulo,actor,duracion)
values('Mr. Johns',null,null);
Verifique que el registro ha sido ingresado.
9- Ingrese un registro con cadenas vacías para los campos varchar y valor 0 para
los campos numéricos:
insert into peliculas (codigo,titulo,actor,duracion)
values(0,'','',0);
Visualice el registro para ver cómo almacenó MySQL el registro ingresado
anteriormente.
10- Coloque 120 en la duración de la película cuyo valor de duración sea nulo (1
registro actualizado):
56
update peliculas set duracion=120 where duracion is null;
11- Coloque 'Desconocido' en el campo "actor" en los registros que tengan valor
nulo en dicho campo (1 registro afectado):
update peliculas set actor='Desconocido'
where actor is null;
12- Muestre todos los registros. Note que el cambio anterior no afectó al registro
con valor nulo en el campo "actor".
13- Coloque 'Desconocido' en el campo "actor" en los registros que tengan cadena
vacía en dicho campo (1 registro afectado):
update peliculas set actor='Desconocido'
where actor='';
14- Elimine los registros cuyo título sea una cadena vacía:
delete from peliculas
where titulo='';
Los campos de cualquier tipo aceptan el atributo "null" y "not null" con lo cual
permiten o no valores nulos.
57
Hemos aprendido que al crear una tabla, es importante elegir el tipo de dato
adecuado, el más preciso, según el caso. Si un campo almacenará sólo valores
positivos, es útil definir dicho campo con este atributo.
En los tipos enteros, "unsigned" duplica el rango, es decir, el tipo "integer" permite
valores de -2000000000 a 2000000000 aprox., si se define "integer unsigned" el
rango va de 0 a 4000000000 aprox.
Los tipos de coma flotante (float por ejemplo) también aceptan el atributo
"unsigned", pero el valor del límite superior del rango se mantiene.
Ejemplo:
Field Type
____________________________
codigo int(10) unsigned
titulo varchar(20)
autor varchar(30)
editorial varchar(15)
precio float unsigned
cantidad int(10) unsigned
58
Para almacenar el código de los libros, definimos un campo de tipo "integer
unsigned" porque guardaremos valores a partir de 1 en adelante (no valores
negativos).
Para almacenar el precio de los libros, definimos un campo de tipo "float unsigned"
porque jamás guardaremos un valor negativo.
Problema:
3- Cree la tabla y defina cada campo según el rango de valores que almacenará:
create table peliculas(
codigo integer unsigned auto_increment,
titulo varchar(40) not null,
actor varchar(20),
duracion integer unsigned,
primary key(codigo)
);
59
Otros problemas:
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.
2- Cree la tabla y al definir los campos tenga en cuenta el rango de valores que
almacenará cada campo:
- nombre: cadena de 30 caracteres,
- edad: entero positivo. No hay edades con valores negativos.
- sexo: 'f' o 'm',
- domicilio: cadena de 30,
- ciudad: cadena de 30,
- teléfono: cadena de 11,
- monto compra: valor con decimales mayor o igual a cero. No hay compras con
monto negativo.
16 - Tipos de datos
Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto
es, definir los campos y sus tipos más precisos, según el caso. Por ejemplo, si un
campo numérico almacenará solamente valores enteros positivos el tipo "integer"
con el atributo "unsigned" es más adecuado que, por ejemplo un "float".
Hasta ahora hemos visto 3 tipos de datos: varchar, integer (con y sin signo) y float
(con y sin signo). Hay más tipos, incluso, subtipos.
C) FECHAS Y HORAS: para guardar fechas y horas dispone de varios tipos: date
(fecha), datetime (fecha y hora), time (hora), year (año) y timestamp.
60
D) OTROS TIPOS: enum y set representan una enumeración y un conjunto
respectivamente. Lo veremos más adelante.
E) Otro valor que podemos almacenar es el valor "null". El valor 'null' significa
“valor desconocido” o "dato inexistente", ya lo estudiamos. No es lo mismo que 0 o
una cadena vacía.
Hasta ahora hemos visto 3 tipos de datos: varchar, integer (con y sin signo) y float
(con y sin signo). Hay más tipos, incluso, subtipos.
Para los tipos que almacenan cadenas, si asignamos una cadena de caracteres
de mayor longitud que la permitida o definida, la cadena se corta. Por ejemplo, si
61
definimos un campo de tipo varchar(10) y le asignamos la cadena 'Buenas tardes',
se almacenará 'Buenas tar' ajustándose a la longitud de 10.
Es importante elegir el tipo de dato adecuado según el caso, el más preciso. Por
ejemplo, si vamos a almacenar un caracter, conviene usar char(1), que ocupa 1
byte y no varchar(1), que ocupa 2 bytes.
Ejemplo :
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.
Note que definimos el campo "sexo" de tipo "char", porque necesitamos solamente
1 caracter "f" o "m", que siempre será fijo, con esta definición ocupamos un byte.
describe visitantes
62
18 - Tipos de datos (numéricos)
Hasta ahora hemos visto 2 tipos de datos para almacenar valores numéricos:
integer (con y sin signo) y float (con y sin signo). Existe variedad de tipos
numéricos para representar enteros, negativos, decimales.
Para almacenar valores enteros, por ejemplo, en campos que hacen referencia a
cantidades, precios, etc., usamos: 1) integer(x) o int(x): su rango es de -
2000000000 a 2000000000 aprox. El tipo "int unsigned" va de 0 a 4000000000. El
tipo "integer" tiene subtipos:
- tinyint(x): define un valor entero pequeño, cuyo rango es de -128 a 127. El tipo
sin signo va de 0 a 255.
Todos los tipos enteros pueden tener el atributo "unsigned", esto permite sólo
valores positivos y duplica el rango. Los tipos de coma flotante también aceptan el
atributo "unsigned", pero el valor del límite superior del rango no se modifica.
Es importante elegir el tipo de dato adecuado según el caso, el más preciso. Por
ejemplo, si un campo numérico almacenará valores positivos menores a 10000, el
tipo "int" no es el más adecuado, porque su rango va de -2000000000 a
2000000000 aprox., conviene el tipo "smallint unsigned", cuyo rango va de 0 a
63
60000 aprox. De esta manera usamos el menor espacio de almacenamiento
posible.
float 4
decimal(t,d) t+2 si d>0, t+1 si d=0 y d+2 si t<d
Ejemplo:
64
drop table if exists libros;
describe libros;
Problema:
Otros problemas:
65
Ciudad País Temp Maxima Temp.Min Precipitacion Anual
Bs. As. Argentina 30 8 1200
Canberra Australia 28 0 620
Brasilia Brasil 27 13 1500
Madrid España 31 2 400
Mexico Mexico 23 7 850
Moscu Rusia 24 -13 690
Oslo Noruega 28 -16 750
Ottawa Canadá 26 -16 900
Santiago Chile 29 3 300
Viena Austria 25 -4 600
2- Cree la tabla eligiendo el tipo de dato adecuado para almacenar los datos
descriptos arriba:
- ciudad y país: cadena de caracteres,
- temperaturas (máxima y mínima): entero desde -20 hasta 40 aprox.
- precipitaciones media anual: desde 0 a 2000 aprox.
2- Cree la tabla eligiendo el tipo de dato adecuado para almacenar los datos
descriptos arriba:
- Gas: cadena,
- Temperatura Crítica: valores decimales desde -300 hasta 400 aprox.,
- Presión Crítica: valores decimales positivos hasta 300 aprox.
C) Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".
66
La tabla contiene estos datos:
Si ingresamos los valores como cadenas, un valor entre "00" y "69" es convertido
a valores "year" en el rango de 2000 a 2069; si el valor está entre "70" y "99", se
convierten a valores "year" en el rango 1970 a 1999.
Para almacenar valores de tipo fecha se permiten como separadores "/", "-" y ".".
67
Si ingresamos '2006-2-1' (mes y día de 1 dígito), lo toma como '2006-02-01'.
Es importante elegir el tipo de dato adecuado según el caso, el más preciso. Por
ejemplo, si sólo necesitamos registrar un año (sin día ni mes), el tipo adecuado es
"year" y no "date".
Ejemplo:
Una playa de estacionamiento guarda cada día los datos de los vehículos que
ingresan a la playa en una tabla llamada "vehiculos".
68
horasalida time
);
Note que no ingresamos los segundos y colocó por defecto "00" para ellos.
69
insert into vehiculos values('HTR234','auto','2006-12-15 12:15',null);
almacena "00:00:15".
Problema:
Una concesionaria de autos vende autos usados. Guarda los siguientes datos en
la tabla "autos":
- marca (fiat 128, renault 11, peugeot 505, etc.)
- modelo (año)
- dueño (nombre del dueño)
- precio (valor con decimales positivo que puede llegar hasta 999999.99 aprox.).
2- Cree la tabla eligiendo el tipo de dato adecuado para almacenar estos datos:
create table autos(
marca varchar(15),
modelo year,
dueño varchar(30),
precio decimal (8,2) unsigned
);
70
3- Ingrese los siguientes registros:
insert into autos values('Fiat 128','1970','Juan Lopez',50000);
insert into autos values('Renault 11','1990','Juan Lopez',80000);
insert into autos values('Fiat 128','1971','Ana Ferreyra',51000);
insert into autos values('Peugeot 505','1998','Luis Luque',99000);
insert into autos values('Peugeot 505','1997','Carola Perez',85000);
Otros problemas:
Una empresa almacena los datos de sus empleados en una tabla "empleados".
71
4- Seleccione todos los datos de los empleados que ingresaron a la empresa
antes del 2000:
select * from empleados
where fechaingreso<'2000';
72
20 - Valores por defecto.
Hemos visto los valores por defecto de los distintos tipos de datos. Ahora que
conocemos más tipos de datos, vamos a ampliar la información referente a ellos y
a repasar los conocidos.
Para campos de cualquier tipo no declarados "not null" el valor por defecto es
"null" (excepto para tipos "timestamp" que no trataremos aquí).
Para campos declarados "not null", el valor por defecto depende del tipo de dato.
Para cadenas de caracteres el valor por defecto es una cadena vacía. Para
valores numéricos el valor por defecto es 0; en caso de ser "auto_increment" es el
valor mayor existente+1 comenzando en 1. Para campos de tipo fecha y hora, el
valor por defecto es 0 (por ejemplo, en un campo "date" es "0000-00-00").
Para todos los tipos, excepto "blob", "text" y "auto_increment" se pueden explicitar
valores por defecto con la cláusula "default"; tema que veremos más adelante.
Los campos para los cuales no se ingresaron valores tomarán los valores por
defecto según el tipo de dato del campo, en el campo "codigo" ingresará el
siguiente valor de la secuencia porque es "auto_increment"; en el campo "titulo",
ingresará una cadena vacía porque es "varchar not null"; en el campo "editorial"
almacenará "null", porque no está definido "not null"; en el campo "precio"
guardará "null" porque es el valor por defecto de los campos no definidos como
"not null" y en el campo "cantidad" ingresará 0 porque es el valor por defecto de
los campos numéricos que no admiten valores nulos.
Ejemplo:
73
drop table if exists libros;
74
insert into libros (autor,editorial,cantidad)
values('Borges','Planeta',100);
Problema:
Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".
3- Agregue los siguientes registros para ver cómo guarda MySQL los valores no
ingresados:
insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (codigo,duracion)
values(5,90);
insert into peliculas (titulo,actor)
('Harry Potter y la piedra filosofal','Daniel R.');
insert into peliculas (titulo,actor,duracion)
('Harry Potter y la piedra filosofal','Daniel R.',120);
4- Seleccione todos los datos de las películas para ver cómo guardó MySQL los
valores no ingresados. En el primer registro ingresado, en el campo "codigo"
ingresará "1", el primer valor para campos "auto_increment". En el segundo
registro ingresado se almacena una cadena vacía para el título y el valor "null"
para el actor. En el tercer registro guarda "6" en "codigo", el siguiente valor de la
secuencia tomando el valor más alto y en "duracion" almacena "0". En el
cuarto registro sigue la secuencia del código.
Otros problemas:
Una empresa almacena los datos de sus empleados en una tabla "empleados".
75
2- Cree la tabla:
create table empleados(
nombre varchar(20),
documento char(8) not null,
sexo char(1),
domicilio varchar(30),
fechaingreso date not null,
fechanacimiento date,
sueldo decimal(5,2) unsigned not null
);
3- Agregue los siguientes registros para ver cómo guarda MySQL los valores no
ingresados:
insert into empleados (nombre,documento,sexo)
values('Marcela Medina','22333444','f');
insert into empleados (domicilio,fechaingreso)
values('Avellaneda 200','2005-08-16');
insert into empleados (fechanacimiento,sueldo)
values('1970-09-26',500.90);
4- Seleccione todos los datos de los empleados para ver cómo guardó MySQL los
valores no ingresados.
En el primer registro ingresado, en los campos "domicilio" y "fechanacimiento"
ingresará "null",
porque ninguno de los campos están definidos como "not null"; en el campo
"fechaingreso"
almacena "000-00-00" ya que dicho campo no admite valores nulos; en el campo
"sueldo" guarda "0.00"
porque el campo no admite valores nulos. En el segundo registro ingresado se
almacena "null" en los
campos "nombre", "sexo" y "fechanacimiento" pues estos campos admiten valores
"null"; en el
campo "documento", que no admite valores nulos, se almacena una cadena vacía.
En el tercer registro
guarda "null" en los campos "nombre", "sexo" y "domicilio", ya que los permiten; en
el
campo "documento", almacena una cadena vacía.
76
21 - Valores inválidos.
Hemos visto los valores por defecto de los distintos tipos de datos.
Un valor por defecto se inserta cuando no está presente al ingresar un registro y
en algunos casos en que el dato ingresado es inválido.
Un valor es inválido por tener un tipo de dato incorrecto para el campo o por estar
fuera de rango.
- Pasa por alto los valores fuera del rango, 0 en caso de no ser "unsigned" y todos
los menores a 1 en caso de ser "unsigned".
77
- Si ingresamos un valor fuera de rango continúa la secuencia.
-valor "null": si un campo está definido "not null" e intentamos ingresar "null",
aparece un mensaje de error y la sentencia no se ejecuta.
Los valores inválidos para otros tipos de campos lo trataremos más adelante.
RESUMEN:
78
Ejemplo:
79
Ingresemos otro registro:
Como cargamos en el campo "precio" (decimal 5,2) un valor con más decimales
que los permitidos, el valor es redondeado al más cercano (33.57).
Intentamos ingresar el valor 0 para el código, lo pasa por alto y sigue la secuencia.
Lo mismo sucede si ingresamos un valor negativo.
Si intentamos ingresar "null" para el código, lo pasa por alto y sigue la secuencia.
Otro ejemplo:
Otro ejemplo:
insert into libros (titulo,autor,cantidad)
values ('Antologia poetica','Borges',null);
80
drop table if exists libros;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
cantidad mediumint unsigned not null,
primary key(codigo)
);
insert into libros (titulo,autor,editorial,precio)
values ('Alicia en el pais de las maravillas',555,'Planeta',23.45);
select * from libros;
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('Matematica estas ahi','Paenza','Planeta','abc',20000000);
select * from libros;
insert into libros (titulo,editorial,precio)
values ('Alegoria','Planeta',3333.50);
select * from libros;
insert into libros (titulo,editorial,precio)
values ('Alegoria','Planeta',33.567);
select * from libros;
insert into libros (codigo,titulo)
values (2,'El gato con botas');
select * from libros;
insert into libros (codigo,titulo)
values (0,'El gato con botas');
insert into libros (codigo,titulo)
values (-5,'Robin Hood');
select * from libros;
insert into libros (codigo,titulo)
values (null,'Alicia a traves del espejo');
select * from libros;
insert into libros (titulo,autor)
values (null,'Borges');
select * from libros;
insert into libros (titulo,autor,cantidad)
values ('Antologia poetica','Borges',null);
select * from libros;
Prolbema:
Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
domicilio varchar(30),
81
fechaingreso date not null,
fechanacimiento date,
primary key(documento)
);
Otros problemas:
Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".
82
7- Muestre los registros para ver qué valor se guardó en "codigo".
10- Muestre los registros para ver qué se almacenó en "titulo" (cadena cortada).
12- Muestre los registros para ver qué se almacenó en "duración" (el valor límite
permitido por el rango más cercano al ingresado).
Como no ingresamos valor para el campo "codigo", MySQL insertará el valor por
defecto, como "codigo" es un campo "auto_increment", el valor por defecto es el
siguiente de la secuencia.
MySQL insertará "null", porque el valor por defecto de un campo (de cualquier
tipo) que acepta valores nulos, es "null".
MySQL insertará el valor "null" porque el valor por defecto de un campo (de
cualquier tipo) que acepta valores nulos, es "null".
83
Si omitimos el valor correspondiente al título:
MySQL guardará una cadena vacía, ya que éste es el valor por defecto de un
campo de tipo cadena definido como "not null" (no acepta valores nulos).
Podemos establecer valores por defecto para los campos cuando creamos la
tabla. Para ello utilizamos "default" al definir el campo. Por ejemplo, queremos que
el valor por defecto del campo "precio" sea 1.11 y el valor por defecto del campo
"autor" sea "Desconocido":
84
Los campos definidos "auto_increment" no pueden explicitar un valor con "default",
tampoco los de tipo "blob" y "text".
-para campos de cualquier tipo que admiten valores nulos, el valor por defecto
"null";
-para campos que no admiten valores nulos, es decir, definidos "not null", el valor
por defecto depende del tipo de dato:
describe libros;
"Field" contiene el nombre del campo; "Type", el tipo de dato; "NULL" indica si el
campo admite valores nulos; "Key" indica si el campo está indexado (lo veremos
más adelante); "Default" muestra el valor por defecto del campo y "Extra" muestra
información adicional respecto al campo, por ejemplo, aquí indica que "codigo"
está definido "auto_increment".
También se puede utilizar "default" para dar el valor por defecto a los campos en
sentencias "insert", por ejemplo:
Ejemplo:
85
Creamos la tabla con la siguiente estructura:
Ingresamos algunos registros omitiendo algunos campos para ver cómo trabaja la
cláusula "default".
MySQL insertará una cadena vacía, porque el valor por defecto de un campo de
tipo caracter definido como "not null" es ese y para el código, seguirá con la
secuencia.
86
Si omitimos el valor correspondiente al precio:
Se guardará "1.11" ya que éste es el valor por defecto que explicitamos al definir
el campo.
También podemos usar "default" para dar el valor por defecto a los campos en
sentencias "insert", por ejemplo:
87
Problema:
4- Muestre todos los campos de todos los pedidos para ver cómo se guardaron los
datos no ingresados.
Otros problemas:
A) 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.
88
sexo char(1) default 'f',
domicilio varchar(30),
ciudad varchar(20) default 'Cordoba',
telefono varchar(11),
mail varchar(30) default 'no tiene',
montocompra decimal (6,2)
);
4- Ingrese algunos registros sin especificar valores para algunos campos para ver
cómo opera la cláusula "default".
B) Una pequeña biblioteca de barrio registra los préstamos de sus libros en una
tabla llamada "prestamos". En ella almacena la siguiente información: título del
libro, documento de identidad del socio a quien se le presta el libro, fecha de
préstamo, fecha en que tiene que devolver el libro y si el libro ha sido o no
devuelto.
2- Cree la tabla:
create table prestamos(
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
devuelto char(1) default 'n'
);
4- Seleccione todos los registros para ver qué se guardó en el campo "devuelto"
para el cual no ingresamos datos.
89
23 - Atributo zerofill en una columna de una tabla.
Note que especificamos el tamaño del tipo "int" entre paréntesis para que muestre
por la izquierda ceros, cuando los valores son inferiores al indicado; dicho
parámetro no restringe el rango de valores que se pueden almacenar ni el número
de digitos.
Al ingresar un valor de código con menos cifras que las especificadas (6),
aparecerán ceros a la izquierda rellenando los espacios; por ejemplo, si
ingresamos "33", aparecerá "000033". Al ingresar un valor para el campo
"cantidad", sucederá lo mismo.
Ejemplo:
90
Creamos la tabla:
describe libros;
Los valores de código están rellenados a la izquierda con ceros; también los del
campo "cantidad".
91
insert into libros (codigo,titulo,autor,editorial,precio,cantidad)
values(-400,'Matematica estas ahi', 'Paenza', 'Paidos',15.2,-100);
Como los valores son inválidos, almacena los valores por defecto según el tipo;
para el campo "auto_increment" sigue la secuencia y para el campo "cantidad"
guarda "00000".
Problema:
Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".
2- Cree la tabla:
create table cuentas(
numero int(8) zerofill auto_increment,
documento char(8) not null,
nombre varchar(30),
saldo decimal(9,2),
primary key(numero)
);
92
3- Visualice la estructura de la tabla:
describe cuentas;
note que en la columna que muestra el tipo aparece "zerofill" en el campo
"numero".
Otros problemas:
Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".
93
24 - Columnas calculadas.
Si queremos ver los títulos, precio y cantidad de cada libro escribimos la siguiente
sentencia:
select titulo,precio,cantidad
from libros;
Ejemplo:
Creamos la tabla:
94
Ingresamos algunos registros:
Para obtener el monto total en dinero de un título podemos multiplicar el precio por
la cantidad, por cada título, MySQL realiza el cálculo y lo incluye en una columna
extra en la salida:
Para saber el precio de cada libro con un 10% de descuento podemos incluir en la
sentencia los siguientes cálculos:
95
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Antologia poetica','Borges','Planeta',40,150);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',18.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Borges','Paidos',36.40,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00,500);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00,300);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null,50);
select titulo, precio,cantidad,precio*cantidad
from libros;
select titulo, precio,precio*0.1,precio-(precio*0.1)
from libros;
Problema:
Una empresa almacena los datos de sus empleados en una tabla "empleados".
96
4- La empresa está pensando en aumentar un 10% el sueldo a los empleados, y
quiere saber a cuánto subiría cada sueldo básico, para ello usamos la siguiente
sentencia en la cual incluimos una columna que hará el cálculo de cada sueldo
más el 10%:
select nombre, sueldobasico,sueldobasico+sueldobasico*1/10
from empleados;
5- La empresa paga un salario familiar por hijos a cargo, $200 por cada hijo.
Necesitamos el nombre del empleado, el sueldo básico, la cantidad de hijos a
cargo, el total del salario familiar y el suedo final (incluyendo el salario familiar):
Otros problemas:
2- Cree la tabla con la estructura necesaria para almacenar los datos descriptos
anteriormente.
97
4- El precio representa el costo del artículo al comprarlo. Este comercio vende sus
artículos por mayor y por menor, para la venta minorista incrementa el precio de
costo en un 10%, para la venta mayorista lo incrementa en un 5%. Muestre los
precios de cada artículo y calcule en 2 columnas diferentes el precio de cada uno
de ellos al venderse por mayor y por menor:
select nombre,precio,precio+precio*0.1,precio+precio*0.05
from articulos;
MySQL tiene algunas funciones para trabajar con cadenas de caracteres. Estas
son algunas:
select ord('A');
retorna 65.
-char(x,..): retorna una cadena con los caracteres en código ASCII de los enteros
enviados como argumentos. Ejemplo:
select char(65,66,67);
retorna "ABC".
98
-concat_ws(separador,cadena1,cadena2,...): "ws" son las iniciales de "with
separator". El primer argumento especifica el separador que utiliza para los demás
argumentos; el separador se agrega entre las cadenas a concatenar. Ejemplo:
select concat_ws('-','Juan','Pedro','Luis');
retorna "Juan-Pedro-Luis".
select length('Hola');
devuelve 4.
retorna 2.
retorna 2.
99
Ejemplos:
select locate('ar','Margarita',1);
retorna 1.
select locate('ar','Margarita',3);
retorna 5.
devuelve 2.
select lpad('hola',10,'0');
retorna "000000hola".
100
primer argumento, empezando desde la posición especificada en el segundo
argumento. Ejemplo:
retorna "enas".
Ejemplo:
retorna "enas".
select substring('Margarita',4);
retorna "garita".
retorna "garita".
101
retorna "garita", todo lo posterior a la segunda ocurrencia de "ar".
retorna
"Hola "
.
retorna
" Hola"
.
retorna 'Hola'.
retorna "hola00".
retorna "00hola".
retorna "hola".
retorna "hola".
102
select trim (' hola ');
retorna "hola".
select replace('xxx.mysql.com','x','w');
retorna "www.mysql.com'.
select repeat('hola',3);
retorna "holaholahola".
select reverse('Hola');
retorna "aloH".
retorna ""bxxtardes".
103
-ucase(cadena) y upper(cadena): retornan la cadena con todos los caracteres en
mayúsculas. Ejemplo:
select strcmp('Hola','Chau');
retorna 1.
Ejemplo:
select concat_ws('-',titulo,autor)
from libros;
104
la salida muestra una sola columna en la cual se concatenan, con el separador "-",
los distintos campos especificados.
select left(titulo,15)
from libros;
105
26 - Funciones matemáticas.
select 5/0;
MySQL tiene algunas funciones para trabajar con números. Aquí presentamos
algunas.
select abs(-20);
retorna 20.
select ceiling(12.34),
retorna 13.
select floor(12.34);
retorna 12.
select mod(10,3);
retorna 1.
select mod(10,2);
retorna 0.
106
- %: %: devuelve el resto de una división. Ejemplos:
select 10%3;
retorna 1.
select 10%2;
retorna 0.
select power(2,3);
retorna 8.
-rand(): retorna un valor de coma flotante aleatorio dentro del rango 0 a 1.0.
select round(12.34);
retorna 12.
select round(12.64);
retorna 13.
select truncate(123.4567,2);
retorna 123.45;
retorna 123.
107
Ejemplo:
select titulo,truncate(precio,1)
from libros;
108
drop table if exists libros;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar (20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
insert into libros (titulo,autor,editorial,precio)
values('El alehp','Borges','Paidos',33.4);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','L. Carroll','Planeta',16.3);
insert into libros (titulo,autor,editorial,precio)
values('Alicia a traves del espejo','L. Carroll','Planeta',18.8);
select titulo, ceiling(precio),floor(precio)
from libros;
select titulo, round(precio)
from libros;
select titulo,truncate(precio,1)
from libros;
109
valores para "tipo" pueden ser: second, minute, hour, day, month, year,
minute_second (minutos y segundos), hour_minute (horas y minutos), day_hour
(días y horas), year_month (año y mes), hour_second (hora, minuto y segundo),
day_minute (dias, horas y minutos), day_second(dias a segundos).
-dayofmonth(fecha): retorna el día del mes para la fecha dada, dentro del rango 1
a 31. Ejemplo: dayofmonth('2006-08-10') retorna 10.
-dayofweek(fecha): retorna el índice del día de semana para la fecha pasada como
argumento. Los valores de los índices son: 1=domingo, 2=lunes,... 7=sábado).
Ejemplo: dayofweek('2006-08-10') retorna 5, o sea jueves.
-dayofyear(fecha): retorna el día del año para la fecha dada, dentro del rango 1 a
366. Ejemplo: dayofmonth('2006-08-10') retorna 222.
Ejemplos:
Los valores para tipo pueden ser: second, minute, hour, day, month, year,
minute_second, hour_minute, day_hour, year_month, hour_second (horas,
minutos y segundos), day_minute (días, horas y minutos), day_second (días a
segundos).
110
-period_add(p,n): agrega "n" meses al periodo "p", en el formato "YYMM" o
"YYYYMM"; retorna un valor en el formato "YYYYMM". El argumento "p" no es una
fecha, sino un año y un mes. Ejemplo: period_add('200608',2) retorna "200610".
-to_days(fecha): retorna el número de día (el número de día desde el año 0).
Ejemplo:
Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos". En ella almacena la siguiente información:
111
Creamos la tabla:
Ingresamos un registro con los 3 primeros datos y calculamos con una función la
fecha de devolución:
112
values ('Manual de 1 grado','23456789','2006-08-10',date_add('2006-08-10', interval 5 day));
select * from prestamos;
insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion)
values ('Alicia en el pais de las maravillas','23456789',
'2006-08-12',date_add('2006-08-12', interval 5 day));
insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion)
values ('El aleph','22543987','2006-08-15',date_add('2006-08-15', interval 5 day));
insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion)
values ('Manual de geografia 5 grado','25555666','2006-08-30',
date_add('2006-08-30', interval 5 day));
select * from prestamos;
insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion)
values ('Atlas universal','24000111',current_date,date_add(current_date, interval 5 day));
select * from prestamos;
Problema:
Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
sexo char(1),
domicilio varchar(30),
fechaIngreso date,
fechaNacimiento date,
sueldoBasico decimal(5,2) unsigned,
primary key(documento)
);
113
values ('30000222','Luis Luque','m','Urquiza 456','1980-09-01','1980-03-29',700);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('20555444','Maria Laura Torres','f','San Martin 1122','2000-05-15','1965-
12-22',700);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('30000234','Alberto Soto','m','Peru 232','2003-08-15','1989-10-10',420);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('20125478','Ana Gomez','f','Sarmiento 975','2004-06-14','1976-09-
21',350);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('24154269','Ofelia Garcia','f','Triunvirato 628','2004-09-23','1974-05-
12',390);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('306154269','Federico Gonzalez','m','Peru 390','1996-08-15','1985-05-
01',580);
4- Es política de la empresa festejar cada fin de mes, los cumpleaños de todos los
empleados que cumplen ese mes. Necesitamos los nombres y fecha de
nacimiento de los empleados que cumplen años en el mes de mayo:
select nombre,fechaNacimiento from empleados
where month(fechaNacimiento)=5;
114
where month(fechaIngreso)=8;
Otros problemas:
115
(year(current_date)-year(fechaNacimiento)) -
(right(current_date,5)<right(fechaNacimiento,5)) as 'Edad'
from alumnos;
2- Cree la tabla.
select documento,fechavencimiento,
current_date as 'Fecha Pago',
monto,
datediff(current_date,fechavencimiento) as 'Retraso en dias',
(monto*0.01*datediff(current_date,fechavencimiento)) as 'Recargo',
monto+((monto*0.01)*datediff(current_date,fechavencimiento)) as 'Total a Pagar'
from luz
where datediff(current_date,fechavencimiento)>0;
"datediff()" retorna la cantidad de días entre una fecha y otra; si la fecha enviada
como primer argumento es anterior a la del segundo argumento, retorna un valor
negativo. Por eso, en la sentencia anterior colocamos la condición "where", si la
116
obviamos, descontará el 1% del monto por cada día de diferencia entre la fecha de
vencimiento y la fecha actual.
C-) En una página web se solicitan los siguientes datos para guardar información
de sus visitas: nombre, mail, pais.
117
28 - Cláusula order by del select.
Por ejemplo, recuperamos los registros de la tabla "libros" ordenados por el título:
También podemos colocar el número de orden del campo por el que queremos
que se ordene en lugar de su nombre. Por ejemplo, queremos el resultado del
"select" ordenado por "precio":
También podemos ordenar por varios campos, por ejemplo, por "titulo" y
"editorial":
Incluso, podemos ordenar en distintos sentidos, por ejemplo, por "titulo" en sentido
ascendente y "editorial" en sentido descendente:
select codigo,titulo,autor,editorial,precio
from libros order by titulo asc, editorial desc;
Debe aclararse al lado de cada campo, pues estas palabras claves afectan al
campo inmediatamente anterior.
Ejemplo:
118
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(15),
precio decimal (5,2) unsigned,
primary key (codigo)
);
Visualizamos su estructura:
describe libros;
select codigo,titulo,autor,editorial,precio
from libros
order by titulo;
select codigo,titulo,autor,editorial,precio
from libros
order by 5;
select codigo,titulo,autor,editorial,precio
from libros
order by titulo, editorial;
119
Ahora los ordenamos en distintos sentidos, por "titulo" en sentido ascendente y
"editorial" en sentido descendente:
select codigo,titulo,autor,editorial,precio
from libros
order by titulo asc, editorial desc;
Problema:
120
2- Cree la tabla con la siguiente estructura:
create table medicamentos(
codigo int unsigned auto_increment,
nombre varchar(20),
laboratorio varchar(20),
precio decimal(5,2),
cantidad int unsigned,
primary key(codigo)
);
Otros problemas:
121
3- Visualice la estructura de la tabla "peliculas".
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.
122
values ('Fabiola Martinez','[email protected]','2006-10-12');
insert into visitas (nombre,mail,fecha)
values ('Fabiola Martinez','[email protected]','2006-09-12');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-12');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-15');
Queremos recuperar todos los registros cuyo autor sea igual a "Borges" y cuyo
precio no supere los 20 pesos, para ello necesitamos 2 condiciones:
Queremos ver los libros cuyo autor sea "Borges" y/o cuya editorial sea "Planeta":
123
select * from libros
where autor='Borges' or
editorial='Planeta';
Los registros recuperados con una sentencia que une 2 condiciones con el
operador "or", cumplen 1 de las condiciones o ambas.
Queremos ver los libros cuyo autor sea "Borges" o cuya editorial sea "Planeta":
Queremos recuperar los libros que no cumplan la condición dada, por ejemplo,
aquellos cuya editorial NO sea "Planeta":
Los paréntesis se usan para encerrar condiciones, para que se evalúen como una
sola expresión.
124
(editorial='Paidos' and precio<20);
select*from libros
where (autor='Borges' or editorial='Paidos') and
(precio<20);
Ejemplo :
125
Vamos a recuperar registros estableciendo 2 condiciones, necesitamos los
operadores lógicos.
Para recuperar todos los registros cuyo autor sea igual a "Borges" y cuyo precio
no supere los 20 pesos, tipeamos:
Seleccionamos los libros cuyo autor sea "Paenza" y/o cuya editorial sea "Planeta":
Queremos ver los libros cuyo autor sea "Borges" o cuya editorial sea "Planeta":
126
where (autor='Borges') or
(editorial='Paidos' and precio<20);
127
(editorial='Paidos' and precio<20);
select * from libros
where (autor='Borges' or editorial='Paidos')
and (precio<20);
Problema:
128
6- Recupere los medicamentos cuyo laboratorio sea 'Roche' o cuyo precio sea
menor a 5:
select * from medicamentos
where laboratorio='Roche' or
precio<5;
Note que la salida es diferente, hemos cambiado el operador de la sentencia
anterior. Ahora se recuperaron todos los registros cuyo laboratorio es igual a
'Roche' y todos los registros cuyo precio es menor a 5. Aquellos registros que no
cumplieron con la condición 1 (no son de "Roche") ni con la condicion2 (no
cuestan menos de 5) no aparecen.
7- Muestre todos los registros que no sean de "Bayer" usando el operador "not".
9- Muestre todos los medicamentos cuyo laboratorio sea "Bayer" y cuya cantidad
NO sea=100:
select * from medicamentos
where laboratorio='Bayer' and
not cantidad=100;
Analice estas 2 últimas sentencias. El operador "not" afecta a la condición a la cual
antecede, no a las siguientes. Los resultados de estas 2 sentencias son diferentes.
10- Elimine todos los registros cuyo laboratorio sea igual a "Bayer" y su precio sea
mayor a 10:
delete from medicamentos
where laboratorio='Bayer' and
precio>10;
Sólo 1 registro debe ser eliminado, el que cumple con ambas condiciones.
11- Cambie la cantidad por 200, a todos los medicamentos de "Roche" cuyo precio
sea mayor a 5:
update medicamentos set cantidad=200
where laboratorio='Roche' and
precio>5;
Un solo registro fue actualizado porque sólo uno cumplió con las condiciones
especificadas.
12- Borre los medicamentos cuyo laboratorio sea "Bayer" o cuyo precio sea menor
a 3. Antes veamos cuáles cumplen con la condición, los registros 5 y 6 son de
"Bayer, cumplen con la primera
condición, los registros 4 y 5 cumplen con la segunda condición, es decir, se
borrarán 3 registros:
129
el 4 porque cumple con la segunda condición, el 5 porque cumple con ambas y el
6 porque cumple con
la primera. Tipeamos:
delete from medicamentos
where laboratorio='Bayer' or
precio<3;
Otros problemas:
4- Recupere los registros cuyo actor sea "Tom Cruise" or "Richard Gere". (3
registros).
5- Recupere los registros cuyo actor sea "Tom Cruise" y "Richard Gere".
(ninguno cumple ambas condiciones).
6- Cambie la duración a 200, de las películas cuyo actor sea "Daniel R." y cuya
duración sea 180. (1 registro afectado).
130
8- Borre todas las películas donde el actor NO sea "Tom Cruise" y cuya duración
sea mayor o igual a 100:
delete from peliculas
where not actor='Tom Cruise' and
duracion<=100;
Deben borrarse 2 registros.
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas: nombre, mail, pais.
4- Muestre los datos de las visitas de "Argentina" que hayan ingresado después
del mes de septiembre (9):
131
select*from visitas
where pais='Argentina' and
month(fecha)>9;
5- Elimine todos los registros cuyo pais no sea "Mexico" y que hayan visitado la
página antes de las 16 hs.:
delete from visitas
where pais<>'Mexico' and
hour(fecha)<16;
= (igual), <> (distinto), > (mayor), < (menor), >= (mayor o igual), <= (menor o
igual), is null/is not null (si un valor es NULL o no).
Para recuperar de nuestra tabla "libros" los registros que tienen precio mayor o
igual a 20 y menor o igual a 40, usamos 2 condiciones unidas por el operador
lógico "and":
Para recuperar los libros cuyo autor sea 'Paenza' o 'Borges' usamos 2
condiciones:
132
Podemos usar "in":
Con "in" averiguamos si el valor de un campo dado (autor) está incluido en la lista
de valores especificada (en este caso, 2 cadenas).
Para recuperar los libros cuyo autor no sea 'Paenza' ni 'Borges' usamos:
Con "in" averiguamos si el valor del campo está incluido en la lista, con "not"
antecediendo la condición, invertimos el resultado.
Ejemplo:
133
values('Aprenda PHP','Mario Molina','Emece',19.50);
insert into libros (titulo,autor,editorial,precio)
values('Cervantes y el quijote','Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)
values('Matematica estas ahi', 'Paenza', 'Paidos',19);
Recuperamos los registros que tienen precio mayor o igual a 20 y menor o igual a
40, usando 2 condiciones:
134
primary key(codigo)
);
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',15.50);
insert into libros (titulo,autor,editorial,precio)
values('Martin Fierro','Jose Hernandez','Emece',22.90);
insert into libros (titulo,autor,editorial,precio)
values('Martin Fierro','Jose Hernandez','Planeta',39);
insert into libros (titulo,autor,editorial,precio)
values('Aprenda PHP','Mario Molina','Emece',19.50);
insert into libros (titulo,autor,editorial,precio)
values('Cervantes y el quijote','Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)
values('Matematica estas ahi', 'Paenza', 'Paidos',19);
select * from libros
where precio>=20 and
precio<=40;
select * from libros
where precio between 20 and 40;
select * from libros
where autor='Borges' or
autor='Paenza';
select * from libros
where autor in('Borges','Paenza');
select * from libros
where autor<>'Borges' and
autor<>'Paenza';
select * from libros
where autor not in ('Borges','Paenza');
Problema:
135
values('Sertal','Roche',5.2,100);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Buscapina','Roche',4.10,200);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Amoxidal 500','Bayer',15.60,100);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Paracetamol 500','Bago',1.90,200);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Bayaspirina','Bayer',2.10,150);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Amoxidal jarabe','Bayer',5.10,250);
5- Recupere los nombres y precios de los medicamentos cuyo precio esté entre 5
y 15:
select nombre,precio from medicamentos
where precio between 5 and 15;
Otros problemas:
136
values('BCD333','Peugeot 505','1990',80000);
insert into autos(patente,marca,modelo,precio)
values('GCD123','Renault Clio','1990',70000);
insert into autos(patente,marca,modelo,precio)
values('BCC333','Renault Megane','1998',95000);
insert into autos(patente,marca,modelo,precio)
values('BVF543','Fiat 128','1975',20000);
4- Seleccione todos los autos cuyo año sea '1970' o '1975' usando el operador
"in":
select * from autos
where modelo in ('1970','1975');
5- Seleccione todos los autos cuyo precio esté entre 50000 y 100000:
select * from autos
where precio between 50000 and 100000;
Si queremos recuperar todos los libros cuyo autor sea "Borges", y especificamos
la siguiente condición:
137
Esto sucede porque el operador "=" (igual), también el operador "<>" (distinto)
comparan cadenas de caracteres completas. Para comparar porciones de
cadenas utilizamos los operadores "like" y "not like".
Note que el símbolo "%" ya no está al comienzo, con esto indicamos que el título
debe tener como primera letra la "A" y luego, cualquier cantidad de caracteres.
Así como "%" reemplaza cualquier cantidad de caracteres, el guión bajo "_"
reemplaza un caracter, es el otro caracter comodín. Por ejemplo, queremos ver los
libros de "Lewis Carroll" pero no recordamos si se escribe "Carroll" o "Carrolt",
entonces tipeamos esta condición:
138
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
139
where autor like '%Borges%';
140
values('Manual de PHP', 'J.C. Paez', 'Paidos',19);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',36.00);
select * from libros
where autor='Borges';
select * from libros
where autor like '%Borges%';
select * from libros
where titulo like 'A%';
select * from libros
where titulo not like 'A%';
select * from libros
where autor like '%Carrol_';
select * from libros
where titulo like '%Harry Potter%';
Problema:
141
values('Paracetamol 500','Bago',1.90);
insert into medicamentos (nombre, laboratorio,precio)
values('Bayaspirina','Bayer',2.10);
insert into medicamentos (nombre, laboratorio,precio)
values('Amoxidal jarabe','Bayer',5.10);
insert into medicamentos (nombre, laboratorio,precio)
values('Sertal compuesto','Bayer',5.10);
insert into medicamentos (nombre, laboratorio,precio)
values('Paracetamol 1000','Bago',2.90);
insert into medicamentos (nombre, laboratorio,precio)
values('Amoxinil','Roche',17.80);
142
Otros problemas:
5- Actualice el valor del campo "actor" cambiando por 'R. Gere- J. Roberts', de la
película cuyo código es 5:
update peliculas set actor='R. Gere-J. Roberts'
where codigo=5;
6- Seleccione todas las películas en las cuales trabaje el actor "Gere". Use "like".
(2 registros seleccionados).
7- Recupere los registros que NO contengan la letra "y" en el título y contenga "ch"
en el campo "actor" (2 registros):
select * from peliculas
where titulo not like '%y%' and
143
actor like '%ch%';
8- Seleccione las películas que comiencen con "M" y cuya duración sea menor a
150 (3 registros):
select * from peliculas
where titulo like 'M%' and
duracion<150;
10- Recupere los registros que cumplan la condición del punto anterior, para
verificar el cambio de la duración:
select * from peliculas
where actor like 'D%';
144
5- Busque los registros cuya clave contenga sólo 5 letras:
select * from usuarios
where clave like '_____';
Para buscar los autores que tienen al menos una "h" o una "k" o una "w" tipeamos:
Para buscar los autores que no tienen ni "h" o una "k" o una "w" tipeamos:
Para buscar los autores que tienen por lo menos una de las letras de la "a" hasta
la "d", es decir, "a,b,c,d", usamos:
145
Para buscar títulos que contengan una "a" luego un caracter cualquiera y luego
una "e" utilizamos la siguiente sentencia:
Podemos mostrar los títulos que contienen una "a" seguida de 2 caracteres y
luego una "e":
Ejemplo:
Creamos la tabla:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
primary key(codigo)
);
146
Ingresamos algunos registros:
Retorna 4 registros.
Para buscar los registros cuyos autores tienen al menos una "h" o una "k" o una
"w" tipeamos:
4 registros devueltos.
Para buscar los libros cuyos autores no tienen ni "h" o una "k" o una "w" tipeamos:
Selecciona 5 registros.
Para buscar los autores que tienen por lo menos una de las letras de la "a" hasta
la "d", es decir, "a,b,c,d", usamos:
147
select autor from libros
where autor regexp '[a-d]';
Selecciona 7 registros.
Devuelve 3 registros.
Retorna 2 registros.
Para buscar títulos que contengan una "a" luego un caracter cualquiera y luego
una "e" utilizamos la siguiente sentencia:
Retorna 2 registros.
Podemos mostrar los títulos que contienen una "a" seguida de 2 caracteres y
luego una "e":
Selecciona 3 registros.
Devuelve 1 registro.
148
Selecciona 9 registros.
Selecciona 6 registros.
149
select autor from libros
where autor regexp '......';
select titulo from libros
where titulo regexp 'a.*a';
Problema:
Trabaje con la tabla "agenda" que registra la información referente a sus amigos.
150
6- Busque los apellidos que tienen por lo menos una de las letras de la "v" hasta la
"z" (v,w,x,y,z):
select * from agenda
where apellido regexp '[v-z]';
10- Seleccione el nombre y mail de todos los amigos cuyos mails tengan al menos
20 caracteres:
select nombre,mail from agenda
where mail regexp '....................';
Otros problemas:
151
values ('impresora','Epson Stylus C85',500,30);
insert into articulos (nombre, descripcion, precio,cantidad)
values ('monitor','Samsung 14',800,10);
insert into articulos (nombre, descripcion, precio,cantidad)
values ('teclado','ingles Biswal',100,50);
insert into articulos (nombre, descripcion, precio,cantidad)
values ('teclado','español Biswal',90,50);
insert into articulos (nombre, descripcion, precio,cantidad)
values ('impresora multifuncion','HP 1410',300,20);
5-Busque los artículos en los cuales el campo "descripcion" no tienen "H" ni "W":
select * from articulos
where descripcion not regexp '[hw]';
Imaginemos que nuestra tabla "libros" contiene muchos registros. Para averiguar
la cantidad sin necesidad de contarlos manualmente usamos la función "count()":
También podemos utilizar esta función junto con la clausula "where" para una
consulta más específica. Por ejemplo, solicitamos la cantidad de libros que
contienen la cadena "Borges":
152
where autor like '%Borges%';
Para contar los registros que tienen precio (sin tener en cuenta los que tienen
valor nulo), usamos la función "count()" y en los paréntesis colocamos el nombre
del campo que necesitamos contar:
Note que "count(*)" retorna la cantidad de registros de una tabla (incluyendo los
que tienen valor "null") mientras que "count(precio)" retorna la cantidad de
registros en los cuales el campo "precio" no es nulo. No es lo mismo. "count(*)"
cuenta registros, si en lugar de un asterisco colocamos como argumento el
nombre de un campo, se contabilizan los registros cuyo valor en ese campo no es
nulo.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
153
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Martin Fierro','Jose Hernandez','Emece',22.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Antologia poetica','J.L. Borges','Planeta',40,150);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',18.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Bioy Casares- J.L. Borges','Paidos',36.40,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80,120);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null,200);
Retorna 9.
Nos retorna 3.
Para obtener la cantidad de libros cuyo precio no tiene valor nulo usamos la
función "count()" y dentro del paréntesis colocamos el nombre del campo
correspondiente:
154
drop table if exists libros;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
cantidad mediumint unsigned,
primary key(codigo)
);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('El aleph','Borges','Planeta',15,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Martin Fierro','Jose Hernandez','Emece',22.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Antologia poetica','J.L. Borges','Planeta',40,150);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',18.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Bioy Casares- J.L. Borges','Paidos',36.40,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80,120);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null,200);
select count(*) from libros;
select count(*) from libros
where editorial='Planeta';
select count(*) from libros where autor like '%Borges%';
select count(precio) from libros;
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.
155
3- Ingrese algunos registros:
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Susana Molina', 28,'f','Colon 123','Cordoba',null,45.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marcela Mercado',36,'f','Avellaneda 345','Cordoba','4545454',0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia','03547123456',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Teresa Garcia',33,'f','Gral. Paz 123','Alta Gracia','03547123456',0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roberto Perez',45,'m','Urquiza 335','Cordoba','4123456',33.20);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia','03547121212',53.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roxana Lopez',20,'f','Triunvirato 345','Alta Gracia',null,0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Juan Torres',43,'m','Sarmiento 876','Cordoba','4988778',15.30);
Recuerde que no es lo mismo contar todos los registros que contar los que tienen
teléfono, porque en el segundo caso no considera los registros con valor nulo en el
campo "telefono".
156
select count(*) from visitantes
where montocompra<>0;
Otros problemas:
A) Una pequeña biblioteca de barrio registra los préstamos de sus libros en una
tabla llamada "prestamos".
2- Cree la tabla:
create table prestamos(
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevuelto date
);
La tabla registra el documento del socio a quien se le presta el libro, el título del
libro prestado, la fecha de préstamo y la fecha en que se devuelve.
157
5- Cuente la cantidad de libros devueltos (contando por fechadevuelto):
select count(fechadevuelto)
from prestamos;
158
insert into agenda values('Lopez','Maria','Salta
314',null,'[email protected]');
También podemos combinarla con "where". Por ejemplo, queremos saber cuántos
libros tenemos de la editorial "Planeta":
159
La función avg() retorna el valor promedio de los valores del campo especificado.
Por ejemplo, queremos saber el promedio del precio de los libros referentes a
"PHP":
Ejemplo:
Trabajamos con la tabla "libros" que registra la información de los libros que vende
una librería.
Creamos la tabla:
160
values('Antologia poetica','J.L. Borges','Planeta',40,150);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',18.20,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Bioy Casares- J.L. Borges','Paidos',36.40,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80,120);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null,200);
Retorna 1220; verifique la suma, sumando los valores de todos los registros del
campo "cantidad".
Retorna 250; verifique el total sumando las cantidades de los libros cuya editorial
sea "Planeta".
Devuelve 46.
161
Retorna 45.
Solicitamos el promedio del precio de los libros que tratan sobre "PHP":
Retorna 24.50...
162
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Bioy Casares- J.L. Borges','Paidos',36.40,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80,120);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null,200);
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.
163
3- Ingrese algunos registros:
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Susana Molina', 28,'f','Colon 123','Cordoba',null,45.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marcela Mercado',36,'f','Avellaneda 345','Cordoba','4545454',0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia','03547123456',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Teresa Garcia',33,'f','Gral. Paz 123','Alta Gracia','03547123456',0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roberto Perez',45,'m','Urquiza 335','Cordoba','4123456',33.20);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia','03547121212',53.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roxana Lopez',20,'f','Triunvirato 345','Alta Gracia',null,0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Juan Torres',43,'m','Sarmiento 876','Cordoba','4988778',15.30);
164
Otros problemas:
2- cree la tabla:
create table inscripciones(
nombre varchar(30),
documento char(8),
fechainscripto date,
pago decimal(5,2) unsigned not null
);
5- Calcule la suma recaudada por los pagos de los cursos el día "2006-08-10":
select sum(pago)
from inscripciones
where fechainscripto='2006-08-10';
165
from inscripciones
where pago>0;
166
6- Cuente la cantidad de películas que comiencen con la cadena "Harry Potter":
select count(*)
from peliculas
where titulo like 'Harry Potter%';
7- Un socio alquiló todas las películas en las cuales trabaja "Richard Gere", quiere
saber el total de minutos que duran todas sus películas:
select sum(duracion)
from peliculas
where actor='Richard Gere';
167
5- Muestre el valor de auto más caro de 1990:
select max(precio)
from autos
where modelo='1990';
7- Calcule el valor en dinero de todos los autos marca "Renault" con modelos
menores a "1995":
select sum(precio)
from autos
where marca like '%Renault%' and
modelo<1995;
2- Cree la tabla:
create table facturas(
numero int(10) zerofill,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned
);
168
from facturas
where numero='2002';
169
La instrucción anterior solicita que muestre el nombre de la ciudad y cuente la
cantidad agrupando los registros por el campo "ciudad". Como resultado aparecen
los nombres de las ciudades y la cantidad de registros para cada valor del campo.
Para obtener la cantidad visitantes con teléfono no nulo, de cada ciudad utilizamos
la función "count()" enviándole como argumento el campo "telefono", agregamos
"group by" y el campo por el que deseamos que se realice el agrupamiento
(ciudad):
170
Podemos agrupar por más de un campo, por ejemplo, vamos a hacerlo por
"ciudad" y "sexo":
Podemos usar las palabras claves "asc" y "desc" para una salida ordenada:
Ejemplo :
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.
Creamos la tabla:
171
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia','03547123456',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Teresa Garcia',33,'f','Gral. Paz 123','Alta Gracia','03547123456',0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roberto Perez',45,'m','Urquiza 335','Cordoba','4123456',33.20);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia','03547121212',53.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roxana Lopez',20,'f','Triunvirato 345','Alta Gracia',null,0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Juan Torres',43,'m','Sarmiento 876','Cordoba','4988778',15.30);
172
select sexo, max(montocompra),
min(montocompra)
from visitantes
group by sexo;
173
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',25);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia','03547121212',53.50);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Roxana Lopez',20,'f','Triunvirato 345','Alta Gracia',null,0);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48);
insert into visitantes (nombre,edad, sexo,domicilio,ciudad,telefono,montocompra)
values ('Juan Torres',43,'m','Sarmiento 876','Cordoba','4988778',15.30);
select ciudad, count(*)
from visitantes
group by ciudad;
select ciudad, count(telefono)
from visitantes
group by ciudad;
select sexo, sum(montocompra) from visitantes
group by sexo;
select sexo, max(montocompra) from visitantes
group by sexo;
select sexo, min(montocompra) from visitantes
group by sexo;
select sexo, max(montocompra),
min(montocompra)
from visitantes
group by sexo;
select ciudad, avg(montocompra) from visitantes
group by ciudad;
select ciudad, sexo, count(*) from visitantes
group by ciudad,sexo;
select ciudad, count(*) from visitantes
where ciudad<>'Cordoba'
group by ciudad;
select ciudad, count(*) from visitantes
group by ciudad desc;
Problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes".
174
3- Ingrese algunos registros:
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Lopez Marcos', 'Colon 111', 'Córdoba','Cordoba','null');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje','Cordoba','4578585');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria','Cordoba','4578445');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario','Santa Fe',null);
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Pereyra Lucas', 'San Martin 555', 'Cruz del Eje','Cordoba','4253685');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Gomez Ines', 'San Martin 666', 'Santa Fe','Santa Fe','0345252525');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Torres Fabiola', 'Alem 777', 'Villa del Rosario','Cordoba','4554455');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Lopez Carlos', 'Irigoyen 888', 'Cruz del Eje','Cordoba',null);
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Cordoba','Cordoba','4223366');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas','Misiones','0457858745');
5- Obtenga el total de los registros que no tienen valor nulo en los teléfonos (8):
select count(telefono) from clientes;
Otros problemas:
A) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.
175
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha date,
primary key(numero)
);
B) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
sexo char(1),
domicilio varchar(30),
176
fechaingreso date,
fechanacimiento date,
sueldobasico decimal(5,2) unsigned,
primary key(documento)
);
4- Es política de la empresa festejar cada fin de mes, los cumpleaños de todos los
empleados que
cumplen ese mes. Si los empleados son de sexo femenino, se les regala un ramo
de rosas, si son de
sexo masculino, una corbata. La secretaria de la Gerencia necesita saber cuántos
ramos de rosas y
177
cuántas corbatas debe comprar para el mes de mayo:
select sexo,count(sexo)
from empleados
where month(fechanacimiento)=5
group by sexo;
2- Cree la tabla:
create table facturas(
numero int(10) zerofill,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned
);
3- Ingrese algunos registros:
insert into facturas values(504,'escuadra 20 cm.',2.5,100);
insert into facturas values(504,'escuadra 50 cm.',5,80);
insert into facturas values(2002,'compas plastico',8,120);
insert into facturas values(2002,'compas metal',15.4,100);
insert into facturas values(2002,'escuadra 20 cm.',2.5,100);
insert into facturas values(4567,'escuadra 50 cm.',5,200);
178
36 - Selección de un grupo de registros (having)
179
Ambas devuelven el mismo resultado, pero son diferentes.
Queremos la cantidad de libros, sin considerar los que tienen precio nulo,
agrupados por editorial, sin considerar la editorial "Planeta":
Aquí, selecciona los registros rechazando los que no cumplan con la condición
dada en "where", luego los agrupa por "editorial" y finalmente rechaza los grupos
que no cumplan con la condición dada en el "having".
Podemos encontrar el mayor valor de los libros agrupados por editorial y luego
seleccionar las filas que tengan un valor mayor o igual a 30:
Esta misma sentencia puede usarse empleando un "alias", para hacer referencia a
la columna de la expresión:
180
Ejemplo :
Trabajamos con la tabla "libros" que registra los datos de una librería.
Creamos la tabla:
181
select editorial, count(*) from libros
group by editorial
having count(*)>2;
Queremos contar los registros agrupados por editorial sin tener en cuenta a la
editorial "Planeta". Tipeamos y analicemos las siguientes sentencias:
Note que ambas retornan la misma salida. La primera, selecciona los registros sin
considerar los de la editorial "Planeta" y luego los agrupa para contarlos. La
segunda, selecciona todos los registros, los agrupa para contarlos y finalmente
rechaza la cuenta correspondiente a la editorial "Planeta". Recuerde no confundir
las cláusulas "where" y "having"; la primera establece condiciones para la
selección de registros individuales, la segunda establece condiciones para la
selección de filas de una salida "group by".
182
select editorial, avg(precio) from libros
group by editorial
having count(*) > 2;
Para encontrar el mayor valor de los libros agrupados por editorial y luego
seleccionar las filas que tengan un valor mayor o igual a 30 usamos:
Para esta misma sentencia podemos utilizar un "alias" para hacer referencia a la
columna de la expresión:
183
group by editorial
having count(*)>2;
select editorial, avg(precio)
from libros
group by editorial;
select editorial, avg(precio)
from libros
group by editorial
having avg(precio)>25;
select editorial, count(*) from libros
where editorial<>'Planeta'
group by editorial;
select editorial, count(*) from libros
group by editorial
having editorial<>'Planeta';
select editorial, count(*) from libros
where precio is not null
group by editorial
having editorial<>'Planeta';
select editorial, avg(precio) from libros
group by editorial
having count(*) > 2;
select editorial, max(precio)
from libros
group by editorial
having max(precio)>=30;
select editorial, max(precio) as 'mayor'
from libros
group by editorial
having mayor>=30;
Problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes".
184
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje','Cordoba','4578585');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria','Cordoba','4578445');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario','Santa Fe',null);
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Pereyra Lucas', 'San Martin 555', 'Cruz del Eje','Cordoba','4253685');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Gomez Ines', 'San Martin 666', 'Santa Fe','Santa Fe','0345252525');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Torres Fabiola', 'Alem 777', 'Villa del Rosario','Cordoba','4554455');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Lopez Carlos', 'Irigoyen 888', 'Cruz del Eje','Cordoba',null);
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Cordoba','Cordoba','4223366');
insert into clientes (nombre,domicilio,ciudad,provincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas','Misiones','0457858745');
6- Obtenga el total de los registros agrupados por ciudad y provincia sin considerar
los que tienen menos de 2 clientes:
select ciudad, provincia, count(*)
from clientes
group by ciudad,provincia
having count(*)>1;
7- Obtenga el total de los registros sin teléfono nulo, agrupados por ciudad y
provincia sin considerar los que tienen menos de 2 clientes:
select ciudad, provincia, count(*)
from clientes
where telefono is not null
group by ciudad,provincia
having count(*)>1;
Otros problemas:
A) Un comercio que tiene un stand en una feria registra en una tabla llamada
"visitantes" algunos
185
datos de las personas que visitan o compran en su stand para luego enviarle
publicidad de sus
productos.
186
select ciudad, sexo, sum(montocompra)
from visitantes
group by ciudad, sexo
having sum(montocompra)>50;
6- Muestre el monto mayor de compra agrupado por ciudad, siempre que el valor
supere los 30 pesos,
considerando sólo los visitantes con telefono no nulo:
select ciudad, max(montocompra)
from visitantes
where telefono is not null
group by ciudad
having max(montocompra)>30;
7- Agrupe por ciudad y muestre para cada grupo (ciudad) el total de visitantes, la
suma de sus
compras y el promedio de compras:
select ciudad, count(*), sum(montocompra),avg(montocompra)
from visitantes
group by ciudad;
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.
187
insert into visitas (nombre,mail,pais,puntaje)
values ('Fabiola Martinez',null,'Peru',8);
insert into visitas (nombre,mail,pais,puntaje)
values ('Mariana Torres','MarianitaTorres','Peru',7);
C) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
sexo char(1),
domicilio varchar(30),
fechaIngreso date,
fechaNacimiento date,
sueldoBasico decimal(5,2),
primary key(documento)
);
188
values ('20111222','Hector Pereyra','m','Caseros 987','1995-04-01','1965-03-
25',510);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('30000222','Luis LUque','m','Urquiza 456','1980-09-01','1980-03-29',700);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('20555444','Maria Laura Torres','f','San Martin 1122','2000-05-15','1965-
12-22',700);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('30000234','Alberto Soto','m','Peru 232','2003-08-15','1989-10-10',420);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('20125478','Ana Gomez','f','Sarmiento 975','2004-06-14','1976-09-
21',350);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('24154269','Ofelia Garcia','f','Triunvirato 628','2004-09-23','1974-05-
12',390);
4- La empresa festeja cada mes los cumpleaños de todos los empleados que
cumplen ese mes. Queremos saber cuántos empleados cumplen años en los
meses de agosto a diciembre:
select month(fechanacimiento) as mes,
count(*) as cantidad
from empleados
group by mes
having mes>=8;
189
Aparecen repetidos. Para obtener la lista de autores sin repetición usamos:
Note que en los tres casos anteriores aparece "null" como un valor para "autor"· Si
sólo queremos la lista de autores conocidos, es decir, no queremos incluir "null" en
la lista, podemos utilizar la sentencia siguiente:
Para contar los distintos autores, sin considerar el valor "null" usamos:
Note que si contamos los autores sin "distinct", no incluirá los valores "null" pero si
los repetidos:
select count(autor)
from libros;
Podemos combinarla con "where". Por ejemplo, queremos conocer los distintos
autores de la editorial "Planeta":
190
También puede utilizarse con "group by":
Para mostrar los títulos de los libros sin repetir títulos, usamos:
La cláusula "distinct" afecta a todos los campos presentados. Para mostrar los
títulos y editoriales de los libros sin repetir títulos ni editoriales, usamos:
Note que los registros no están duplicados, aparecen títulos iguales pero con
editorial diferente, cada registro es diferente.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
191
values('Antologia poetica','Borges','Planeta',40);
insert into libros (titulo,autor,editorial,precio)
values('Aprenda PHP','Mario Molina','Emece',18.20);
insert into libros (titulo,autor,editorial,precio)
values('Cervantes y el quijote','Bioy Casares- Borges','Paidos',36.40);
insert into libros (titulo,autor,editorial,precio)
values('Manual de PHP', null, 'Paidos',30.80);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Planeta',45.00);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la camara secreta','J.K. Rowling','Planeta',46.00);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Emece',12.10);
Para contar los distintos autores, sin considerar el valor "null" usamos:
Note que si contamos los autores sin "distinct", no incluirá los valores "null" pero si
los repetidos:
select count(autor)
from libros;
select editorial
from libros;
192
select distinct editorial
from libros;
Para mostrar los títulos y editoriales de los libros sin repetir títulos ni editoriales,
usamos:
La consulta nos devuelve registros con títulos iguales pero con editorial diferente,
cada registro es distinto.
193
values('Aprenda PHP','Mario Molina','Emece',18.20);
insert into libros (titulo,autor,editorial,precio)
values('Cervantes y el quijote','Bioy Casares- Borges','Paidos',36.40);
insert into libros (titulo,autor,editorial,precio)
values('Manual de PHP', null, 'Paidos',30.80);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Planeta',45.00);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la camara secreta','J.K. Rowling','Planeta',46.00);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Emece',12.10);
select distinct autor
from libros;
select distinct autor
from libros
where autor is not null;
select count(distinct autor)
from libros;
select count(autor)
from libros;
select editorial
from libros;
select distinct editorial
from libros;
select count(distinct editorial)
from libros;
select distinct autor from libros
where editorial='Planeta';
select editorial,count(distinct autor)
from libros
group by editorial;
select distinct titulo,editorial
from libros
order by titulo;
Problema:
194
clases tinyint unsigned default 10,
fechainicio date,
costo decimal(5,2) unsigned,
primary key(codigo)
);
5- Seleccione los cursos donde el tema incluya "PHP", sin repetir horario ni tema:
select distinct horario,tema from cursos
where tema like '%PHP%';
195
Otros problemas:
A) Una empresa tiene registrados sus clientes en una tabla llamada "clientes".
196
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.
197
Note que las dos últimas sentencias tienen una salida diferente. Una persona
ingresó 2 veces en el mismo día, en el punto Nº6 se cuenta, en el punto Nº 7 no
se cuenta porque solicitamos fechas
diferentes.
198
1- Elimine la tabla si existe.
199
2- Cree la tabla:
create table inscriptos(
documento char(8) not null,
nombre varchar(30),
deporte varchar(15) not null,
año year,
matricula char(1) default 'N'
);
7- Muestre la cantidad de inscriptos por año, sin considerar los alumnos que se
inscribieron en más de un deporte:
select año,count(distinct nombre)
from inscriptos
group by año;
200
38 - Alias
select count(*)
from libros
where autor like '%Borges%';
La columna de la salida ahora tiene como encabezado el alias, lo que hace más
comprensible el resultado.
Un alias puede tener hasta 255 caracteres, acepta todos los caracteres. La
palabra clave "as" es opcional en algunos casos, pero es conveniente usarla. Si el
alias consta de una sola cadena las comillas no son necesarias, pero si contiene
más de una palabra, es necesario colocarla entre comillas.
Se pueden utilizar alias en las clásulas "group by", "order by", "having". Por
ejemplo:
select editorial as 'Nombre de editorial'
from libros
group by 'Nombre de editorial';
Los alias serán de suma importancia cuando rescate datos desde el lenguaje PHP
201
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
Colocamos un alias "Libros de Borges" para la expresión "count(*)" para tener una
salida más clara:
202
select editorial as 'Nombre de editorial'
from libros
group by 'Nombre de editorial';
203
group by 'Nombre de editorial';
select editorial, count(*) as cantidad
from libros
group by editorial
order by cantidad;
select editorial, count(*) as cantidad
from libros
group by editorial
having cantidad>2;
Problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes".
204
4- Obtenga el total de los registros que no tienen valor nulo en los teléfonos y
coloque un alias para dicha columna:
select count(telefono) as 'con telefono'
from clientes;
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.
Necesitamos definir una clave primaria para una tabla con los datos descriptos
arriba. No podemos usar 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 solo cumple con la condición para ser clave, es decir,
debe identificar un solo registro, el valor no puede repetirse, debemos usar 2
campos.
205
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.
Nombramos los campos que formarán parte de la clave separados por comas.
Un campo que es parte de una clave primaria puede ser autoincrementable sólo si
es el primer campo que compone la clave, si es secundario no se permite.
Es posible eliminar un campo que es parte de una clave primaria, la clave queda
con los campos restantes. Esto, siempre que no queden registros con clave
repetida. Por ejemplo, podemos eliminar el campo "horallegada":
siempre que no haya registros con "patente" duplicada, en ese caso aparece un
mensaje de error y la eliminación del campo no se realiza.
206
Ejemplo:
Una playa de estacionamiento guarda cada día los datos de los vehículos que
ingresan a la playa en una tabla llamada "vehiculos".
Para crear una tabla con clave primaria compuesta usamos la siguiente sintaxis:
describe vehiculos;
Vemos que en la columna "key", en ambos campos aparece "PRI", porque ambos
son clave primaria.
207
5- Si ingresamos un registro con patente repetida, no hay problemas, siempre que
la hora de ingreso sea diferente, sino, repetimos el valor de la clave:
Ahora si lo permite.
10- Vea la estructura de la tabla para ver cómo quedó la clave primaria:
describe vehiculos;
208
values('DRT123','auto','15:30',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('FRT545','moto','19:45',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('GTY154','auto','20:30','21:00');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('ACD123','auto','16:00',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('ACD123','auto','16:00',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('ADF123','moto','8:30','10:00');
alter table vehiculos drop horallegada;
delete from vehiculos
where patente='ACD123';
alter table vehiculos drop horallegada;
describe vehiculos;
Problema:
Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos". En ella almacena la siguiente información:
-título del libro,
-documento de identidad del socio a quien se le presta el libro,
-fecha de préstamo,
-fecha de devolución del libro,
-devuelto: si el libro ha sido o no devuelto.
3- Cree la tabla:
create table prestamos(
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
devuelto char(1) default 'N',
primary key(titulo,fechaprestamo)
);
209
insert into prestamos (titulo,documento,fechaprestamo)
values('El aleph','22333444','2006-07-10');
insert into prestamos (titulo,documento,fechaprestamo)
values('El aleph','30333444','2006-08-10');
Note que un mismo libro fue prestado a un mismo socio pero en una fecha distinta.
Otros problemas:
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.
210
1- Elimine la tabla "inscriptos" si existe.
3- Necesitamos una clave primaria que identifique cada registro. Un socio puede
inscribirse en varios deportes en distintos años. Un socio no puede inscribirse en
el mismo deporte el mismo año. varios socios se inscriben en un mismo deporte.
Cree la tabla con una clave compuesta:
create table inscriptos(
documento char(8) not null,
nombre varchar(30),
deporte varchar(15) not null,
año year,
matricula char(1),
primary key(documento,deporte,año)
);
211
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (serie,numero)
);
212
values('B',102,2,'goma lapiz-tinta',0.35,200);
9- Muestre los registros concatenando "serie" con "numero", usando un alias para
esa columna, muestre los demás campos y ordene por el alias:
select concat_ws('-',serie,numero) as serienumero,
numeroitem,descripcion,precioporunidad,cantidad
from facturas
order by serienumero;
10- Agrupe los registros por serie y número de factura y muestre el total (en una
columna calculada) de cada factura:
select serie,numero,
sum(precioporunidad*cantidad) as total
from facturas
group by serie,numero;
El índice es un tipo de archivo con 2 entradas: un dato (un valor de algún campo
de la tabla) y un puntero.
Un índice posibilita el acceso directo y rápido haciendo más eficiente las
búsquedas. Sin índice, se debe recorrer secuencialmente toda la tabla para
encontrar un registro.
213
La indexación es una técnica 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.
Es importante identificar el o los campos por los que sería útil crear un indice,
aquellos campos por los cuales se realizan operaciones de búsqueda con
frecuencia.
1) "primary key": es el que definimos como clave primaria. Los valores indexados
deben ser únicos y además no pueden ser nulos. MySQL le da el nombre
"PRIMARY". Una tabla solamente puede tener una clave primaria.
3) "unique": crea un indice para los cuales los valores deben ser únicos y
diferentes, aparece un mensaje de error si intentamos agregar un registro con un
valor ya existente. Permite valores nulos y pueden definirse varios por tabla.
Podemos darle un nombre, si no se lo damos, se coloca uno por defecto.
Todos los índices pueden ser multicolumna, es decir, pueden estar formados por
más de 1 campo.
Una tabla puede tener hasta 64 índices. Los nombres de índices aceptan todos los
caracteres y pueden tener una longitud máxima de 64 caracteres. Pueden
comenzar con un dígito, pero no pueden tener sólo dígitos.
Una tabla puede ser indexada por campos de tipo numérico o de tipo caracter.
También se puede indexar por un campo que contenga valores NULL, excepto los
PRIMARY.
"show index" muestra información sobre los índices de una tabla. Por ejemplo:
214
41 - Indice de tipo primary.
Los valores indexados deben ser únicos y además no pueden ser nulos. Una tabla
solamente puede tener una clave primaria por lo tanto, solamente tiene un índice
PRIMARY.
Puede ser multicolumna, es decir, pueden estar formados por más de 1 campo.
Podemos ver la estructura de los índices de una tabla con "show index". Por
ejemplo:
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
215
Veamos la estructura de los índices de la tabla:
Problema:
Una empresa almacena los datos de sus clientes en una tabla llamada "clientes".
216
3- Vea la estructura de los índices la tabla y analice la información:
show index from clientes;
Otros problemas:
Vamos a ver el otro tipo de índice, común. Un índice común se crea con "index",
los valores no necesariamente son únicos y aceptan valores "null". Puede haber
varios por tabla.
217
Luego de la definición de los campos colocamos "index" seguido del nombre que
le damos y entre paréntesis el o los campos por los cuales se indexará dicho
índice.
Ciertas tablas (MyISAM, InnoDB y BDB) soportan índices en campos que permiten
valores nulos, otras no, debiendo definirse el campo como "not null".
Para crear índices por múltiple campos se listan los campos dentro de los
paréntesis separados con comas. Los valores de los índices se crean
concatenando los valores de los campos mencionados.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
218
primary key(codigo),
index i_editorial (editorial)
);
Analicemos la estructura de los índices:
Vemos que la tabla tiene 2 índices, uno de ellos corresponde a la clave primaria
(codigo) que se creó automáticamente al definir el campo "código" como clave
primaria; el otro es el que creamos con "index" llamado "i_editorial".
La columna "Non_unique" indica si los valores son "no únicos"; para el índice
creado por la clave primaria indica "false" (0), significa que SON únicos, no hay
valores repetidos para ese campo (recuerde lo aprendido sobre clave primaria);
para el índice "i_editorial" indica "true" (1), es decir, NO son únicos, hay valores
repetidos.
219
primary key(codigo),
index i_tituloeditorial (titulo,editorial)
);
Note que los campos se listan entre paréntesis separados por comas.
Aparecen 3 filas.
220
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key(codigo),
index i_tituloeditorial (titulo,editorial)
);
show index from libros;
Problema:
Otros problemas:
221
3- Muestre los índices:
show index from clientes;
4- Analice la información:
Aparecen 3 filas, 3 índices. Uno de ellos corresponde a la clave primaria
(PRIMARY), es único (los valores no se repiten) y no acepta valores nulos. Otro
índice, llamado "i_ciudadprovincia", es No único, es decir, acepta valores
repetidos, consta de 2 campos, el orden es "ciudad" y "provincia" y acepta valores
nulos (ambos campos).
222
43 - Indice único (unique)
Veamos el otro tipo de índice, único. Un índice único se crea con "unique", los
valores deben ser únicos y diferentes, aparece un mensaje de error si intentamos
agregar un registro con un valor ya existente. Permite valores nulos y pueden
definirse varios por tabla. Podemos darle un nombre, si no se lo damos, se coloca
uno por defecto.
Crearemos dos índices únicos, uno por un solo campo y otro multicolumna:
Luego de la definición de los campos colocamos "unique" seguido del nombre que
le damos y entre paréntesis el o los campos por los cuales se indexará dicho
índice.
Tipo Nombre Palabra clave Valores únicos Acepta null Cantidad por tabla
_______________________________________________________________________________
clave primaria PRIMARY no Si No 1
común darlo o por defecto "index" o "key" No Si varios
único darlo o por defecto "unique" Si Si varios
Ejemplo:
Trabajamos con nuestra tabla "libros" de una librería.
Crearemos dos índices únicos, uno por un solo campo y otro multicolumna:
223
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
unique i_codigo (codigo),
unique i_tituloeditorial (titulo,editorial)
);
Aparecen 3 filas.
Ambos índices son únicos, o sea, no permiten valores repetidos, esto se indica en
la columna "Non_unique". La columna "Key_name" indica el nombre de los
índices. La columna "Seq_in_index" y "Column_name" muestran la secuencia de
la indexación para cada campo del índice "i_tituloeditorial". En el índice
"i_tituloeditorial" y el campo "titulo" muestra 1 y para el campo "editorial" muestra
2, esto significa que está indexado en ese orden.
224
Problema:
4- Ingrese algunos registros. Ingrese 2 ó 4 alumnos para los años 2004, 2005 y
2006.
Otros problemas:
A) Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas" que
almacena la siguiente información:
225
- fecha de la consulta,
- número de consulta por día,
- documento del paciente,
- obra social del paciente,
- nombre del médico que atiende al paciente,
2- Cree la tabla con una clave primaria compuesta (fecha y número de consulta);
un índice único (fecha,documento y médico). Hay 2 campos por los cuales
podemos realizar consultas frecuentemente: "medico" y "obrasocial", cree índices
para esos campos.
6- Los valores para el índice único no pueden repetirse. Intente ingresar una
consulta del mismo paciente, en la misma fecha con el mismo médico.
7- Note que los índices por los campos "medico" y "obrasocial" son comunes,
porque los valores se repiten. Ingrese consultas en las cuales se repitan los
médicos y las obras sociales.
2- Cree la tabla con una clave primaria por número de vehículo y un índice único
por "patente",
226
éste es un valor por el cual podemos realizar consultas frecuentemente y es único
(igual que el número del remis):
Se elimina el índice con "drop index" seguido de su nombre y "on" seguido del
nombre de la tabla a la cual pertenece.
Podemos eliminar los índices creados con "index" y con "unique" pero no el que se
crea al definir una clave primaria. Un índice PRIMARY se elimina automáticamente
al eliminar la clave primaria (tema que veremos más adelante).
Ejemplo :
Trabajamos con nuestra tabla "libros" de una librería.
Creamos dos índices, uno común, por un solo campo y otro único multicolumna:
227
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key (codigo),
index i_editorial (editorial),
unique i_tituloeditorial (titulo,editorial)
);
Vemos que tenemos tres índices, uno creado automáticamente al definir la clave
primaria (PRIMARY).
Para eliminar los índices creados con "index" y con "unique" usamos "drop index".
Eliminamos el índice "i_editorial":
Si tipeamos:
show index from libros;
vemos que solamente queda el índice creado al definir la clave primaria. Este tipo
de índice no puede borrarse con "drop index".
228
Problema:
Un instituto de enseñanza guarda los datos de sus alumnos en una tabla llamada
"alumnos".
Otros problemas:
Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".
229
medico varchar(30),
primary key(fecha,numero),
unique i_consulta(documento,fecha,medico),
index i_medico (medico),
index i_obrasocial (obrasocial)
);
Entonces, para agregar un índice común a una tabla existente usamos "create
index", indicamos el nombre, sobre qué tabla y el o los campos por los cuales se
indexará, entre paréntesis.
Para agregar un índice único a una tabla existente usamos "create unique index",
indicamos el nombre, sobre qué tabla y entre paréntesis, el o los campos por los
cuales se indexará.
Ejemplo:
Trabajamos con nuestra tabla "libros" de una librería.
230
Creamos la tabla con clave primaria:
231
Problema:
Retome la tabla "clientes" que almacena información sobre los clientes de una
empresa.
Otros problemas:
Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".
232
5- Agregue un índice común por el campo "obrasocial":
create index i_obrasocial on consultas (obrasocial);
La cláusula "limit" se usa para restringir los registros que se retornan en una
consulta "select".
Ejemplo:
select * from libros limit 0,4;
Si tipeamos:
select * from libros limit 5,4;
Para recuperar los registros desde cierto número hasta el final, se puede colocar
un número grande para el segundo argumento:
233
Podemos ordenar los regitros por precio (por ejemplo) y borrar 2:
esta sentencia borrará los 2 primeros registros, es decir, los de precio más bajo.
Luego eliminamos con "limit" la cantidad sobrante (tenemos 3 y queremos solo 1):
Sólo queda 1.
234
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
235
select * from libros limit 8;
Para recuperar los registros desde cierto número hasta el último, colocamos un
número grande para el segundo argumento:
Ordenamos por precio y combinamos "limit" con el comando "delete" para eliminar
los 2 registros con precio más bajo:
Pero nos equivocamos y volvemos a ingresar el mismo libro, del mismo autor y
editorial 2 veces más (es un error que no controla MySQL):
Para eliminar el libro duplicado y que sólo quede un registro de él, vemos cuántos
tenemos:
Luego eliminamos con "limit" la cantidad sobrante (tenemos 3 y queremos sólo 1):
236
autor='Borges' and
editorial='Planeta'
limit 2;
Sólo queda 1.
drop table if exists libros;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
primary key (codigo)
);
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',15);
insert into libros (titulo,autor,editorial,precio)
values('Martin Fierro','Jose Hernandez','Emece',22.20);
insert into libros (titulo,autor,editorial,precio)
values('Antologia poetica','Borges','Planeta',40);
insert into libros (titulo,autor,editorial,precio)
values('Aprenda PHP','Mario Molina','Emece',18.20);
insert into libros (titulo,autor,editorial,precio)
values('Cervantes y el quijote','Borges','Paidos',36.40);
insert into libros (titulo,autor,editorial,precio)
values('Manual de PHP', 'J.C. Paez', 'Paidos',30.80);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la piedra filosofal','J.K. Rowling','Paidos',45.00);
insert into libros (titulo,autor,editorial,precio)
values('Harry Potter y la camara secreta','J.K. Rowling','Paidos',46.00);
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',null);
select * from libros limit 0,4;
select * from libros limit 5,4;
select * from libros limit 8;
select * from libros limit 6,10000;
237
values('El aleph','Borges','Planeta',15);
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',15);
select * from libros
where titulo='El aleph" and
autor='Borges' and
editorial='Planeta';
delete from libros
where titulo='El aleph" and
autor='Borges' and
editorial='Planeta'
limit 2;
select * from libros
where titulo='El aleph" and
autor='Borges' and
editorial='Planeta';
Problema:
Trabaje con la tabla "peliculas" de un video club que alquila películas en video.
3- Ingrese 10 registros.
Otros problemas:
Trabaje con la tabla "agenda" que registra la información referente a sus amigos.
238
nombre varchar(20) not null,
domicilio varchar(30),
telefono varchar(11),
mail varchar(30),
index i_apellido (apellido)
);
3- Ingrese 10 registros.
Podemos ejecutar la sentencia anterior varias veces seguidas y veremos que los
registros recuperados son diferentes en cada ocasión.
Ejemplo:
Trabajamos con la tabla "libros" en el cual una librería guarda los datos de sus
libros.
239
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
Agregamos varios registros:
Nos devuelve los datos de 5 libros tomados al azar de la tabla "libros". Podemos
ejecutar la sentencia anterior varias veces seguidas y veremos que los registros
recuperados son diferentes en cada ocasión:
240
values(3,'Alicia a traves del espejo','Lewis Carroll','Planeta',15);
insert into libros
values(4,'Alicia en el pais de las maravillas','Lewis Carroll','Planeta',18);
insert into libros values(5,'Martin Fierro','Jose Hernandez','Planeta',34.6);
insert into libros values(6,'Martin Fierro','Jose Hernandez','Emece',45);
insert into libros values(7,'Aprenda PHP','Mario Molina','Planeta',55);
insert into libros values(8,'Java en 10 minutos','Mario Molina','Planeta',45);
insert into libros values(9,'Matematica estas ahi','Paenza','Planeta',12.5);
select * from libros
order by rand()
limit 5;
select * from libros order by rand() limit 5;
select * from libros order by rand() limit 5;
select * from libros order by rand() limit 5;
Problema:
241
El instituto quiere tomar 3 alumnos al azar para que representen al instituto en una
feria de ciencias. Para recuperar de una tabla registros aleatorios se puede utilizar
la función "rand()" combinada con "order by" y "limit":
select documento,nombre
from alumnos
order by rand()
limit 3;
Otros problemas:
242
values ('impresora multifuncion','HP 1410',300,20);
4- El comercio quiere tomar 2 artículos al azar para ofrecer una oferta especial
haciendo un descuento. Seleccione 2 registros al azar de la tabla "articulos":
select * from articulos
order by rand()
limit 2;
Ejecute la sentencia varias veces para verificar que los registros seleccionados
son diferentes.
Si tenemos la tabla "libros" con el campo "codigo" establecido como clave primaria
e intentamos ingresar ("insert") un valor de código existente, aparece un mensaje
de error porque no está permitido repetir los valores del campo clave. Si
empleamos "replace" en lugar de "insert", la sentencia se ejecuta reemplazando el
registro con el valor de código existente por el nuevo registro.
Si empleamos "replace":
243
"replace" funciona como "insert" en los siguientes casos: - si los datos ingresados
no afectan al campo único, es decir no se ingresa valor para el campo indexado:
aparece un mensaje indicando que se afectó solo una fila, no hubo reemplazo
porque el código no existía antes de la nueva inserción.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
244
Ingresamos algunos registros:
insert into libros
values (10,'Alicia en el pais de las maravillas','Lewis Carroll','Emece',15.4);
insert into libros
values (15,'Aprenda PHP','Mario Molina','Planeta',45.8);
insert into libros values (23,'El aleph','Borges','Planeta',23.0);
aparece un mensaje indicando que se afectó solo una fila, no hubo reemplazo
porque el código no existía antes de la nueva inserción.
245
drop table if exists libros;
create table libros(
codigo int unsigned,
titulo varchar(40),
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
insert into libros
values (10,'Alicia en el pais de las maravillas','Lewis Carroll','Emece',15.4);
insert into libros
values (15,'Aprenda PHP','Mario Molina','Planeta',45.8);
insert into libros values (23,'El aleph','Borges','Planeta',23.0);
insert into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);
replace into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);
replace into libros(titulo,autor,editorial,precio)
values('Cervantes y el quijote','Borges','Paidos',28);
replace into libros values(30,'Matematica estas ahi','Paenza','Paidos',12.8);
alter table libros drop primary key;
replace into libros values(10,'Harry Potter ya la piedra filosofal','Hawking','Emece',48);
Problema:
2- Cree la tabla:
create table alumnos(
legajo int(10) unsigned auto_increment,
nombre varchar(30),
documento char(8),
domicilio varchar(30),
primary key(legajo),
unique i_documento (documento)
);
246
5- Ingrese el registro anterior reemplazando el existente:
replace into alumnos values('3567','Marcos Pereyra','30000333','Guemes 134');
7- Reemplace el registro:
replace into alumnos values('4567','Susana Juarez','30000333','Avellaneda 33');
note que el alumno con documento "30000333" se eliminó y se reemplazó por el
nuevo registro.
"alter table" hace una copia temporal de la tabla original, realiza los cambios en la
copia, luego borra la tabla original y renombra la copia.
Para ello utilizamos nuestra tabla "libros", definida con la siguiente estructura:
247
- código, int unsigned auto_increment, clave primaria,
- titulo, varchar(40) not null,
- autor, varchar(30),
- editorial, varchar (20),
- precio, decimal(5,2) unsigned.
Usamos "alter table" seguido del nombre de la tabla y "add" seguido del nombre
del nuevo campo con su tipo y los modificadores.
Ejemplo:
Trabajamos con la tabla "libros".
248
Para agregar el campo "cantidad" de tipo smallint unsigned not null, tipeamos:
describe libros;
Si mostramos todos los registros, vemos que los valores para el nuevo campo se
cargaron con su valor por defecto, "0" en el ejemplo porque el campo agregado es
de tipo numérico y declarado "not null".
Si mostramos todos los registros, vemos que los valores para el nuevo campo se
cargaron con su valor por defecto, "null" en este caso.
249
Problema:
Otros problemas:
Un comercio que vende por mayor artículos de librería y papelería tiene una tabla
llamada "articulos".
250
precio decimal(4,2) unsigned,
primary key(codigo)
);
4- El comercio, que hasta ahora ha vendido sus artículos por mayor, comenzará la
venta por menor. Necesita alterar la tabla agregando un campo para almacenar el
precio por menor para cada artículo.
Agrege un campo llamado "preciopormenor":
alter table articulos
add preciopormenor decimal(4,2) unsigned;
251
Para eliminar el campo "edicion" tipeamos:
Entonces, para borrar un campo de una tabla usamos "alter table" junto con "drop"
y el nombre del campo a eliminar.
Hay que tener cuidado al eliminar un campo, éste puede ser clave primaria. Es
posible eliminar un campo que es clave primaria, no aparece ningún mensaje:
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
252
Para eliminar el campo "edicion" tipeamos:
describe libros;
253
Problema:
254
Otros problemas:
Trabajamos con nuestra tabla "usuarios" que almacena los nombres de los
usuarios y sus claves.
2- Cree la tabla:
create table usuarios (
nombre varchar(30),
clave varchar(10)
);
Queremos modificar el tipo del campo "cantidad", como guardaremos valores que
no superarán los 50000 usaremos smallint unsigned, tipeamos:
255
modify cantidad smallint unsigned;
Usamos "alter table" seguido del nombre de la tabla y "modify" seguido del nombre
del nuevo campo con su tipo y los modificadores.
Queremos modificar el tipo del campo "titulo" para poder almacenar una longitud
de 40 caracteres y que no permita valores nulos, tipeamos:
Hay que tener cuidado al alterar los tipos de los campos de una tabla que ya tiene
registros cargados. Si tenemos un campo de texto de longitud 50 y lo cambiamos
a 30 de longitud, los registros cargados en ese campo que superen los 30
caracteres, se cortarán.
"alter table" combinado con "modify" permite agregar y quitar campos y atributos
de campos. Para modificar el valor por defecto ("default") de un campo podemos
usar también "modify" pero debemos colocar el tipo y sus modificadores, entonces
resulta muy extenso, podemos setear sólo el valor por defecto con la siguienmte
sintaxis:
256
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Para modificar el tipo del campo "titulo" para poder almacenar una longitud de 40
caracteres y que no permita valores nulos, tipeamos:
describe libros;
257
alter table libros
modify autor varchar(10);
Note que los nombres de los autores que tenían más de 10 caracteres se cortaron.
Note que en el campo "autor" del libro "El gato con botas", ahora tiene una cadena
vacía, lo habíamos cargado con "null", pero al redefinir el campo como no nulo,
"null" se convirtió en un valor inválido.
Note que el valor "150" se convierte en un valor inválido para el tipo, entonces
guarda en su lugar, el valor límite más cercano, "99.99".
La sentencia no se ejecuta.
258
drop table if exists libros;
create table libros(
codigo int unsigned,
titulo varchar(30) not null,
autor varchar(30),
editorial varchar (20),
precio decimal(5,2) unsigned,
cantidad int unsigned
);
alter table libros
modify cantidad smallint unsigned;
describe libros;
alter table libros
modify titulo varchar(40) not null;
describe libros;
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('El aleph','Borges','Planeta',23.5,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('Alicia en el pais de las maravillas','Lewis Carroll','Emece',25,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('El gato con botas',null,'Emece',10,500);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('Martin Fierro','Jose Hernandez','Planeta',150,200);
alter table libros
modify autor varchar(10);
select * from libros;
alter table libros
modify autor varchar(10) not null;
select * from libros;
alter table libros
modify precio decimal(4,2);
select * from libros;
alter table libros
modify codigo int unsigned auto_increment;
Problema:
259
4- Modifique el campo "nombre" para poder almacenar una longitud de 40
caracteres y que no permita valores nulos:
alter table peliculas
modify nombre varchar(40) not null;
Otros problemas:
260
- nombre, varchar(40),
- autor, varchar(30),
Usamos "alter table" seguido del nombre de la tabla y "change" seguido del
nombre actual y el nombre nuevo con su tipo y los modificadores.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
261
Para cambiar el nombre del campo "costo" por "precio", tipeamos:
Para cambiar el nombre del campo "nombre" por "titulo" y redefinirlo como "not
null", tipeamos:
describe libros;
vemos que el campo ahora tiene un nuevo nombre y no permite valores nulos.
Problema:
Un comercio que vende por mayor artículos de librería y papelería tiene una tabla
llamada "articulos".
262
1- Elimine la tabla, si existe.
4- El comercio, que hasta ahora ha vendido sus artículos por mayor comenzará la
venta por menor. Necesita alterar la tabla modificando el nombre del campo
"precio" por "preciopormayor" además desea redefinirlo como no nulo:
263
8- Muestre todos los registros:
select * from articulos;
Otros problemas:
3- Cambie el nombre del campo "actor" por "protagonista" y modifíquelo para que
permita valores nulos:
alter table peliculas
change actor protagonista varchar(20);
4- Cambie el campo "nombre" por "titulo" sin alterar los otros atributos:
alter table peliculas
change nombre titulo varchar(40) not null;
264
Para agregar una clave primaria a una tabla existente usamos:
Usamos "alter table" con "add primary key" y entre paréntesis el nombre del
campo que será clave.
Con "alter table" y "drop primary key" eliminamos una clave primaria definida al
crear la tabla o agregada luego.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
265
autor varchar(30),
editorial varchar (20),
precio decimal(5,2) unsigned,
cantidad smallint unsigned
);
Para establecer el campo "codigo" como clave primaria usamos:
alter table libros
add primary key (codigo);
describe libros;
la sentencia no se ejecuta porque si existe un campo con este atributo DEBE ser
clave primaria.
266
drop table if exists libros;
create table libros(
codigo int unsigned,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar (20),
precio decimal(5,2) unsigned,
cantidad smallint unsigned
);
alter table libros
add primary key (codigo);
describe libros;
alter table libros
add primary key (titulo);
alter table libros
modify codigo int unsigned auto_increment;
alter table libros
drop primary key;
alter table libros
modify codigo int unsigned;
alter table libros
drop primary key;
describe libros;
Problema:
267
y si intentamos agregar más registros, aparecerá un mensaje indicando que la
clave está repetida:
insert into medicamentos (nombre, laboratorio,precio)
values('Paracetamol 1000','Bago',2.90);
Otros problemas:
Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos".
2- Cree la tabla:
create table prestamos(
codigo int unsigned,
268
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
devuelto char(1) /* si se devolvió 's' sino 'n'*/
);
Usamos "alter table" con "add primary key" y entre paréntesis el nombre del
campo que será clave.
Si intentamos agregar otra clave primaria, aparecerá un mensaje de error porque
(recuerde) una tabla solamente puede tener una clave primaria.
269
autoincrementable y luego agregarlo como clave porque para definir un campo
"auto_increment" éste debe ser clave primaria.
Con "alter table" y "drop primary key" eliminamos una clave primaria definida al
crear la tabla o agregada luego.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
270
Si intentamos agregar otra clave primaria, aparecerá un mensaje de error porque
(recuerde) una tabla solamente puede tener una clave primaria:
la sentencia no se ejecuta porque si existe un campo con este atributo DEBE ser
clave primaria.
describe libros;
271
add primary key (titulo);
alter table libros
modify codigo int unsigned auto_increment;
alter table libros
drop primary key;
alter table libros
modify codigo int unsigned;
alter table libros
drop primary key;
describe libros;
Problema:
272
El código se alteró, ahora tiene el valor "1".
Otros problemas:
Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos".
2- Cree la tabla:
create table prestamos(
codigo int unsigned,
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
devuelto char(1) /* si se devolvió 's' sino 'n'*/
);
3- Agregue una clave primaria compuesta por "codigo" y "fechaprestamo":
alter table prestamos
add primary key (codigo,fechaprestamo);
273
54 - Agregar índices(alter table - add index)
Usamos "alter table" junto con "add index" seguido del nombre que le daremos al
índice y entre paréntesis el nombre de el o los campos por los cuales se indexará.
Para agregar un índice único multicampo, por los campos "titulo" y "editorial",
usamos la siguiente sentencia:
alter table libros
add unique index i_tituloeditorial (titulo,editorial);
Usamos "alter table" junto con "add unique index" seguido del nombre que le
daremos al índice y entre paréntesis el nombre de el o los campos por los cuales
se indexará.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
274
editorial varchar (20),
precio decimal(5,2) unsigned,
cantidad smallint unsigned
);
Para agregar un índice común por el campo "editorial" tipeamos:
alter table libros
add index i_editorial (editorial);
Para agregar un índice único multicolumna por los campos "titulo" y "editorial",
tipeamos:
alter table libros
add unique index i_tituloeditorial (titulo,editorial);
Problema:
2- Cree la tabla:
create table alumnos(
legajo int unsigned auto_increment,
nombre varchar(30),
documento char(8) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar(20),
primary key(legajo)
275
);
3- Vea los índices de la tabla.
4- Agregue un índice común por los campos "ciudad" y "provincia" (que pueden
repetirse):
alter table alumnos
add index i_ciudadprovincia(ciudad,provincia);
5- Agregue un índice único (no pueden repetirse los valores) por el campo
"documento":
alter table alumnos
add unique index i_documento (documento);
Otros problemas:
Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".
2- Cree la tabla con una clave primaria compuesta (fecha y número de consulta):
create table consultas(
fecha date,
numero int unsigned,
documento char(8) not null,
obrasocial varchar(30),
medico varchar(30),
primary key(fecha,numero)
);
3- Agregue un índice único llamado "i_consulta" compuesto por los campos
"documento", "fecha" y "medico":
alter table consultas
add unique index i_consulta(documento,fecha,medico);
276
55 - Borrado de índices (alter table - drop index)
Trabajamos con la tabla "libros" de una librería, que tiene los siguientes campos e
índices:
Usamos "alter table" y "drop index" seguido del nombre del índice a borrar.
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
277
Para eliminar el índice común llamado "i_editorial" usamos la siguiente sintaxis:
alter table libros
drop index i_editorial;
278
Problema:
Otros problemas:
Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".
279
primary key(fecha,numero),
unique i_consulta(documento,fecha,medico),
index i_medico (medico),
index i_obrasocial (obrasocial)
);
3- Vea los índices de la tabla.
Para cambiar el nombre de una tabla llamada "amigos" por "contactos" usamos
esta sintaxis:
Entonces usamos "alter table" seguido del nombre actual, "rename" y el nuevo
nombre.
280
Ejemplo:
Eliminamos las tablas "amigos" y "contactos" si existen.
Podemos intercambiar los nombres de dos tablas. Por ejemplo, tenemos una tabla
llamada "amigos" con los datos de nuestros amigos y otra tabla "contactos" con
los datos de compañeros de trabajo, ambas con la misma estructura.
Créelas:
create table amigos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
create table contactos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
281
Ingresemos algunos registros:
Para intercambiar los nombres de estas dos tablas, debemos tipear lo siguiente:
rename table amigos to auxiliar,
contactos to amigos,
auxiliar to contactos;
282
values('Lopez','4223344');
rename table amigos to auxiliar,
contactos to amigos,
auxiliar to contactos;
select * from amigos;
select * from contactos;
Problema:
Otros problemas:
Una empresa tiene almacenados los datos de sus clientes en una tabla llamada
"clientes" y los datos de sus empleados en otra tabla denominada "empleados".
283
fechaingreso date,
sueldo decimal(6,2) unsigned
);
create table empleados(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
ciudad varchar(30),
provincia varchar(30)
);
3- Vea la estructura de ambas tablas:
describe clientes;
describe empleados;
Los valores presentados como permitidos tienen un valor de índice que comienza
en 1.
Una empresa necesita personal, varias personas se han presentado para cubrir
distintos cargos. La empresa almacena los datos de los postulantes a los puestos
en una tabla llamada "postulantes". Le interesa, entre otras cosas, conocer los
estudios que tiene cada persona, si tiene estudios primario, secundario, terciario,
universitario o ninguno. Para ello, crea un campo de tipo "enum" con esos valores.
Para definir un campo de tipo "enum" usamos la siguiente sintaxis al crear la tabla:
284
create table postulantes(
numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
estudios enum('ninguno','primario','secundario', 'terciario','universitario'),
primary key(numero)
);
En los 3 casos guarda una cadena vacía, en los 2 primeros porque los índices
ingresados están fuera de rango y en el tercero porque el valor no está incluido en
la lista de permitidos.
Esta cadena vacía de error, se diferencia de una cadena vacía permitida porque la
primera tiene el valor de índice 0; entonces, podemos seleccionar los registros con
valores inválidos en el campo de tipo "enum" así:
285
Para seleccionar registros con un valor específico de un campo enumerado
usamos "where", por ejemplo, queremos todos los postulantes con estudios
universitarios:
Si el campo está definido como "not null" e intenta almacenar el valor "null"
aparece un mensaje de error y la sentencia no se ejecuta.
Los bytes de almacenamiento del tipo "enum" depende del número de valores
enumerados.
Ejemplo:
Una empresa necesita personal, varias personas se han presentado para cubrir
distintos cargos.
La empresa almacena los datos de los postulantes a los puestos en una tabla
llamada "postulantes". Le interesa, entre otras cosas, conocer los estudios que
tiene cada persona, si tiene estudios primario, secundario, terciario, universitario o
ninguno. Para ello, crea un campo de tipo "enum" con esos valores.
Ingresamos un registro sin especificar valor para "estudios", guardará el valor por
defecto:
286
Vemos el registro ingresado:
select * from postulantes;
Como el campo está definido como "not null", si intentamos almacenar el valor
"null" aparece un mensaje de error y la sentencia no se ejecuta.
insert into postulantes (documento,nombre,sexo,estudios)
values('25676567','Marisa Molina','f',null);
287
insert into postulantes (documento,nombre,sexo,estudios)
values('22333444','Ana Acosta','f','primario');
insert into postulantes (documento,nombre,sexo,estudios)
values('22433444','Mariana Mercado','m','universitario');
insert into postulantes (documento,nombre,sexo)
values('24333444','Luis Lopez','m');
select * from postulantes;
insert into postulantes (documento,nombre,sexo,estudios)
values('2455566','Juana Pereyra','f',5);
insert into postulantes (documento,nombre,sexo,estudios)
values('24678907','Pedro Perez','m','Post Grado');
insert into postulantes (documento,nombre,sexo,estudios)
values('22222333','Susana Pereyra','f',6);
insert into postulantes (documento,nombre,sexo,estudios)
values('25676567','Marisa Molina','f',0);
select * from postulantes
where estudios=0;
select * from postulantes
where estudios='universitario';
insert into postulantes (documento,nombre,sexo,estudios)
values('25676567','Marisa Molina','f',null);
Problema:
288
values ('26333444','Luis Perez','m',1,400);
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('26336444','Marcelo Torres','m',3,460);
Otros problemas:
2- Cree la tabla:
create table viajes(
codigo int unsigned auto_increment,
nombre varchar(50),
pension enum ('no','media','completa') not null,
hotel enum ('1','2','3','4','5'),/* cantidad de estrellas*/
dias tinyint unsigned,
salida date,
precioporpersona decimal(8,2) unsigned,
primary key(codigo)
);
4- Ingrese algunos registros:
insert into viajes (nombre,pension,hotel,dias,salida)
values ('Mexico mágico','completa','4',15,'2005-12-01');
insert into viajes (nombre,pension,hotel,dias,salida)
values ('Europa fantastica','media','5',28,'2005-05-10');
insert into viajes (nombre,pension,hotel,dias,salida)
values ('Caribe especial','no','3',7,'2005-11-25');
289
5- Intente ingresar un valor "null" para el campo "pension":
insert into viajes (nombre,pension,hotel,dias,salida)
values ('Mexico maravilloso',null,'4',15,'2005-12-01');
290
58 - Tipo de dato set.
Puede tener 1 ó más valores que se eligen de una lista de valores permitidos que
se especifican al definir el campo y se separan con comas. Puede tener un
máximo de 64 miembros. Ejemplo: un campo definido como set ('a', 'b') not null,
permite los valores 'a', 'b' y 'a,b'. Si carga un valor no incluido en el conjunto "set",
se ignora y almacena cadena vacía.
Una empresa necesita personal, varias personas se han presentado para cubrir
distintos cargos. La empresa almacena los datos de los postulantes a los puestos
en una tabla llamada "postulantes". Le interesa, entre otras cosas, saber los
distintos idiomas que conoce cada persona; para ello, crea un campo de tipo "set"
en el cual guardará los distintos idiomas que conoce cada postulante.
Para ingresar un valor que contenga más de un elemento del conjunto, se separan
por comas, por ejemplo:
291
Tampoco importa si se repite algún valor, cada elemento repetido, se ignora y se
guarda una vez y en el orden que ha sido definido, por ejemplo, si ingresamos:
Si se ingresa un valor de índice fuera de rango, coloca una cadena vacía. Por
ejemplo:
1='ingles',
2='italiano',
3='ingles,italiano',
4='portugues',
5='ingles,portugues',
6='italiano,portugues',
7='ingles,italiano,portugues'.
292
Para búsquedas de valores en campos "set" se utiliza el operador "like" o la
función "find_in_set()".
Para recuperar todos los valores que contengan la cadena "ingles" podemos usar
cualquiera de las siguientes sentencias:
Para buscar registros que contengan sólo el primer miembro del conjunto "set"
usamos:
Para buscar los registros que contengan el valor "ingles,italiano" podemos utilizar
cualquiera de las siguientes sentencias:
También podemos usar el operador "not". Para recuperar todos los valores que no
contengan la cadena "ingles" podemos usar cualquiera de las siguientes
sentencias:
293
select * from postulantes
where idioma not like '%ingles%';
select * from postulantes
where not find_in_set('ingles',idioma)>0;
Los bytes de almacenamiento del tipo "set" depende del número de miembros, se
calcula así: (cantidad de miembros+7)/8 bytes; entonces puede ser 1,2,3,4 u 8
bytes.
Ejemplo:
Una empresa necesita personal, varias personas se han presentado para cubrir
distintos cargos. La empresa almacena los datos de los postulantes a los puestos
en una tabla llamada "postulantes". Le interesa, entre otras cosas, saber los
distintos idiomas que conoce cada persona; para ello, crea un campo de tipo "set"
en el cual guardará los distintos idiomas que conoce cada postulante.
294
Si ingresamos un valor que no está en la lista "set", se ignora y se almacena una
cadena vacía:
insert into postulantes (documento,nombre,idioma)
values('27555464','Diana Herrero','frances');
También coloca una cadena vacía si ingresamos valore de índice fuera de rango:
insert into postulantes (documento,nombre,idioma)
values('28255265','Pedro Perez',0);
insert into postulantes (documento,nombre,idioma)
values('22255260','Nicolas Duarte',8);
Para localizar los registros que sólo contienen el primer miembro del conjunto "set"
usamos:
select * from postulantes
where idioma='ingles';
295
También podemos buscar por el número de índice:
select * from postulantes
where idioma=1;
Para recuperar todos los valores que NO contengan la cadena "ingles" podemos
usar cualquiera de las siguientes sentencias:
select * from postulantes
where idioma not like '%ingles%';
select * from postulantes
where not find_in_set('ingles',idioma)>0;
296
select * from postulantes
where idioma=1;
select * from postulantes
where idioma=7;
select * from postulantes
where idioma not like '%ingles%';
select * from postulantes
where not find_in_set('ingles',idioma)>0;
Problema:
297
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','lunes,martes,miercoles,jueves,viernes','AM',10,'2006-09-
18',180);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','lunes,viernes','PM',10,'2006-09-25',280);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('JavaScript','lunes,martes,viernes,sabado','PM',12,'2006-09-18',150);
5- Otra persona quiere aprender a diseñar páginas web, tiene disponibles todas
las mañanas excepto los miércoles. Vea si existe algún curso que cumpla con sus
necesidades:
select * from cursos
where tema like '%paginas web%' and
horario='AM' and
dias not like '%miercoles%';
6- Otra persona necesita aprender JavaScript, tiene disponibles todos las tardes
excepto los jueves y quiere un curso que no supere las 15 clases para el mes de
setiembre. Busque algún curso para esta persona:
select * from cursos
where tema='%javascript%' and
horario='PM' and
not find_in_set('jueves',dias)>0 and
clases<=15 and
month(fechainicio)=9;
Otros problemas:
298
3- Ingrese algunos registros:
insert into inmuebles (detalles,precio)
values('terraza,pileta',50000);
insert into inmuebles (detalles,precio)
values('patio,terraza,pileta',60000);
insert into inmuebles (detalles,precio)
values('ascensor,terraza,pileta',80000);
insert into inmuebles (detalles,precio)
values('patio,estacionamiento',65000);
insert into inmuebles (detalles,precio)
values('estacionamiento',90000);
2- Cree la tabla:
create table viajes(
codigo int unsigned auto_increment,
299
nombre varchar(50),
pension enum ('no','media','completa') not null,
ciudades set ('Acapulco','DF','Cancun','Puerto Vallarta','Cuernavaca') not null,
dias tinyint unsigned,
salida date,
precioporpersona decimal(8,2) unsigned,
primary key(codigo)
);
3- Ingrese los siguientes registros:
insert into viajes (nombre,pension,ciudades,dias,salida)
values ('Mexico mágico','completa','DF,Acapulco',15,'2005-12-01');
insert into viajes (nombre,pension,ciudades,dias,salida)
values ('Mexico especial','media','DF,Acapulco,Cuernavaca',28,'2005-05-10');
insert into viajes (nombre,pension,ciudades,dias,salida)
values ('Mexico unico','no','Acapulco,Puerto Vallarta',7,'2005-11-15');
insert into viajes (nombre,pension,ciudades,dias,salida)
values ('Mexico DF','no','DF',5,'2005-10-25');
insert into viajes (nombre,pension,ciudades,dias,salida)
values ('Mexico caribeño','completa','Cancun',15,'2005-10-25');
6- Seleccione todos los viajes que no incluyan "Acapulco" y que incluyan pensión
completa:
select * from viajes
where ciudades not like '%Acapulco%' and
pension='completa';
300
59 - Tipos de datos blob y text.
Los tipos "blob" o "text" son bloques de datos. Tienen una longitud de 65535
caracteres.
Existen subtipos:
Se ingresan los datos en un campo "text" o "blob" como si fuera de tipo cadena de
caracteres, es decir, entre comillas:
301
No se pueden establecer valores por defecto a los campos de tipo "blob" o "text",
es decir, no aceptan la cláusula "default" en la definición del campo.
Ejemplo:
Un video club almacena la información de sus películas en alquiler en una tabla
denominada "peliculas". Además del título, actor y duración de cada película
incluye un campo en el cual guarda la sinopsis de cada una de ellas.
Para buscar todas las películas que en su campo "sinopsis" contengan el texto
"Drama" usamos "like":
302
drop table if exists peliculas;
create table peliculas(
codigo int unsigned auto_increment,
nombre varchar(40),
actor varchar(30),
duracion tinyint unsigned,
sinopsis text,
primary key (codigo)
);
insert into peliculas values(1,'Mentes que brillan','Jodie Foster',120,
'El no entiende al mundo ni el mundo lo entiende a él, es un niño superdotado. La escuela
especial a la que asiste tampoco resuelve los problemas del niño. Su madre hará todo lo que esté
a su alcance para ayudarlo. Drama');
insert into peliculas values(3,'La terminal','Tom Hanks',180, 'Sin papeles y esperando que el
gobierno resuelva su situación migratoria, Victor convierte el aeropuerto de Nueva York en su
nuevo hogar trasformando la vida de los empleados del lugar. Drama');
Problema:
Una inmobiliaria guarda los datos de sus inmuebles en venta en una tabla llamada
"inmuebles".
2- Cree la tabla:
create table inmuebles(
codigo int unsigned auto_increment,
domicilio varchar(30),
barrio varchar(20),
detalles text,
primary key(codigo)
);
3- Ingrsee algunos registros:
insert into inmuebles values(1,'Colon 123','Centro','patio, 3 dormitorios, garage
doble, pileta,
asador, living, cocina, comedor, escritorio, 2 baños');
insert into inmuebles values(2,'Caseros 345','Centro','patio, 2 dormitorios, cocina-
comedor, living');
303
insert into inmuebles values(3,'Sucre 346','Alberdi','2 dormitorios, problemas de
humedad');
insert into inmuebles values(4,'Sarmiento 832','Gral. Paz','3 dormitorios, garage, 2
patios');
insert into inmuebles values(5,'Avellaneda 384','Centro',' 2 patios, 2 dormitorios,
garage');
Otros problemas:
Una librería guarda la información de sus libros en una tabla llamada "libros".
2- Cree la tabla con un campo "blob" en el cual se pueda almacenar los temas
principales que trata
el libro:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(20),
temas blob,
precio decimal(5,2) unsigned,
primary key(codigo)
);
304
insert into libros values(3,'PHP desde cero','Joaquin Perez','Planeta',
'Instalacion de PHP.
Instrucciones basicas.
Definición de variables.', 50);
4- Busque todos los libros sobre "PHP" que incluyan el tema "variables":
select * from libros
where titulo like '%PHP%' and
temas like '%variables%';
No nos interesa el precio exacto de cada libro, sino si el precio es menor o mayor
a $50. Podemos utilizar estas sentencias:
Veamos el ejemplo:
select titulo,
if (precio>50,'caro','economico')
from libros;
305
Si el precio del libro es mayor a 50 (primer argumento del "if"), coloca "caro"
(segundo argumento del "if"), en caso contrario coloca "economico" (tercer
argumento del "if").
Queremos mostrar los nombres de los autores y la cantidad de libros de cada uno
de ellos; para ello especificamos el nombre del campo a mostrar ("autor"),
contamos los libros con "autor" conocido con la función "count()" y agrupamos por
nombre de autor:
El resultado nos muestra cada autor y la cantidad de libros de cada uno de ellos.
Si solamente queremos mostrar los autores que tienen más de 1 libro, es decir, la
cantidad mayor a 1, podemos usar esta sentencia:
Pero si no queremos la cantidad exacta sino solamente saber si cada autor tiene
más de 1 libro, podemos usar "if":
select autor,
if (count(*)>1,'Más de 1','1')
from libros
group by autor;
select editorial,
if (count(*)>4,'5 o más','menos de 5') as cantidad
from libros
group by editorial
order by cantidad;
306
Ejemplo:
Trabajamos con las tablas "libros" de una librería.
Creamos la tabla:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(30),
precio decimal(5,2) unsigned,
primary key (codigo)
);
Ingresamos algunos registros:
insert into libros (titulo, autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',50.5);
insert into libros (titulo, autor,editorial,precio)
values('Alicia a traves del espejo','Lewis Carroll','Emece',25);
insert into libros (titulo, autor,editorial,precio)
values('El aleph','Borges','Paidos',15);
insert into libros (titulo, autor,editorial,precio)
values('Matemática estas ahi','Paenza','Paidos',10);
insert into libros (titulo, autor,editorial)
values('Antologia','Borges','Paidos');
insert into libros (titulo, editorial)
values('El gato con botas','Paidos');
insert into libros (titulo, autor,editorial,precio)
values('Martin Fierro','Jose Hernandez','Emece',90);
No nos interesa el precio exacto de cada libro, sino si el precio es menor o mayor
a $50. Podemos utilizar estas sentencias:
select titulo from libros
where precio<50;
307
Si el precio del libro es mayor a 50 (primer argumento del "if"), coloca "caro"
(segundo argumento del "if"), en caso contrario coloca "economico" (tercer
argumento del "if").
Queremos mostrar los nombres de los autores y la cantidad de libros de cada uno
de ellos; para ello especificamos el nombre del campo a mostrar ("autor"),
contamos los libros con "autor" conocido con la función "count()" y agrupamos por
nombre de autor:
select autor, count(*)
from libros
group by autor;
El resultado nos muestra cada autor y la cantidad de libros de cada uno de ellos.
Si solamente queremos mostrar los autores que tienen más de 1 libro, es decir, la
cantidad mayor a 1, podemos usar esta sentencia:
select autor, count(*)
from libros
group by autor
having count(*)>1;
Pero si no queremos la cantidad exacta sino solamente saber si cada autor tiene
más de 1 libro, podemos usar "if":
select autor,
if (count(*)>1,'Más de 1','1')
from libros
group by autor;
select autor,
if (count(*)>1,'Más de 1','1') as cantidad
from libros
group by autor
order by cantidad;
308
Si la cantidad de libros de cada editorial es mayor a 4 (primer argumento del "if"),
coloca "5 o más" (segundo argumento del "if"), en caso contrario coloca "menos de
5" (tercer argumento del "if"). Además, la sentencia ordena la salida por el alias
"cantidad".
drop table if exists libros;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(30),
precio decimal(5,2) unsigned,
primary key (codigo)
);
insert into libros (titulo, autor,editorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',50.5);
insert into libros (titulo, autor,editorial,precio)
values('Alicia a traves del espejo','Lewis Carroll','Emece',25);
insert into libros (titulo, autor,editorial,precio)
values('El aleph','Borges','Paidos',15);
insert into libros (titulo, autor,editorial,precio)
values('Matemática estas ahi','Paenza','Paidos',10);
insert into libros (titulo, autor,editorial)
values('Antologia','Borges','Paidos');
insert into libros (titulo, editorial)
values('El gato con botas','Paidos');
insert into libros (titulo, autor,editorial,precio)
values('Martin Fierro','Jose Hernandez','Emece',90);
select titulo from libros
where precio<50;
select titulo from libros
where precio >=50;
select titulo,
if (precio>50,'caro','economico')
from libros;
select autor, count(*)
from libros
group by autor;
select autor, count(*)
from libros
group by autor
having count(*)>1;
select autor,
if (count(*)>1,'Más de 1','1')
from libros
group by autor;
select autor,
if (count(*)>1,'Más de 1','1') as cantidad
from libros
group by autor
order by cantidad;
select editorial,
if (count(*)>4,'5 o más','menos de 5') as cantidad
from libros
group by editorial
order by cantidad;
309
Problema:
Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
sexo char(1),
domicilio varchar(30),
fechaingreso date,
fechanacimiento date,
sueldobasico decimal(5,2) unsigned,
primary key(documento)
);
3- Ingrese algunos registros:
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('22333111','Juan Perez','m','Colon 123','1990-02-01','1970-05-10',550,0);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('25444444','Susana Morales','f','Avellaneda 345','1995-04-01','1975-11-
06',650,2);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('20111222','Hector Pereyra','m','Caseros 987','1995-04-01','1965-03-
25',510,1);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('30000222','Luis LUque','m','Urquiza 456','1980-09-01','1980-03-
29',700,3);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('20555444','Maria Laura Torres','f','San Martin 1122','2000-05-15','1965-
12-22',400,3);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
310
values ('30000234','Alberto Soto','m','Peru 232','2003-08-15','1989-10-10',420,1);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('20125478','Ana Gomez','f','Sarmiento 975','2004-06-14','1976-09-
21',350,2);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico,hij
os)
values ('24154269','Ofelia Garcia','f','Triunvirato 628','2004-09-23','1974-05-
12',390,0);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico,hij
os)
values ('304154269','Oscar Torres','m','Hernandez 1234','1996-04-10','1978-05-
02',400,0);
4- Es política de la empresa festejar cada fin de mes, los cumpleaños de todos los
empleados que cumplen ese mes. Si los empleados son de sexo femenino, se les
regala un ramo de rosas, si son de sexo masculino, una corbata. La secretaria de
la Gerencia necesita saber cuántos ramos de rosas y cuántas corbatas debe
comprar para el mes de mayo:
select sexo,count(sexo),
if (sexo='f','rosas','corbata') as 'Obsequio'
from empleados
where month(fechanacimiento)=5
group by sexo;
6- La empresa paga un sueldo adicional por hijos a cargos. para un sueldo básico
menor o igual a $500 el salario familiar por hijo es de $300, para un sueldo
superior, el monto es de $150 por hijo. Muestre el nombre del empleado, el sueldo
básico, la cantidad de hijos a cargo, el valor del salario por hijo, el valor total del
salario familiar y el sueldo final con el salario familiar incluido de todos los
empleados con hijos a cargo:
select nombre,sueldobasico,hijos,
if (sueldobasico<=500,300,150) as salarioporhijo,
if (sueldobasico<=500,300*hijos,150*hijos) as salariofamiliar,
311
if (sueldobasico<=500,sueldobasico+(300*hijos),sueldobasico+(150*hijos)) as
total
from empleados
where hijos>0;
Otros problemas:
2- Cree la tabla:
create table luz(
documento char(8) not null,
domicilio varchar(30),
monto decimal(5,2) unsigned,
vencimiento date
);
3- Ingrese algunos registros con fechas de vencimiento anterior a la fecha actual
(vencidas) y posteriores a la fecha actual (no vencidas).
312
6- Si un usuario tiene más de una boleta vencida se le corta el servicio. Muestre el
documento y la cantidad de boletas vencidas de cada usuario que tenga boletas
vencidas y muestre un mensaje "Cortar servicio" si tiene 2 o más vencidas:
select documento,count(*),
if (count(*)>1,'Cortar servicio','') as 'aa'
from luz
where datediff(current_date,vencimiento)>0
group by documento;
2- cree la tabla:
create table alumnos(
legajo char(5) not null,
nombre varchar(30),
promedio decimal(4,2)
);
3- Ingrese los siguientes registros:
insert into alumnos values(3456,'Perez Luis',8.5);
insert into alumnos values(3556,'Garcia Ana',7.0);
insert into alumnos values(3656,'Ludueña Juan',9.6);
insert into alumnos values(2756,'Moreno Gabriela',4.8);
insert into alumnos values(4856,'Morales Hugo',3.2);
C) Una playa de estacionamiento guarda cada día los datos de los vehículos que
ingresan a la playa
en una tabla llamada "vehiculos".
313
1- Elimine la tabla, si existe.
2- Cree la tabla:
create table vehiculos(
patente char(6) not null,
tipo char(4),
horallegada time not null,
horasalida time,
primary key(patente,horallegada)
);
3- Ingrese algunos registros:
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('ACD123','auto','8:30','9:40');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('AKL098','auto','8:45','15:10');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('HGF123','auto','9:30','18:40');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('DRT123','auto','15:30',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('FRT545','moto','19:45',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('GTY154','auto','20:30','21:00');
314
D) Un teatro con varias salas guarda la información de las entradas vendidas en
una tabla llamada "entradas".
2- Cree la tabla:
create table entradas(
sala tinyint unsigned,
fecha date,
hora time,
capacidad smallint unsigned,
entradasvendidas smallint unsigned,
primary key(sala,fecha,hora)
);
3- Ingrese algunos registros:
insert into entradas values(1,'2006-05-10','20:00',300,50);
insert into entradas values(1,'2006-05-10','23:00',300,250);
insert into entradas values(2,'2006-05-10','20:00',400,350);
insert into entradas values(2,'2006-05-11','20:00',400,380);
insert into entradas values(2,'2006-05-11','23:00',400,400);
insert into entradas values(3,'2006-05-12','20:00',350,350);
insert into entradas values(3,'2006-05-12','22:30',350,100);
insert into entradas values(4,'2006-05-12','20:00',250,0);
4- Muestre todos los registros y un mensaje si las entradas para una función están
agotadas:
select sala,fecha,hora,
if (capacidad=entradasvendidas,'sala llena',capacidad-entradasvendidas) as
'Entradas disponibles'
from entradas;
5- Muestre todos los datos de las funciones que tienen vendidad entradas y
muestre un mensaje si se vendió más o menos de la mitad de la capacidad de la
sala:
select *,
if (entradasvendidas>(capacidad div 2),'mas de la mitad','menos de la mitad
vendidas') as vendidas
from entradas
where entradasvendidas>0;
315
61 - Funciones de control de flujo (case)
La función "case" es similar a la función "if", sólo que se pueden establecer varias
condiciones a cumplir.
select editorial,
if (count(*)>1,'Mas de 2','1') as 'cantidad'
from libros
group by editorial;
vemos los nombres de las editoriales y una columna "cantidad" que especifica si
hay más o menos de uno. Podemos obtener la misma salida usando un "case":
select editorial,
case count(*)
when 1 then 1
else 'mas de 1' end as 'cantidad'
from libros
group by editorial;
case
when then
...
else end
select editorial,
case count(*)
when 1 then 1
end as 'cantidad'
from libros
group by editorial;
316
Con el "if" solamente podemos obtener dos salidas, cuando la condición resulta
verdadera y cuando es falsa, si queremos más opciones podemos usar "case".
Vamos a extender el "case" anterior para mostrar distintos mensajes:
select editorial,
case count(*)
when 1 then 1
when 2 then 2
when 3 then 3
else 'Más de 3' end as 'cantidad'
from libros
group by editorial;
Incluso podemos agregar una cláusula "order by" y ordenar la salida por la
columna "cantidad":
select editorial,
case count(*)
when 1 then 1
when 2 then 2
when 3 then 3
else 'Más de 3' end as 'cantidad'
from libros
group by editorial
order by cantidad;
select editorial,
case count(*)
when 1 then 1
when >1 then 'mas de 1'
end as 'cantidad'
from libros
group by editorial;
case
when then
...
else
end
317
Veamos un ejemplo:
select editorial,
case
when count(*)=1 then 1
else 'mas de uno'
end as cantidad
from libros
group by editorial;
Ejemplo:
Trabajamos con la tabla "libros" de una librería.
Creamos la tabla:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
cantidad smallint unsigned,
primary key(codigo)
);
Ingresamos algunos registros:
insert into libros (titulo,autor,editorial,precio,cantidad)
values('El aleph','Borges','Planeta',34.5,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Carroll L.','Paidos',20.7,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('harry Potter y la camara secreta',null,'Emece',35,500);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Molina Mario','Planeta',54,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Harry Potter y la piedra filosofal',null,'Emece',38,500);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda Java','Molina Mario','Planeta',55,100);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda JavaScript','Molina Mario','Planeta',58,150);
318
else 'mas de 1' end as 'cantidad'
from libros
group by editorial;
Agregamos la cláusula "order by" para ordenar la salida por la columna "cantidad":
select editorial,
case count(*)
when 1 then 1
when 2 then 2
when 3 then 3
else 'Más de 3' end as 'cantidad'
from libros
group by editorial
order by cantidad;
319
Usemos la otra sintaxis de "case":
select editorial,
case when count(*)=1 then 1
else 'mas de 1'
end as 'cantidad'
from libros
group by editorial;
320
select editorial,
case count(*)
when 1 then 1
when 2 then 2
when 3 then 3
else 'Más de 3' end as 'cantidad'
from libros
group by editorial
order by cantidad;
select editorial,
case count(*)
when 1 then 1
when >1 then 'mas de 1'
end as 'cantidad'
from libros
group by editorial;
select editorial,
case when count(*)=1 then 1
else 'mas de 1'
end as 'cantidad'
from libros
group by editorial;
Problema:
2- Cree la tabla:
create table alumnos(
legajo char(5) not null,
nombre varchar(30),
promedio decimal(4,2)
);
3- Ingrese los siguientes registros:
insert into alumnos values(3456,'Perez Luis',8.5);
insert into alumnos values(3556,'Garcia Ana',7.0);
insert into alumnos values(3656,'Ludueña Juan',9.6);
insert into alumnos values(2756,'Moreno Gabriela',4.8);
insert into alumnos values(4856,'Morales Hugo',3.2);
insert into alumnos values(7856,'Gomez Susana',6.4);
321
when 1 then 'reprobado'
when 2 then 'reprobado'
when 3 then 'reprobado'
when 4 then 'regular'
when 5 then 'regular'
when 6 then 'regular'
when 7 then 'promocionado'
when 8 then 'promocionado'
when 9 then 'promocionado'
else 'promocionado'
end as 'estado'
from alumnos;
Otros problemas:
A) Una playa de estacionamiento guarda cada día los datos de los vehículos que
ingresan a la playa en una tabla llamada "vehiculos".
2- Cree la tabla:
create table vehiculos(
patente char(6) not null,
tipo char(4),
horallegada time not null,
horasalida time,
primary key(patente,horallegada)
);
322
values('FRT545','moto','19:45',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('GTY154','auto','20:30','21:00');
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.
323
3- Ingrese algunos registros:
insert into visitas (nombre,mail,fecha)
values ('Ana Maria Lopez','[email protected]','2006-02-10');
insert into visitas (nombre,mail,fecha)
values ('Gustavo Gonzalez','[email protected]','2006-05-10');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-06-11');
insert into visitas (nombre,mail,fecha)
values ('Fabiola Martinez','[email protected]','2006-10-12');
insert into visitas (nombre,mail,fecha)
values ('Fabiola Martinez','[email protected]','2006-09-12');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-12');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-15');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-15');
324
62 - Varias tablas (join)
Hasta ahora hemos trabajado con una sola tabla, pero en general, se trabaja con
varias tablas.
Por ejemplo, los datos de nuestra tabla "libros" podrían separarse en 2 tablas, una
"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 este modo, 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 referente al código de la editorial en la
tabla "libros" y en "editoriales".
325
select * from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo;
Indicamos el nombre de la tabla luego del "from" ("libros"), unimos esa tabla con
"join" y el nombre de la otra tabla ("editoriales"), luego especificamos la condición
para enlazarlas con "on", es decir, el campo por el cual se combinarán. "on" hace
coincidir registros de las dos tablas basándose en el valor de algún campo, en
este ejemplo, los códigos de las editoriales de ambas tablas, el campo
"codigoeditorial" de "libros" y el campo "codigo" de "editoriales" son los que
enlazarán ambas tablas.
326
Entonces, si en las tablas, los campos tienen el mismo nombre, debemos
especificar a cuál tabla pertenece el campo al hacer referencia a él, para ello se
antepone el nombre de la tabla al nombre del campo, separado por un punto (.).
Ejemplo:
Trabajamos con las tablas "libros" y editoriales" de una librería.
327
Cree las siguientes tablas:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) not null default 'Desconocido',
codigoeditorial tinyint unsigned not null,
precio decimal(5,2) unsigned,
cantidad smallint unsigned default 0,
primary key (codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20) not null,
primary key(codigo)
);
Cargamos algunos registros en la tabla "editoriales":
insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Emece');
insert into editoriales (nombre) values('Planeta');
insert into editoriales (nombre) values('Sudamericana');
328
haremos coincidir los registros de las dos tablas, el campo "codigoeditorial" de
"libros" y el campo "codigo" de "editoriales" son los que enlazarán ambas tablas.
Por ello, si hacemos referencia a un campo de una tabla que tiene el mismo
nombre que el campo de la otra tabla consultada, debemos especificar a cuál tabla
pertenece dicho campo.
329
drop table if exists libros, editoriales;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) not null default 'Desconocido',
codigoeditorial tinyint unsigned not null,
precio decimal(5,2) unsigned,
cantidad smallint unsigned default 0,
primary key (codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20) not null,
primary key(codigo)
);
insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Emece');
insert into editoriales (nombre) values('Planeta');
insert into editoriales (nombre) values('Sudamericana');
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('El Aleph','Borges',3,43.5,200);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Alicia en el pais de las maravillas','Lewis Carroll',2,33.5,100);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Aprenda PHP','Mario Perez',1,55.8,50);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Java en 10 minutos','Juan Lopez',1,88,150);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Alicia a traves del espejo','Lewis Carroll',1,15.5,80);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Cervantes y el quijote','Borges- Bioy Casares',3,25.5,300);
select * from libros;
select * from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo;
select * from libros
join editoriales;
select * from libros
join editoriales
on codigoeditorial=codigo;
select * from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
select titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
select l.codigo,titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
select codigo,titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
330
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.
331
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Carlos', 'Irigoyen 888', 'Cruz del Eje',1,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Cordoba',1,'4223366');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas',4,'0457858745');
5- Obtenga la misma información anterior pero ordenada por nombre del cliente:
select c.nombre,c.domicilio,c.ciudad,p.nombre,c.telefono
from clientes as c
join provincias as p
on c.codigoProvincia=p.codigo
order by c.nombre;
Otros problemas:
332
create table inscriptos(
documento char(8) not null,
deporte varchar(15) not null,
año year,
matricula char(1), /*si esta paga ='s' sino 'n'*/
primary key(documento,deporte,año)
);
6- Muestre el nombre de los socios y los deportes en los cuales están inscriptos
este año:
select s.nombre,i.deporte
from socios as s
join inscriptos as i
on s.documento=i.documento
where año=2006;
333
join inscriptos as i
on s.documento=i.documento
where s.documento='23333444';
B) Una pequeña biblioteca de barrio registra los préstamos de sus libros en una
tabla llamada "prestamos" y los datos de sus libros en una tabla llamada "libros".
4- Muestre todos los datos de los préstamos, incluyendo el nombre del libro (join
con "libros"):
select l.titulo,p.*
from prestamos as p
334
join libros as l
on l.codigo=p.codigolibro;
6- Muestre los títulos de los libros, la fecha de préstamo y el documento del socio
de todos los libros que no han sido devueltos:
select l.titulo,p.documento,p.fechaprestamo
from prestamos as p
join libros as l
on l.codigo=p.codigolibro
where p.fechadevolucion is null;
C) Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas" y en otra tabla denominada "obrassociales" almacena los datos de las
obras sociales que atiende.
335
insert into consultas values('2006-08-10','8:00','22333444',1,'Perez');
insert into consultas values('2006-08-10','10:00','22333444',1,'Lopez');
insert into consultas values('2006-08-10','8:30','23333444',1,'Perez');
insert into consultas values('2006-08-10','9:00','24333444',2,'Perez');
insert into consultas values('2006-08-10','10:00','25333444',3,'Perez');
insert into consultas values('2006-08-10','8:30','25333444',1,'Garcia');
insert into consultas values('2006-09-10','8:30','25333444',1,'Lopez');
6- Muestre las obras sociales DISTINTAS que atendió el doctor "Perez" el día
"2006-08-10":
select distinct os.nombre
from consultas as c
join obrassociales as os
on os.codigo=c.codigoobrasocial
where c.fecha='2006-08-10' and
medico='Perez';
63 - Clave foránea.
Un campo que se usa para establecer un "join" (unión) con otra tabla en la cual es
clave primaria, se denomina "clave ajena o foránea".
336
el campo "codigoeditorial" de "libros" es una clave foránea, se emplea para
enlazar la tabla "libros" con "editoriales" y es clave primaria en "editoriales" con el
nombre "codigo".
Cuando alteramos una tabla, debemos tener cuidado con las claves foráneas. Si
modificamos el tipo, longitud o atributos de una clave foránea, ésta puede quedar
inhabilitada para hacer los enlaces.
Las claves foráneas 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.
Ejemplo:
Trabajamos con las tablas "libros" y "editoriales" de una librería.
337
Si modificamos el tipo, longitud o atributos de una clave foránea, ésta puede
quedar inhabilitada para hacer los enlaces.
Veamos un ejemplo:
alter table libros
modify codigoeditorial char(1);
El libro con código de editorial "23" ("Paidos") ahora tiene "2" ("Emece") en
"codigoeditorial" y el libro con código de editorial "15" ("Planeta") ahora almacena
"1" (valor inexistente en "editoriales").
select l.titulo,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
El resultado es erróneo.
Las claves foráneas 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.
338
primary key(codigo)
);
insert into editoriales values(2,'Emece');
insert into editoriales values(15,'Planeta');
insert into editoriales values(23,'Paidos');
insert into libros values(1,'El aleph','Borges',23,4.55,10);
insert into libros values(2,'Alicia en el pais de las maravillas','Lewis Carroll',2,11.55,2);
insert into libros values(3,'Martin Fierro','Jose Hernandez',15,7.12,4);
alter table libros
modify codigoeditorial char(1);
select * from libros;
select l.titulo,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;
alter table editoriales
modify codigo char(1);
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.
339
insert into provincias(codigo,nombre) values(13,'Salta');
insert into provincias(codigo,nombre) values(15,'Buenos Aires');
insert into provincias(codigo,nombre) values(20,'Neuquen');
340
No lo permite porque si la modifica los valores para el campo clave quedan
repetidos.
Otros problemas:
Un club dicta clases de distintos deportes. En una tabla llamada "deportes" guarda
la información de los distintos deportes que se enseñan y en una tabla
denominada "inscriptos" almacena la información necesaria para las inscripciones
a los distintos deportes.
341
6- Actualice la tabla "deportes" almacenando en "codigo" el primer caracter del
nombre del deporte:
update deportes set codigo=left(nombre,1);
8- Realice un "join":
select d.nombre,i.*
from deportes as d
join inscriptos as i
on d.codigo=i.codigodeporte;
No encuentra coincidencia.
Un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con otra
tabla (derecha), pero, si un valor de la tabla de la izquierda no encuentra
342
coincidencia en la tabla de la derecha, se genera una fila extra (una por cada valor
no encontrado) con todos los campos seteados a "null".
La primera sentencia opera así: por cada valor de codigo de "editoriales" busca
coincidencia en la tabla "libros", si no encuentra coincidencia para algún valor,
genera una fila seteada a "null".
Luego del "on" se especifican los campos que se asociarán; no se deben colocar
condiciones en la parte "on" para restringir registros que deberían estar en el
resultado, para ello hay que usar la cláusula "where".
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:
select e.nombre,l.titulo
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
where l.codigoeditorial is not null;
El anterior "left join" muestra los valores de la tabla "editoriales" que están
presentes en la tabla de la derecha ("libros").
343
select e.nombre,l.titulo from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
where l.codigoeditorial is null;
El anterior "left join" muestra los valores de la tabla "editoriales" que no encuentran
correspondencia en la tabla de la derecha, "libros".
Ejemplo:
Trabajamos con las tablas "libros" y editoriales" de una librería.
344
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Cervantes y el quijote','Borges- Bioy Casares',3,25.5,300);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Aprenda Java en 10 minutos','Lopez Juan',5,28,100);
Para obtener la lista de todas las editoriales y los libros de las mismas, incluso de
las cuales no tenemos libros usamos:
select * from editoriales
left join libros
on editoriales.codigo=libros.codigoeditorial;
Un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con otra
tabla (derecha), pero, 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 seteados a "null".
Para encontrar los valores de código de la tabla "editoriales" que están presentes
en la tabla "libros" usamos un "where":
select nombre,titulo
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
where l.codigoeditorial is not null;
345
Para mostrar las editoriales que no están presentes en "libros":
select e.nombre,l.titulo from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
where l.codigoeditorial is null;
346
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.
347
values ('Lopez Carlos', 'Irigoyen 888', 'Cruz del Eje',1,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Cordoba',1,'4223366');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas',4,'0457858745');
Otros problemas:
348
matricula char(1), /*si esta paga ='s' sino 'n'*/
primary key(documento,deporte,año)
);
B) Un club de barrio realiza una rifa anual y guarda los datos de las rifas en dos
tablas, una denominada "premios" y otra llamada "numerosrifa".
349
create table premios(
posicion tinyint unsigned auto_increment,
premio varchar(20),
numeroganador tinyint unsigned,
primary key(posicion)
);
create table numerosrifa(
numero tinyint unsigned not null,
documento char(8) not null,
primary key(numero)
);
3- Ingrese algunos registros:
insert into premios values(1,'PC Pentium',205);
insert into premios values(2,'Televisor 21 pulgadas',29);
insert into premios values(3,'Microondas',5);
insert into premios values(4,'Multiprocesadora',15);
insert into premios values(5,'Cafetera',33);
note que la posición "5" no aparece en la lista porque el número ganador de esa
posición no fue vendido, no se encuentra en la tabla "premios". Y note que los
números vendidos que no ganaron tiene la fila seteada a "null".
5- Muestre los mismos datos anteriores pero teniendo en cuenta los números
ganadores solamente:
select nr.numero,p.posicion,p.premio
from numerosrifa as nr
left join premios as p
on p.numeroganador=nr.numero
where p.numeroganador is not null;
350
6- Realice un "left join" pero en esta ocasión busque los números ganadores de la
tabla "premios" en la tabla "numerosrifa":
select nr.numero,p.posicion,p.premio
from premios as p
left join numerosrifa as nr
on p.numeroganador=nr.numero;
7- Realice el mismo "join" anterior pero sin considerar los valores de "premios" que
no encuentren coincidencia en "numerosrifa".
select nr.numero,p.posicion,p.premio
from premios as p
left join numerosrifa as nr
on p.numeroganador=nr.numero
where nr.numero is not null;
select nombre,titulo
from libros as l
right join editoriales as e
on e.codigo=l.codigoeditorial;
La primera busca valores de "codigo" de la tabla "editoriales" (tabla de la
izquierda) coincidentes con los valores de "codigoeditorial" de la tabla "libros"
(tabla de la derecha). La segunda busca valores de la tabla de la derecha
coincidentes con los valores de la tabla de la izquierda.
351
Ejemplo:
Trabajamos con las tablas "libros" y editoriales" de una librería.
352
select nombre,titulo
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial;
Esta sentencia busca los nombres de las editoriales que están presentes en
"libros". Podemos realizar la búsqueda de modo inverso con "right join":
select nombre,titulo
from libros as l
right join editoriales as e
on e.codigo=l.codigoeditorial;
La primera, con "left join", busca valores de "codigo" de la tabla "editoriales" (tabla
de la izquierda) coincidentes con los valores de "codigoeditorial" de la tabla "libros"
(tabla de la derecha). La segunda, con "right join", busca valores de
"codigoeditorial" de la tabla "libros" (tabla de la derecha) coincidentes con los
valores de "codigo" de la tabla "editoriales" (tabla de la izquierda).
353
on e.codigo=l.codigoeditorial;
select nombre,titulo
from libros as l
right join editoriales as e
on e.codigo=l.codigoeditorial;
Problema:
Un club dicta clases de distintos deportes. En una tabla llamada "socios" guarda
los datos de sus socios y en una tabla denominada "inscriptos" almacena la
información necesaria para las inscripciones de los socios a los distintos deportes.
354
on s.documento=i.documento;
Note que el socio que no está inscripto en ningún deporte tiene la fila seteada a
"null".
El restaurante quiere combinar los registros de ambas tablas para mostrar los
distintos menúes que ofrece. Podemos usar "cross join":
select c.*,p.*
from comidas as c
cross join postres as p;
select c.*,p.*
from comidas as c
join postres as p;
355
Podemos organizar la salida del "cross join" para obtener el nombre del plato
principal, del postre y el precio total de cada combinación (menú):
select c.nombre,p.nombre,
c.precio+p.precio as total
from comidas as c
cross join postres as p;
Si los datos de las tablas anteriores ("comidas" y "postres") estuvieran en una sola
tabla con la siguiente estructura:
select c1.nombre,c1.precio,c2.nombre,c2.precio
from comidas as c1
cross join comidas as c2
where c1.rubro='plato principal' and
c2.rubro='postre';
select c1.nombre,c2.nombre,
c1.precio+c2.precio as total
from comidas as c1
cross join comidas as c2
where c1.rubro='plato principal' and
c2.rubro='postre';
Ejemplo:
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.
356
Eliminamos dichas tablas, si existen:
drop table if exists comidas, postres;
retorna el mismo resultado que un simple "join" sin parte "on", es decir, si
condición de enlace:
select c.*,p.*
from comidas as c
join postres as p;
Para obtener el nombre del plato principal, del postre y el precio total de cada
combinación (menú) tipeamos la siguiente sentencia:
select c.nombre,p.nombre,
c.precio+p.precio as total
from comidas as c
cross join postres as p;
357
Hemos aprendido que para realizar un "join" no es necesario utilizar 2 tablas,
podemos combinar los registros de una misma tabla.
Note que utilizamos 2 alias para la misma tabla y empleamos un "where" para
combinar el "plato principal" con el "postre".
358
drop table if exists comidas, postres;
create table comidas(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
precio decimal(4,2) unsigned,
primary key (codigo)
);
create table postres(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
precio decimal(4,2) unsigned,
primary key (codigo)
);
insert into comidas values(1,'milanesa y fritas',3.4);
insert into comidas values(2,'arroz primavera',2.5);
insert into comidas values(3,'pollo',2.8);
359
Problema:
4- La empresa quiere que todos sus empleados realicen todas las tareas. Realice
una "cross join":
select nombre,t.domicilio,descripcion
from guardias
cross join tareas as t;
Devuelve el producto cartesiano de ambas tablas, combina todos los registros de
una tabla con todos los registros de la otra.
360
5- Obtenga la misma salida realizando un simple "join" sin parte "on":
select nombre,t.domicilio,descripcion
from guardias
join tareas as t;
Otros problemas:
2- Cree la tabla:
create table equipos(
nombre varchar(30),
barrio varchar(20),
domicilio varchar(30),
entrenador varchar(30)
);
3- Ingrese los siguientes registros:
insert into equipos values('Los tigres','Gral. Paz','Sarmiento 234','Juan Lopez');
insert into equipos values('Los leones','Centro','Colon 123','Gustavo Fuentes');
insert into equipos values('Campeones','Pueyrredon','Guemes 346','Carlos
Moreno');
insert into equipos values('Cebollitas','Alberdi','Colon 1234','Luis Duarte');
4- Cada equipo jugará con todos los demás 2 veces, una vez en cada sede.
Realice un "cross join" para combinar los equipos teniendo en cuenta que un
equipo no juega consigo mismo:
select e1.nombre,e2.nombre,e1.barrio as 'sede'
from equipos as e1
cross join equipos as e2
where e1.nombre<>e2.nombre;
361
1- Elimine la tabla si existe:
2- Cree la tabla:
create table clientes(
nombre varchar(30),
domicilio varchar(30),
sexo char(1),
edad tinyint unsigned
);
3- Ingrese los siguientes registros:
insert into clientes (nombre,sexo,edad) values('Juan Perez','m',45);
insert into clientes (nombre,sexo,edad) values('Ana Lopez','f',50);
insert into clientes (nombre,sexo,edad) values('Federico Herrero','m',30);
insert into clientes (nombre,sexo,edad) values('Mariano Juarez','m',35);
insert into clientes (nombre,sexo,edad) values('Maria Torres','f',36);
insert into clientes (nombre,sexo,edad) values('Ines Duarte','f',55);
insert into clientes (nombre,sexo,edad) values('Alejandra Figueroa','f',40);
6- Se pide, además, que las edades de las posibles parejas no tengan una
diferencia superior a 10 años:
select c1.nombre,c1.edad,c1.sexo, c2.nombre,c2.edad,c2.sexo
from clientes as c1
cross join clientes as c2
where c1.sexo='f' and c2.sexo='m' and
c2.edad - c1.edad between -10 and 10;
362
67 - Varias tablas (natural join)
"natural join" se usa cuando los campos por los cuales se enlazan las tablas tienen
el mismo nombre.
select titulo,nombre
from libros as l
natural join editoriales as e;
select titulo,nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigoeditorial;
select nombre,titulo
from editoriales as e
natural left join libros as l;
select nombre,titulo
from editoriales as e
left join libros as l
on e.codigoeditorial=l.codigoeditorial;
Es decir, con "natural join" no se coloca la parte "on" que especifica los campos
por los cuales se enlazan las tablas, porque MySQL busca los campos con igual
nombre y enlaza las tablas por ese campo.
363
Hay que tener cuidado con este tipo de "join" porque si ambas tablas tiene más de
un campo con igual nombre, MySQL no sabrá por cual debe realizar la unión. Por
ejemplo, si el campo "titulo" de la tabla "libros" se llamara "nombre", las tablas
tendrían 2 campos con igual nombre ("codigoeditorial" y "nombre").
Otro problema que puede surgir es el siguiente. Tenemos la tabla "libros" con los
siguientes campos: codigo (del libro), titulo, autor y codigoeditorial, y la tabla
"editoriales" con estos campos: codigo (de la editorial) y nombre. Si usamos
"natural join", unirá las tablas por el campo "codigo", que es el campo que tienen
igual nombre, pero el campo "codigo" de "libros" no hace referencia al código de la
editorial sino al del libro, así que la salida será errónea.
Ejemplo:
Trabajamos con las tablas "libros" y editoriales" de una librería.
364
Como en ambas tablas, el código de la editorial se denomina "codigoeditorial",
podemos omitir la parte "on" que indica los nombres de los campos por el cual se
enlazan las tablas, empleando "natural join", se unirán por el campo que tienen en
común:
select titulo,nombre
from libros as l
natural join editoriales as e;
Hay que tener cuidado con este tipo de "join" porque si ambas tablas tiene más de
un campo con igual nombre, MySQL no sabrá por cual debe realizar la unión.
Ahora las tablas tienen 2 campos con igual nombre ("codigoeditorial" y "nombre").
Intentemos realizar un "natural join":
select l.nombre,e.nombre
from libros as l
natural join editoriales as e;
No hay salida.
365
alter table editoriales change codigoeditorial codigo tinyint unsigned
auto_increment;
Si usamos "natural join", unirá las tablas por el campo "codigo", que es el campo
que tienen igual nombre, pero el campo "codigo" de "libros" no hace referencia al
código de la editorial sino al del libro, así que la salida será errónea:
select l.*,e.*
from libros as l
natural join editoriales as e;
Note que el libro con código "3" de editorial "Planeta" aparece como perteneciente
a la editorial "Paidos" (código 3) porque buscó coincidencia del código del libro con
el código de editorial.
366
on e.codigoeditorial=l.codigoeditorial;
alter table libros change titulo nombre varchar(40);
select l.nombre,e.nombre
from libros as l
natural join editoriales as e;
alter table libros change nombre titulo varchar(40);
alter table editoriales change codigoeditorial codigo tinyint unsigned auto_increment;
select l.*,e.*
from libros as l
natural join editoriales as e;
Problema:
Un club dicta clases de distintos deportes. En una tabla llamada "socios" guarda
los datos de sus socios y en una tabla denominada "inscriptos" almacena la
información necesaria para las inscripciones de los socios a los distintos deportes.
367
4- Realice un "natural join" de ambas tablas:
select nombre,i.*
from socios as s
natural join inscriptos as i;
"inner join" es igual que "join". Con "inner join", todos los registros no coincidentes
son descartados, sólo los coincidentes se muestran en el resultado:
select nombre,titulo
from editoriales as e
inner join libros as l
on e.codigo=l.codigoeditorial;
368
select nombre,titulo
from editoriales as e
join libros as l
on e.codigo=l.codigoeditorial;
"straight join" es igual a "join", sólo que la tabla de la izquierda es leída siempre
antes que la de la derecha.
Para ver todas las editoriales, agrupadas por nombre, con una columna llamada
"Cantidad de libros" en la que aparece la cantidad calculada con "count()" de todos
los libros de cada editorial tipeamos:
Si usamos "left join" la consulta mostrará todas las editoriales, y para cualquier
editorial que no encontrara coincidencia en la tabla "libros" colocará "0" en
"Cantidad de libros". Si usamos "join" en lugar de "left join":
solamente mostrará las editoriales para las cuales encuentra valores coincidentes
para el código de la editorial en la tabla "libros".
Para conocer el mayor precio de los libros de cada editorial usamos la función
"max()", hacemos una unión y agrupamos por nombre de la editorial:
select e.nombre,
max(l.precio) as 'Mayor precio'
from editoriales as e
left join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;
369
En la sentencia anterior, mostrará, para la editorial de la cual no haya libros, el
valor "null" en la columna calculada; si realizamos un simple "join":
select e.nombre,
max(l.precio) as 'Mayor precio'
from editoriales as e
join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;
sólo mostrará las editoriales para las cuales encuentra correspondencia en la tabla
de la derecha.
Ejemplo:
Trabajamos con la tabla "libros" y "editoriales" de una librería.
370
Para ver todas las editoriales, agrupadas por nombre, con una columna llamada
"cantidad de libros" en la que aparece la cantidad calculada con "count()" de todos
los libros de cada editorial tipeamos:
select e.nombre,count(l.codigoeditorial) as 'cantidad de libros'
from editoriales as e
left join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;
Note que como usamos "left join" la consulta muestra todas las editoriales, y para
la editorial que no encuentra coincidencia en "libros" coloca "0" en "cantidad de
libros". Si usáramos "join" en lugar de "left join":
solamente muestra las editoriales para las cuales encuentra valores coincidentes
para el código de la editorial en "libros".
Para conocer el mayor precio de los libros de cada editorial usamos la función
"max()", hacemos un "join" y agrupamos por nombre de la editorial:
select e.nombre,
max(l.precio) as 'mayor precio'
from editoriales as e
left join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;
select e.nombre,
max(l.precio) as 'mayor precio'
from editoriales as e
join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;
371
drop table if exists libros,editoriales;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) not null default 1,
codigoeditorial tinyint unsigned not null,
precio decimal(5,2) unsigned,
primary key (codigo)
);
create table editoriales (
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key (codigo)
);
insert into editoriales (nombre) values ('Planeta');
insert into editoriales (nombre) values ('Emece');
insert into editoriales (nombre) values ('Paidos');
Problema:
Una empresa tiene registrados sus clientes en una tabla llamada "clientes",
también tiene una
372
tabla "provincias" donde registra los nombres de las provincias de las cuales son
oriundos los clientes.
373
values ('Pereyra Lucas', 'San Martin 555', 'Cruz del Eje',1,'4253685');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Gomez Ines', 'San Martin 666', 'Santa Fe',2,'0345252525');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Torres Fabiola', 'Alem 777', 'Villa del Rosario',1,'4554455');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Carlos', 'Irigoyen 888', 'Cruz del Eje',1,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Cordoba',1,'4223366');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas',4,'0457858745');
374
Otros problemas:
A) 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.
375
values ('Roberto Perez',45,'m','Urquiza 335',1,'4123456',33.20);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Marina Torres',22,'f','Colon 222',3,'03544112233',25);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Julieta Gomez',24,'f','San Martin 333',2,'03547121212',53.50);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Roxana Lopez',20,'f','Triunvirato 345',2,null,0);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Liliana Garcia',50,'f','Paso 999',1,'4588778',48);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Juan Torres',43,'m','Sarmiento 876',1,'4988778',15.30);
376
1- Elimine las tablas si existen.
377
from departamentos as d
join barrios as b
on d.codigobarrio=b.codigo
group by edificio;
378
insert into peliculas (titulo,actores,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actores,duracion)
values('Mision imposible 2','Tom Cruise',180);
insert into peliculas (titulo,actores,duracion)
values('Harry Potter y la piedra filosofal','Daniel H.',120);
insert into peliculas (titulo,actores,duracion)
values('Harry Potter y la camara secreta','Daniel H.',150);
379
6- Muestre la cantidad de películas que alquiló cada socio:
select socio,count(a.codigopelicula) from alquileres
group by socio;
8- Muestre la cantidad de películas alquiladas por mes por cada socio ordenado
por mes:
select socio,
monthname(a.fechaprestamo) as mes,
count(a.codigopelicula)
from alquileres
group by socio, mes
order by mes;
Una biblioteca registra la información de sus libros en una tabla llamada "libros",
los datos de sus socios en "socios" y los préstamos en una tabla "prestamos".
380
Al recuperar los datos de los prestamos:
aparece el código del libro pero no sabemos el nombre y tampoco el nombre del
socio sino su documento. Para obtener los datos completos de cada préstamo,
incluyendo esos datos, necesitamos consultar las tres tablas.
select nombre,titulo,fechaprestamo
from prestamos as p
join socios as s
on s.documento=p.documento
join libros as l
on codigolibro=codigo;
Para ver todos los prestamos, incluso los que no encuentran coincidencia en las
otras tablas, usamos:
select nombre,titulo,fechaprestamo
from prestamos as p
left join socios as s
on p.documento=s.documento
left join libros as l
on l.codigo=p.codigolibro;
Podemos ver aquellos prestamos con valor coincidente para "libros" pero para
"socio" con y sin coincidencia:
select nombre,titulo,fechaprestamo
from prestamos as p
381
left join socios as s
on p.documento=s.documento
join libros as l
on p.codigolibro=l.codigo;
Ejemplo:
Una biblioteca registra la información de sus libros en una tabla llamada "libros",
los datos de sus socios en "socios" y los préstamos en una tabla "prestamos".
382
insert into prestamos values('25333444',25,'2006-08-15',null);
insert into prestamos values('30333444',42,'2006-08-02','2006-08-05');
insert into prestamos values('25333444',2,'2006-08-02','2006-08-05');
aparece el código del libro pero no sabemos el nombre y tampoco el nombre del
socio sino su documento. Para obtener los datos completos de cada préstamo,
incluyendo esos datos, necesitamos consultar las tres tablas.
Muestra todos los prestamos para los cuales encuentra coincidencia en "socios" y
"libros".
Para ver todos los prestamos, incluso los que no encuentran coincidencia en las
otras tablas, usamos:
select nombre,titulo,fechaprestamo
from prestamos as p
left join socios as s
on p.documento=s.documento
left join libros as l
on l.codigo=p.codigolibro;
Note que también se muestran aquellos prestamos para los cuales no se encontró
coincidencia en "libros" y "socios", es decir, hay un código de libro ingresado en
"prestamos" que no existe en la tabla "libros", esa fila está seteada a "null" en
"titulo"; también hay un préstamo con un documento que no está en la tabla
"socios", esa fila contiene "null" en "nombre".
Podemos ver aquellos prestamos con valor coincidente para "libros" pero para
"socio" con y sin coincidencia:
select nombre,titulo,fechaprestamo
from prestamos as p
left join socios as s
on p.documento=s.documento
join libros as l
on p.codigolibro=l.codigo;
383
Note que el préstamo con código de libro inexistente en la tabla "libros" ya no
aparece.
drop table if exists libros,socios,prestamos;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(20) default 'Desconocido',
primary key (codigo)
);
create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key (documento)
);
create table prestamos(
documento char(8) not null,
codigolibro int unsigned,
fechaprestamo date not null,
fechadevolucion date,
primary key (codigolibro,fechaprestamo)
);
insert into socios values('22333444','Juan Perez','Colon 345');
insert into socios values('23333444','Luis Lopez','Caseros 940');
insert into socios values('25333444','Ana Herrero','Sucre 120');
384
Problema:
Un video club que alquila películas en video guarda información de sus películas
en alquiler, sus
socios y los alquileres en 3 tablas llamadas "peliculas", "socios" y "alquileres"
respectivamente.
385
insert into socios (documento,nombre)
values('24333444','Luis Fuentes');
386
7- Muestre la cantidad de películas DISTINTAS que alquiló cada socio:
select s.nombre,count(distinct a.codigopelicula) from socios as s
join alquileres as a
on s.codigo=a.codigosocio
group by s.nombre;
8- Muestre la cantidad de películas alquiladas por mes por cada socio ordenado
por mes:
select s.nombre,
monthname(a.fechaprestamo) as mes,
count(a.codigopelicula)
from socios as s
join alquileres as a
on s.codigo=a.codigosocio
group by s.nombre, mes
order by mes;
Otros problemas:
387
insert into socios values('24333444','Hector Fuentes');
insert into socios values('25333444','Marta Molina');
5- Muestre los nombres de todos los socios y el nombre de los deportes en los
cuales se han inscripto, incluso, si no se ha incripto en ninguno:
select s.nombre,d.nombre
from socios as s
left join inscriptos as i
on s.documento=i.documento
left join deportes as d
on d.codigo=i.codigodeporte;
6- Muestre todos los deportes y los nombres de los socios inscriptos, incluso para
aquellos que no tienen socios inscriptos:
select d.nombre,s.nombre
from deportes as d
left join inscriptos as i
on d.codigo=i.codigodeporte
left join socios as s
on s.documento=i.documento;
388
left join inscriptos as i
on d.codigo=i.codigodeporte
left join socios as s
on s.documento=i.documento
group by d.nombre;
389
insert into materias values(2,1,'Sistemas de datos I','Bernardo Garcia');
insert into materias values(3,1,'Ingles tecnico','Edit Torres');
insert into materias values(1,2,'Programacion basica','Alfredo Lopez');
insert into materias values(2,2,'Ingles I','Edit Torres');
insert into materias values(3,2,'Protocolos','Hector Juarez');
6- Muestre todos los datos de la tabla "inscriptos" (sin códigos) incluyendo los
nombres de las materias y carreras ordenado por nombre de carrera y nombre de
materia:
select i.documento,c.nombre,m.nombre,año,cuota
from inscriptos as i
join carreras as c
on c.codigo=i.codigocarrera
join materias as m
on m.codigo=i.codigomateria and
m.codigocarrera=c.codigo
order by c.nombre,c.nombre;
Note que unimos "inscriptos" con "carreras" por el código de la carrera, "inscriptos"
con "materias" por el código de la materia y "carreras" con "materias" por el código
de la carrera; si olvidamos el último enlace, se combinarán todos los códigos de
carreras con todos los códigos de materias.
390
7- Muestre la cantidad de alumnos que tiene cada profesor (hay profesores que
dictan varias materias en distintas carreras):
select m.profesor,count(*)
from inscriptos as i
join carreras as c
on c.codigo=i.codigocarrera
join materias as m
on m.codigo=i.codigomateria and
m.codigocarrera=c.codigo
group by m.profesor;
8- Muestre la cantidad de alumnos inscriptos en cada materia de cada carrera:
select c.nombre,m.nombre,count(i.codigomateria)
from carreras as c
join materias as m
on c.codigo=m.codigocarrera
left join inscriptos as i
on m.codigo=i.codigomateria and
c.codigo=i.codigocarrera
group by c.nombre,m.nombre;
Note que usamos "left join" para mostrar todas las materias, incluso para aquellas
en las cuales no hay inscriptos.
9- Muestre el documento de los alumnos y la cantidad de materias por carrera en
las que se ha inscripto cada uno de ellos:
select i.documento,c.nombre,
count(i.codigomateria) as materias
from carreras as c
join materias as m
on c.codigo=m.codigocarrera
join inscriptos as i
on m.codigo=i.codigomateria and
c.codigo=i.codigocarrera
group by i.documento,c.nombre;
391
71 - Función de control if con varias tablas.
Por ejemplo, tenemos las tablas "libros" y "editoriales" y queremos saber si hay
libros de cada una de las editoriales:
select e.nombre,
if (count(l.codigoeditorial)>0,'Si','No') as hay
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
select e.nombre,
case count(l.codigoeditorial)
when 0 then 'No'
else 'Si' end as 'Hay'
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
Ejemplo:
Trabajamos con las tablas "libros" y "editoriales" de una librería.
392
Ingresamos algunos registros para la tabla "editoriales":
insert into editoriales (nombre) values ('Planeta');
insert into editoriales (nombre) values ('Emece');
insert into editoriales (nombre) values ('Paidos');
393
insert into editoriales (nombre) values ('Planeta');
insert into editoriales (nombre) values ('Emece');
insert into editoriales (nombre) values ('Paidos');
select e.nombre,
if (count(l.codigoeditorial)>0,'Si','No') as hay
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
select e.nombre,
case count(l.codigoeditorial)
when 0 then 'No'
else 'Si' end as 'Hay'
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
Problema:
394
insert into alumnos values('25222111','Hector Paz');
insert into notas values('22333444',7);
insert into notas values('23555666',8);
insert into notas values('24000333',3);
insert into notas values('25222111',7);
insert into notas values('22333444',7);
insert into notas values('23555666',9);
insert into notas values('24000333',4);
insert into notas values('22333444',6);
insert into notas values('23555666',10);
insert into notas values('24000333',3);
insert into notas values('25222111',9);
insert into notas values('23555666',10);
395
join notas as n
on a.documento=n.documento
group by n.documento
order by 'cantidad de notas';
72 - Variables de usuario.
Para obtener todos los datos del libro podemos emplear una variable para
almacenar el precio más alto:
y luego mostrar todos los datos de dicho libro empleando la variable anterior:
Las variables de usuario son específicas de cada conexión, es decir, una variable
definida por un cliente no puede ser vista ni usada por otros clientes y son
liberadas automáticamente al abandonar la conexión.
Las variables de usuario comienzan con "@" (arroba) seguido del nombre (sin
espacios), dicho nombre puede contener cualquier caracter.
En el ejemplo, mostramos todos los datos del libro com precio más alto, pero, si
además, necesitamos el nombre de la editorial podemos emplear un "join":
select l.titulo,l.autor,e.nombre
from libros as l
396
join editoriales as e
on l.codigoeditorial=e.codigo
where l.precio = @mayorprecio;
Por ejemplo, queremos ver todos los libros de la editorial que tenga el libro más
caro. Debemos buscar el precio más alto y almacenarlo en una variable, luego
buscar el nombre de la editorial del libro con el precio igual al valor de la variable y
guardarlo en otra variable, finalmente buscar todos los libros de esa editorial:
select @editorial:=e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
where precio=@mayorprecio;
select l.titulo,l.autor,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
where e.nombre=@editorial;
Ejemplo:
Trabajamos con la tabla "libros" y "editoriales" de una librería.
397
Ingresamos algunos registros:
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');
Queremos ver todos los libros de la editorial que tenga el libro más caro.
398
where e.nombre=@editorial;
399
Problema:
Un video club que alquila películas en video guarda información de sus películas
en la
tabla "peliculas".
400
73 - Crear tabla a partir de otra (create - insert)
Tenemos la tabla "libros" de una librería y queremos crear una tabla llamada
"editoriales" que contenga los nombres de las editoriales.
2º paso: realizar la consulta en la tabla "libros" para obtener los nombres de las
distintas editoriales:
editorial
_________
Emece
Paidos
Planeta
401
3º paso: insertar los registros necesarios en la tabla "editoriales":
Pero existe otra manera simplificando los pasos. Podemos crear la tabla
"editoriales" con los campos necesarios consultando la tabla "libros" y en el mismo
momento insertar la información:
nombre
______
Emece
Paidos
Planeta
También podemos crear una tabla a partir de una consulta cargando los campos
con los valores de otra tabla y una columna calculada. Veamos un ejemplo.
402
Podemos lograrlo en 3 pasos:
select editorial,count(*)
from libros
group by editorial;
nombre cantidad
________________
Emece 3
Paidos 4
Planeta 2
Pero existe otra manera simplificando los pasos. Podemos crear la tabla
"cantidadporeditorial" con los campos necesarios consultando la tabla "libros" y en
el mismo momento insertar la información:
403
Si seleccionamos todos los registros de la tabla "cantidadporeditorial" aparece lo
siguiente:
nombre cantidad
_______________________
Emece 3
Paidos 4
Planeta 2
Ejemplo:
Tenemos la tabla "libros" de una librería y queremos crear una tabla llamada
"editoriales" que contenga los nombres de las editoriales.
No la creamos aún.
404
insert into libros values (9,'Antologia poetica','Borges','Paidos',47.9);
vemos que el campo "nombre" se creó con el mismo tipo y longitud del campo
"editorial" de "libros".
También podemos crear una tabla a partir de una consulta cargando los campos
con los valores de otra tabla y una columna calculada.
No la creamos aún.
405
Crearemos la tabla "cantidadporeditorial" con los campos necesarios consultando
la tabla "libros" y en el mismo momento insertaremos los registros:
create table cantidadporeditorial
select editorial as nombre,count(*) as cantidad
from libros
group by editorial;
406
Problema:
407
7- Cree la tabla "montofacturas" a partir de la consulta anterior:
create table montofacturas
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;
408
1º paso: crear la tabla "cantidadporeditorial":
select e.nombre,count(*)
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
group by e.nombre;
nombre cantidad
___________________
Emece 3
Paidos 4
Planeta 2
Pero existe otra manera simplificando los pasos. Podemos crear la tabla
"cantidadporeditorial" con los campos necesarios consultando la tabla "libros" y
"editoriales" y en el mismo momento insertar la información:
409
Entonces, se realiza una consulta de la tabla "libros" y "editoriales" (con un "join")
anteponiendo "create table ..." se ingresa el resultado de dicha consulta en la tabla
"cantidadporeditorial" al momento de crearla.
nombre cantidad
_______________________
Emece 3
Paidos 4
Planeta 2
Ejemlo:
Tenemos la tabla "libros" de una librería y queremos crear una tabla llamada
"editoriales" que contenga los nombres de las editoriales.
No la creamos aún.
410
insert into libros values (7,'Aprenda Java','Mario Molina','Paidos',55.4);
insert into libros values (8,'Alicia a traves del espejo','Lewis Carroll','Emece',18);
insert into libros values (9,'Antologia poetica','Borges','Paidos',47.9);
vemos que el campo "nombre" se creó con el mismo tipo y longitud del campo
"editorial" de "libros".
También podemos crear una tabla a partir de una consulta cargando los campos
con los valores de otra tabla y una columna calculada.
No la creamos aún.
411
Pero lo haremos de la manera simplificada.
describe cantidadporeditorial;
412
Problema:
413
7- Cree la tabla "montofacturas" a partir de la consulta anterior:
create table montofacturas
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;
Otros problemas:
A) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".
2- Cree la tabla:
create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
sexo char(1),
domicilio varchar(30),
fechaingreso date,
primary key(documento)
);
3- Ingrese algunos registros:
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('22333111','Juan Perez','m','Colon 123','1990-02-01');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('25444444','Susana Morales','f','Avellaneda 345','1995-04-01');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('20111222','Hector Pereyra','m','Caseros 987','1995-04-01');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('30000222','Luis Luque','m','Urquiza 456','1980-09-01');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('20555444','Maria Laura Torres','f','San Martin 1122','2000-05-15');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('30000234','Alberto Soto','m','Peru 232','2003-08-15');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('20125478','Ana Gomez','f','Sarmiento 975','2004-06-14');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
values ('24154269','Ofelia Garcia','f','Triunvirato 628','2004-09-23');
insert into empleados (documento,nombre,sexo,domicilio,fechaingreso)
414
values ('30154269','Oscar Mendez','m','Colon 1245','2004-06-23');
2- Cree la tabla:
create table inscriptos(
documento char(8) not null,
deporte varchar(20) not null,
año year not null,
cuota char(1), /*'s' o 'n', si esta paga o no*/
primary key(documento,deporte,año)
);
3- Ingrese los siguientes registros:
insert into inscriptos values('22333444','tenis','2005','s');
insert into inscriptos values('22333444','tenis','2006','s');
insert into inscriptos values('22333444','natacion','2005','s');
insert into inscriptos values('24333444','tenis','2005','s');
insert into inscriptos values('24333444','natacion','2006','s');
insert into inscriptos values('25333444','tenis','2005','s');
insert into inscriptos values('25333444','tenis','2006','s');
insert into inscriptos values('25333444','basquet','2006','s');
4- El club desea saber cuántos socios se han inscripto en cada deporte cada año:
415
select deporte,año,count(*)
from inscriptos
group by deporte,año;
2- Cree la tabla:
create table cursos(
codigo tinyint unsigned auto_increment,
tema varchar(20) not null,
dias set ('lunes','martes','miercoles','jueves','viernes','sabado') not null,
horario enum ('AM','PM') not null,
clases tinyint unsigned,
416
fechainicio date,
costo decimal(5,2) unsigned,
primary key(codigo)
);
3- Ingrese los siguientes registros:
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('PHP básico','lunes,martes,miercoles','AM',18,'2006-08-07',200);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('PHP básico','lunes,martes,miercoles','PM',18,'2006-08-14',200);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('PHP básico','sabado','AM',18,'2006-08-05',280);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('PHP avanzado','martes,jueves','AM',20,'2006-08-01',350);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('JavaScript','lunes,martes,miercoles','PM',15,'2006-09-11',150);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','martes,jueves','PM',10,'2006-08-08',250);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','sabado','AM',10,'2006-08-12',280);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','lunes,viernes','AM',10,'2006-08-21',200);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','lunes,martes,miercoles,jueves,viernes','AM',10,'2006-09-
18',180);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('Paginas web','lunes,viernes','PM',10,'2006-09-25',280);
insert into cursos (tema, dias,horario,clases,fechainicio,costo)
values('JavaScript','lunes,martes,viernes,sabado','PM',12,'2006-09-18',150);
417
9- Se quiere saber el promedio de clases por tema:
select tema,avg(clases)
from cursos
group by tema;
D) Un profesor guarda en una tabla llamada "notas" las notas de los alumnos de
un curso.
418
insert into notas values('30533444','Marcelo Morales',3.5);
insert into notas values('30633444','Fabiola Juarez',4.5);
insert into notas values('30333444','Juan Perez',7.8);
insert into notas values('30433444','Ana Maria Garcia',6);
insert into notas values('30533444','Marcelo Morales',4.2);
insert into notas values('30633444','Fabiola Juarez',7);
insert into notas values('30333444','Juan Perez',9);
insert into notas values('30433444','Ana Maria Garcia',5.8);
insert into notas values('30633444','Fabiola Juarez',2);
insert into notas values('30333444','Juan Perez',10);
insert into notas values('30633444','Fabiola Juarez',6.7);
E) Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".
419
1- Elimine la tabla, si existe.
2- Cree la tabla:
create table cuentas(
numero int(8) zerofill auto_increment,
documento char(8) not null,
nombre varchar(30),
saldo decimal(9,2),
primary key(numero)
);
3- Ingrese los siguientes registros:
insert into cuentas values(1234,'22333444','Juan Perez',2000.60);
insert into cuentas values(2566,'23333444','Maria Pereyra',5050);
insert into cuentas values(5987,'24333444','Marcos Torres',200);
insert into cuentas values(14434,'25333444','Ana Juarez',8000.60);
insert into cuentas values(28566,'23333444','Maria Pereyra',8050);
insert into cuentas values(35987,'24333444','Marcos Torres',2000);
F) Una pequeña biblioteca de barrio registra los préstamos de sus libros en una
tabla llamada "prestamos".
420
1- Elimine la tabla, si existe.
2- Cree la tabla:
create table prestamos(
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
primary key(titulo,fechaprestamo)
);
3- Ingrese algunos registros:
insert into prestamos
values('Manual de 1º grado','22333444','2006-07-10','2006-07-12');
insert into prestamos
values('Manual de 1º grado','22333444','2006-07-20','2006-07-21');
insert into prestamos (titulo,documento,fechaprestamo)
values('Manual de 1º grado','23333444','2006-07-25');
insert into prestamos (titulo,documento,fechaprestamo)
values('Alicia en el pais de las maravillas','23333444','2006-07-28');
insert into prestamos (titulo,documento,fechaprestamo)
values('El aleph','25333444','2006-08-10');
insert into prestamos
values('Manual de 2º grado','23333444','2006-07-28','2006-07-29');
4- Muestre los títulos de los libros que no se han devuelto y la fecha de préstamo:
select titulo,fechaprestamo
from prestamos
where fechadevolucion is null;
421
9- Elimine la tabla "morosos" si existe.
10- Cree una tabla llamada "morosos" con los campos "documento", "desde"
(fecha de préstamo desde la cual es moroso) y "cantidad" (cantidad de libros que
debe) y guarde el resultado de la consulta del punto 8:
create table morosos
select documento,
min(fechaprestamo) as desde,
count(*) as cantidad
from prestamos
where fechadevolucion is null
group by documento;
422
4- Muestre todos los registros:
423
-codigo: tinyint unsigned auto_increment,
-nombre: varchar(20),
-domicilio: varchar(30),
-clave primaria: codigo.
select codigo
from editoriales
where nombre='Emece';
Entonces, para realizar una inserción y al mismo tiempo consultar un valor en otra
tabla, colocamos "insert into" junto al nombre de la tabla ("libros") y los campos a
insertar y luego un "select" en el cual disponemos todos los valores, excepto el
valor que desconocemos, en su lugar colocamos el nombre del campo a consultar
("codigo"), luego se continúa con la consulta indicando la tabla de la cual
extraemos el código ("editoriales") y la condición, en la cual damos el "nombre" de
la editorial para que localice el código correspondiente.
424
El registro se cargará con el valor de código de la editorial "Emece".
Ejemplo:
Trabajamos con las tablas "libros" y "editoriales" de una librería.
425
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
codigoeditorial tinyint unsigned,
precio decimal(5,2) unsigned,
primary key (codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
domicilio varchar(30),
primary key(codigo)
);
426
where nombre='Plaza & Janes';
427
insert into libros (titulo,autor,codigoeditorial,precio)
select 'Cervantes y el quijote','Borges',codigo,35
from editoriales
where nombre='Plaza & Janes';
insert into libros (titulo,autor,codigoeditorial,precio)
select 'Harry Potter y la camara secreta','J.K. Rowling',codigo,54
from editoriales
where domicilio like 'San Martin%';
select * from libros;
Problema:
428
buscando en la tabla "socios" el número de socio a partir del número de
documento:
insert into inscriptos (numerosocio,deporte,año,cuota)
select numero,'tenis','2006','s'
from socios
where documento='23333444';
7- La madre de los socios "Perez" quiere inscribir a ambos hijos "natacion" este
año, pero no recuerda sus números de socio ni sus documentos. Inscriba a ambos
localizando sus números de socio con el domicilio:
insert into inscriptos (numerosocio,deporte,año,cuota)
select numero,'natacion','2006','n'
from socios
where domicilio='Urquiza 283';
429
Otros problemas:
A) Una biblioteca registra los préstamos de sus libros en una tabla llamada
"prestamos", los datos de sus libros en una tabla llamada "libros" y los datos de
sus socios en "socios".
430
insert into prestamos values(15,20,'2006-07-10','2006-07-12');
insert into prestamos values(15,31,'2006-07-12','2006-07-15');
insert into prestamos values(15,20,'2006-07-18',null);
insert into prestamos values(28,20,'2006-07-15',null);
insert into prestamos values(30,20,'2006-07-20',null);
insert into prestamos values(35,31,'2006-07-20','2006-07-22');
insert into prestamos values(36,90,'2006-07-25','2006-07-26');
5- El socio llamado "Juan Perez" solicita el libro código 35; no recuerda su número
de socio ni su número de documento. Intente ingresar el registro localizando el
número de socio a partir del nombre:
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select 35,numero,'2006-09-16'
from socios
where nombre='Juan Perez';
Aparece un mensaje de error indicando que la clave se duplica; porque la consulta
retorna 2 registros (hay 2 socios con igual nombre), MySQL intenta insertar 2
registros iguales en todos los valores excepto en el número de documento, pero
no se pueden ingresar 2 registros con el mismo código de libro en la misma fecha
(clave primaria). Resuelva el problema, ingrese el préstamo colocando las
condiciones necesarias para que la consulta retorne solamente una fila:
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select 35,numero,'2006-09-16'
from socios
where nombre='Juan Perez' and
domicilio='Sucre 34';
6- Seleccione el documento y nombre de todos los morosos (una vez cada socio):
select distinct s.documento,s.nombre
from socios as s
join prestamos as p
on s.numero=p.numerosocio
where fechadevolucion is null;
431
8- Cree la tabla "morosos" a partir de la consulta realizada en el punto 6:
create table morosos
select distinct s.documento,s.nombre
from socios as s
join prestamos as p
on s.numero=p.numerosocio
where fechadevolucion is null;
9- Muestre los números de socio, documento y nombre de todos los socios que no
son deudores, empleando un "left join" entre las tablas "socios" y "morosos":
select s.numero,s.documento,s.nombre
from socios as s
left join morosos as m
on s.documento=m.documento
where m.documento is null;
432
La inserción se realizó porque el documento del socio buscado se encontró en la
consulta de "no morosos".
12- Coloque fecha de devolución al libro con código "36" prestado el día "2006-07-
28":
update prestamos
set fechadevolucion='2006-07-29'
where codigolibro=36 and
fechaprestamo='2006-07-28';
13- Muestre el código y nombre de todos los libros que no han sido devueltos:
select l.codigo,l.titulo
from libros as l
left join prestamos as p
on p.codigolibro=l.codigo
where p.fechaprestamo is not null and
fechadevolucion is null;
14- la biblioteca desea crear una tabla llamada "librosausentes" en la que guarde
el código y título de los libros no devueltos. Elimine la tabla "librosausentes" si
existe:
drop table if exists librosausentes;
16- Realice un "left join" entre las tablas "libros" y "librosausentes" mostrando los
códigos y títulos de los libros presentes:
select l.codigo,l.titulo
from libros as l
left join librosausentes as la
on la.codigo=l.codigo
where la.codigo is null;
17- El socio número 82 quiere llevar el libro código "35", ingrese el registro en
"prestamos" sólo si al buscar el código en el resultado de la consulta anterior
encuentra coincidencia, es decir, si el libro está presente:
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select l.codigo,82,'2006-09-17'
from libros as l
left join librosausentes as la
433
on la.codigo=l.codigo
where la.codigo is null and
l.codigo=35;
No se realiza la inserción del registro porque el libro está prestado.
18- El mismo socio intenta llevar el libro con código "36". Realice la misma
consulta:
select l.codigo,82,'2006-09-17'
from libros as l
left join librosausentes as la
on la.codigo=l.codigo
where la.codigo is null and
l.codigo=36;
El registro se cargó porque el libro está presente.
434
insert into materias values(2,1,'Sistemas de datos I','Bernardo Garcia');
insert into materias values(3,1,'Ingles tecnico','Edit Torres');
insert into materias values(1,2,'Programacion basica','Alfredo Lopez');
insert into materias values(2,2,'Ingles I','Edit Torres');
insert into materias values(3,2,'Protocolos','Hector Juarez');
4- Muestre todos los datos de la tabla "inscriptos" (sin códigos) incluyendo los
nombres de las materias y carreras:
select i.documento,c.nombre,m.nombre,año,cuota
from inscriptos as i
join carreras as c
on c.codigo=i.codigocarrera
join materias as m
on m.codigo=i.codigomateria and
m.codigocarrera=c.codigo;
435
76 - Insertar registros con valores de otra tabla (insert - select)
-nombre: varchar(20).
436
Entonces, se puede insertar registros en una tabla con la salida devuelta por una
consulta; para ello escribimos la consulta y le anteponemos "insert into", el nombre
de la tabla en la cual ingresaremos los registros y los campos que se cargarán.
Si los campos presentados entre paréntesis son menos (o más) que las columnas
devueltas por la consulta, aparece un mensaje de error y la sentencia no se
ejecuta.
Ejemplo:
Tenemos las tabla "libros" y "editoriales" de una librería.
437
Ingresamos algunos registros en la tabla "libros":
438
Veamos lo que sucede si presentamos 1 solo campo y la consulta retorna 2
columnas:
insert into cantidadporeditorial (nombre)
select editorial,count(*) as cantidad
from libros
group by editorial;
439
create table cantidadporeditorial(
nombre varchar(20),
cantidad smallint unsigned
);
insert into cantidadporeditorial (nombre)
select editorial,count(*) as cantidad
from libros
group by editorial;
insert into cantidadporeditorial (nombre,cantidad)
select editorial,count(*) as cantidad
from libros
group by editorial;
select * from cantidadporeditorial;
Problema:
440
4- Elimine la tabla "montofacturas" si existe.
Otros problemas:
2- Cree la tabla:
create table inscriptos(
documento char(8) not null,
deporte varchar(20) not null,
año year not null,
cuota char(1), /*'s' o 'n', si esta paga o no*/
primary key(documento,deporte,año)
);
3- Ingrese los siguientes registros:
insert into inscriptos values('22333444','tenis','2005','s');
insert into inscriptos values('22333444','tenis','2006','s');
insert into inscriptos values('22333444','natacion','2005','s');
441
insert into inscriptos values('24333444','tenis','2005','s');
insert into inscriptos values('24333444','natacion','2006','s');
insert into inscriptos values('25333444','tenis','2005','s');
insert into inscriptos values('25333444','tenis','2006','s');
insert into inscriptos values('25333444','basquet','2006','s');
4- El club desea saber cuántas personas se han inscripto en cada deporte cada
año:
select deporte,año,count(*)
from inscriptos
group by deporte,año;
6- Cree la tabla:
create table inscriptospordeporteporaño(
deporte varchar(20),
año year,
cantidad smallint unsigned
);
11- El club desea saber cuántas veces se ha inscripto una persona en algún
deporte:
442
select documento,count(*)
from inscriptos
group by documento;
B) Un profesor guarda en una tabla llamada "notas" las notas de los alumnos de
un curso.
443
insert into notas values('30633444','Fabiola Juarez',6.7);
444
having avg(nota)>=4;
Note que en la lista de campos a cargar no se incluye el campo "numero".
13- Vea los registros recientemente cargados. Note que en el campo "numero" se
cargó automáticamente.
C) Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".
2- Cree la tabla:
create table cuentas(
numero int(8) zerofill auto_increment,
documento char(8) not null,
nombre varchar(30),
saldo decimal(9,2),
primary key(numero)
);
445
3- Ingrese los siguientes registros:
insert into cuentas values(1234,'22333444','Juan Perez',2000.60);
insert into cuentas values(2566,'23333444','Maria Pereyra',5050);
insert into cuentas values(5987,'24333444','Marcos Torres',200);
insert into cuentas values(14434,'25333444','Ana Juarez',8000.60);
insert into cuentas values(28566,'23333444','Maria Pereyra',8050);
insert into cuentas values(35987,'24333444','Marcos Torres',2000);
2- Cree la tabla:
create table clientes(
nombre varchar(30),
domicilio varchar(30),
sexo char(1),
edad tinyint unsigned
);
446
3- Ingrese los siguientes registros:
insert into clientes (nombre,sexo,edad) values('Juan Perez','m',45);
insert into clientes (nombre,sexo,edad) values('Ana Lopez','f',50);
insert into clientes (nombre,sexo,edad) values('Federico Herrero','m',30);
insert into clientes (nombre,sexo,edad) values('Mariano Juarez','m',35);
insert into clientes (nombre,sexo,edad) values('Maria Torres','f',36);
insert into clientes (nombre,sexo,edad) values('Ines Duarte','f',55);
insert into clientes (nombre,sexo,edad) values('Alejandra Figueroa','f',40);
447
E) Varios clubes de barrio se organizaron para realizar campeonatos entre ellos.
La tabla llamada "equipos" guarda la informacion de los distintos equipos que
jugarán.
2- Cree la tabla:
create table equipos(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
domicilio varchar(30),
barrio varchar(20),
primary key(codigo)
);
3- Ingrese los siguientes registros:
insert into equipos values(1,'Los tigres','Sarmiento 234','Gral. Paz');
insert into equipos values(2,'Los leones','Colon 123','Centro');
insert into equipos values(3,'Campeones','Guemes 346','Pueyrredon');
insert into equipos values(4,'Cebollitas','Colon 1234','Alberdi');
448
8- Vea todos los registros de la tabla creada anteriormente.
Note que el código se cargó automáticamente y las fechas de encuentro contienen
"null" para luego ser llenadas.
La tabla "editoriales":
La tabla "cantidadporeditorial":
-nombre: varchar(20),
-cantidad: smallint unsigned.
1º paso: consultar con un "join" los nombres de las distintas editoriales de "libros" y
la cantidad:
select e.nombre,count(l.codigoeditorial)
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
449
obteniendo una salida como la siguiente:
editorial cantidad
______________________
Emece 3
Paidos 1
Planeta 1
Plaza & Janes 0
Entonces, se puede insertar registros en una tabla con la salida devuelta por una
consulta que incluya un "join" o un "left join"; para ello escribimos la consulta y le
anteponemos "insert into", el nombre de la tabla en la cual ingresaremos los
registros y los campos que se cargarán (si se ingresan todos los campos no es
necesario listarlos).
Ejemplo:
Tenemos las tabla "libros", "editoriales" y "cantidadporeditorial".
450
precio decimal(5,2) unsigned,
primary key(codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key(codigo)
);
create table cantidadporeditorial(
nombre varchar(20),
cantidad smallint unsigned
);
Ingresamos algunos registros para las 2 primeras tablas:
Note que usamos "left join" porque hay una editorial de la cual no tenemos libros;
si usáramos "join", esa editorial no aparecería en la lista porque no encontraría
coincidencia de códigos.
451
drop table if exists libros, editoriales, cantidadporeditorial;
Problema:
452
create table socios(
documento char(8),
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
create table deportes(
codigo tinyint unsigned auto_increment,
nombre varchar(15),
profesor varchar(30),
primary key (codigo)
);
create table inscriptos(
documento char(8) not null,
codigodeporte varchar(20) not null,
año year not null,
cuota char(1), /*'s' o 'n', si esta paga o no*/
primary key(documento,codigodeporte,año)
);
3- Ingrese los siguientes registros para las tablas "socios", "deportes" e
"inscriptos":
insert into socios values('22333444','Juan Perez','Colon 123');
insert into socios values('23333444','Ana Lopez','Caseros 984');
insert into socios values('24333444','Marcelo Morales','Sucre 356');
insert into socios values('25333444','Susana Juarez','Sarmiento 723');
453
5- El club quiere almacenar esa información en una tabla llamada
"inscriptospordeporteporaño".
Elimine la tabla, si existe.
454
on i.codigodeporte=d.codigo
where i.cuota='n';
La sentencia no se ejecuta porque los campos listados son 2 y la consulta retorna
3 columnas.
14- Agrupe por nombre del profesor y deporte y cuente la cantidad de alumnos por
profesor y deporte, considerando los deportes para los que no haya inscriptos:
select d.profesor,d.nombre,count(i.codigodeporte) as alumnos
from deportes as d
left join inscriptos as i
on i.codigodeporte=d.codigo
group by d.profesor,d.nombre;
455
18- Muestre todos los registros de la nueva tabla.
Otros problemas:
456
5- Elimine la tabla "promedios" si existe.
457
12- Muestre los registros de "aprobados".
B) Un banco tiene registrados los datos de sus clientes en una tabla denominada
"clientes" y las cuentas corrientes de los mismos en una tabla llamada "cuentas".
458
5- Elimine la tabla "cuentasporcliente", si existe.
459
Queremos unir los datos de ambas tablas en una sola: "libros", es decir, alterar la
tabla "libros" para que almacene el nombre de la editorial y eliminar la tabla
"editoriales".
La tabla "libros" contiene un nuevo campo "editorial" con todos los registros con
valor "null".
select codigo,nombre
from editoriales;
codigo nombre
_________________
1 Planeta
2 Emece
3 Paidos
460
update libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
set libros.editorial=editoriales.nombre;
Entonces, se puede actualizar una tabla con valores de otra tabla. Se coloca
"update" junto al nombre de la tabla a actualizar, luego se realiza el "join" y el
campo por el cual se enlazan las tablas y finalmente se especifica con "set" el
campo a actualizar y su nuevo valor, que es el campo de la otra tabla con la cual
se enlazó.
Ejemplo:
Tenemos la tabla "libros" en la cual almacenamos los datos de los libros de
nuestra biblioteca y la tabla "editoriales" que almacena el nombre de las distintas
editoriales y sus códigos.
461
Queremos unir los datos de ambas tablas en una sola: "libros", es decir, alterar la
tabla "libros" para que almacene el nombre de la editorial, no su código y eliminar
la tabla "editoriales".
vemos que todos los registros tienen el campo "editorial" con valor "null".
Podemos hacerlo en 2 pasos: 1º) consultar los códigos de las editoriales con un
"select" y 2º) actualizar el campo "editorial" de los registros de "libros" uno a uno.
Luego, eliminar el campo "codigoeditorial" de "libros" y la tabla "editoriales".
462
drop table if exists libros, editoriales;
create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(30),
codigoeditorial tinyint unsigned,
primary key(codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key(codigo)
);
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');
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.
463
);
464
on c.codigoprovincia=p.codigo
set c.provincia=p.nombre;
Otros problemas:
465
5- Actualice los nuevos campos realizando un "join" con la tabla "socios":
update socios as s
join inscriptos as i
on s.documento=i.documento
set i.nombre=s.nombre,
i.domicilio=s.domicilio;
B) Una empresa registra los datos personales de sus empleados en una tabla
llamada "empleados" y las dependencias a las cuales pertenecen los mismos en
una tabla denominada "dependencias".
466
insert into dependencias values ('20555444','Secretaría',1000);
insert into dependencias values ('30000234','Secretaría',1000);
insert into dependencias values ('30154269','Relaciones públicas',1100);
467
set nombre=concat(apellido,' ',nombre);
update editoriales
set codigo=9
where nombre='Emece';
468
3) y finalmente actualizar todos los libros de dicha editorial:
update libros
set codigoeditorial=9
where codigoeditorial=2;
update libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
set l.codigoeditorial=9, e.codigo=9
where e.nombre='Emece';
Ejemplo:
Tenemos la tabla "libros" en la cual almacenamos los datos de los libros de
nuestra biblioteca y la tabla "editoriales" que almacena el nombre de las distintas
editoriales y sus códigos.
469
Ingresamos algunos registros:
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');
insert into editoriales values(4,'Plaza & Janes');
470
insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,12.33);
insert into libros values (3,'Matematica estas ahi','Paenza',2,9.99);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,17.22);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,23.56);
update libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
set l.codigoeditorial=9, e.codigo=9
where e.nombre='Emece';
select * from libros;
select * from editoriales;
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
de las cuales son oriundos los clientes.
471
values('Buenos Aires');
insert into provincias (nombre)
values('Neuquen');
Otros problemas:
472
2- Cree las tablas:
create table alumnos(
documento char(8) not null,
nombre varchar(30),
primary key(documento)
);
create table notas(
documento char(8) not null,
nota decimal(4,2) unsigned
);
3- Ingrese los siguientes registros:
insert into alumnos values('22333444','Juan Perez');
insert into alumnos values('23555666','Marina Herrero');
insert into alumnos values('24000333','Daniel Juarez');
insert into alumnos values('25222111','Hector Paz');
473
80 - Borrar registros consultando otras tablas (delete - join)
select codigo
from editoriales
where nombre='Emece';
delete libros
where codigoeditorial=2;
474
Es decir, usamos "delete" junto al nombre de la tabla de la cual queremos eliminar
registros, luego realizamos el "join" correspondiente nombrando las tablas
involucradas y agregamos la condición "where".
Ejemplo:
Tenemos la tabla "libros" en la cual almacenamos los datos de los libros de
nuestra biblioteca y la tabla "editoriales" que almacena el nombre de las distintas
editoriales y sus códigos.
475
O podemos realizar todo en una sola consulta:
delete libros
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';
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.
476
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
codigoprovincia tinyint unsigned,
telefono varchar(11),
primary key(codigo)
);
create table provincias(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key (codigo)
);
3- Ingrese algunos registros para ambas tablas:
insert into provincias (nombre) values('Cordoba');
insert into provincias (nombre) values('Santa Fe');
insert into provincias (nombre) values('Corrientes');
insert into provincias (nombre) values('Misiones');
insert into provincias (nombre) values('Salta');
insert into provincias (nombre) values('Buenos Aires');
insert into provincias (nombre) values('Neuquen');
477
join provincias
on clientes.codigoprovincia=provincias.codigo
where provincias.nombre='Santa Fe';
5- Verifique la eliminación.
Otros problemas:
Un instituto de enseñanza guarda en una tabla llamada "carreras" los datos de las
carreras que dicta, en "materias" las materias de cada carrera y en "inscriptos" las
inscripciones.
478
insert into inscriptos values('25000999',1,2,'2006');
insert into inscriptos values('25000999',2,1,'2006');
insert into inscriptos values('25000999',2,2,'2006');
Queremos eliminar todos los libros cuyo código de editorial no exista en la tabla
"editoriales".
479
Podemos hacerlo en 2 pasos:
1º paso: realizamos un left join para ver qué "codigoeditorial" en "libros" no existe
en "editoriales":
2º paso: borramos todos los libros mostrados en la consulta anterior (uno solo, con
código 5):
delete libros
where codigo=5;
delete libros
FROM libros
left join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.codigo is null;
Ahora queremos eliminar todas las editoriales de las cuales no haya libros:
delete editoriales
from editoriales
left join libros
on libros.codigoeditorial=editoriales.codigo
where libros.codigo is null;
Ejemplo:
Tenemos la tabla "libros" en la cual almacenamos los datos de los libros de
nuestra biblioteca y la tabla "editoriales" que almacena el nombre de las distintas
editoriales y sus códigos.
480
Eliminamos ambas tablas si existen:
drop table if exists libros, editoriales;
Queremos eliminar todos los libros cuyo código de editorial no exista en la tabla
"editoriales". Podemos hacerlo en 2 pasos: 1) realizamos un left join para ver qué
"codigoeditorial" en "libros" no existe en "editoriales", nos retorna el libro con
código "5", recordamos el valor, y 2) borramos todos los libros mostrados en la
consulta anterior (uno solo, con código 5).
481
Eliminemos todas las editoriales de las cuales no haya libros:
delete editoriales
from editoriales
left join libros
on libros.codigoeditorial=editoriales.codigo
where libros.codigo is null;
Veamos si se ha eliminado:
select * from editoriales;
delete libros
FROM libros
left join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.codigo is null;
delete editoriales
from editoriales
left join libros
on libros.codigoeditorial=editoriales.codigo
where libros.codigo is null;
482
Ejemplo:
483
4- Se quiere eliminar de la tabla "deportes" aquellos deportes para los cuales no
hay inscriptos:
delete deportes
from deportes as d
left join inscriptos as i
on d.codigo=i.deporte
where i.deporte is null;
Otros problemas:
A) Un profesor guarda los datos de sus alumnos en una tabla llamada "alumnos" y
los alumnos aprobados en la tabla "aprobados".
484
4- Se quiere eliminar de la tabla "alumnos" todos aquellos alumnos que no se
encuentran en la tabla "aprobados":
delete alumnos
from alumnos as al
left join aprobados as ap
on al.legajo=ap.legajo
where ap.legajo is null;
B) Una pequeña biblioteca de barrio registra los datos de sus socios en la tabla
"socios" y en una tabla "morosos" el documento del socio que adeuda libros y la
fecha desde la cual es moroso.
485
82 - Borrar registros en cascada (delete - join)
delete editoriales
where codigo=@valor;
3º paso: eliminar todos los libros cuyo código de editorial sea igual a la variable:
486
La sentencia anterior elimina de la tabla "editoriales" la editorial "Emece" y de la
tabla "libros" todos los registros con código de editorial correspondiente a
"Emece".
Ejemplo:
Tenemos la tabla "libros" en la cual almacenamos los datos de los libros de
nuestra biblioteca y la tabla "editoriales" que almacena el nombre de las distintas
editoriales y sus códigos. Eliminamos ambas tablas si existen:
drop table if exists libros, editoriales;
487
O podemos hacerlo en una sola consulta:
delete libros,editoriales
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';
delete libros,editoriales
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';
select * from libros;
select * from editoriales;
Problema:
Una clínica registra los pacientes en una tabla llamada "pacientes" y en otra tabla
denominada "obrassociales" almacena los datos de las obras sociales que
atiende.
488
2- Cree las tablas:
create table pacientes(
documento char(8),
nombre varchar(30),
domicilio varchar(30),
codigoobrasocial tinyint unsigned
);
create table obrassociales(
codigo tinyint unsigned auto_increment,
nombre varchar(15),
domicilio varchar(30),
primary key(codigo)
);
3- Ingrese algunos registros:
insert into obrassociales values (1,'PAMI','Colon 345');
insert into obrassociales values (2,'IPAM','Sucre 98');
insert into obrassociales values (3,'OSDOP','Avellaneda 267');
Otros problemas:
489
2- Cree las tablas:
create table deportes(
codigo tinyint unsigned auto_increment,
nombre varchar(20) not null,
profesor tinyint unsigned,
primary key(codigo)
);
create table profesores(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
domicilio varchar(30),
primary key(codigo)
);
create table inscriptos(
numerosocio int unsigned,
deporte tinyint unsigned,
año year not null,
);
3- Ingrese los siguientes registros:
insert into profesores values(1,'Alfredo Perez','Sarmiento 984');
insert into profesores values(2,'Betina Molina','Sucre 356');
insert into profesores values(3,'Carlos Garcia','Urquiza 209');
insert into profesores values(4,'Daniel Morales','Salta 1234');
490
5- Verifique las eliminaciones.
"check table" chequea si una o más tablas tienen errores. Esta sentencia devuelve
la siguiente información: en la columna "Table" muestra el nombre de la tabla; en
"Op" muestra siempre "check"; en "Msg_type" muestra "status", "error", "info" o
"warning" y en "Msg_text" muestra un mensaje, generalmente es "OK".
- fast: controla únicamente las tablas que no se han cerrado en forma correcta.
- changed: únicamente controla las tablas que se han cambiado desde el último
chequeo o que no se cerraron correctamente.
- medium: controla los registros para verificar que los enlaces borrados están bien.
- extended: realiza una búsqueda completa para todas las claves de cada registro.
491
Se pueden combinar las opciones de control, por ejemplo, realizamos un chequeo
rápido de la tabla "libros" y verificamos si se cerró correctamente:
Ejemplo:
Creamos la tabla:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
precio decimal(5,2) unsigned,
primary key(codigo)
);
vamos a chequear el estado de la tabla:
check table libros;
Si el resultado indica que la tabla está corrupta podemos emplear "repair table"
para repararla:
repair table libros;
492
titulo varchar(40),
autor varchar(30),
precio decimal(5,2) unsigned,
primary key(codigo)
);
check table libros;
check table libros fast quick;
repair table libros;
select encode('feliz','dia');
Con "decode" desencriptamos una cadena encriptada con "encode". Esta función
recibe 2 argumentos: el primero, la cadena a desencriptar; el segundo, la
contraseña:
select @clave:=encode('RealMadrid','ganador');
insert into usuarios values ('MariaGarcia',@clave);
493
Veamos los registros ingresados:
Ejemplo:
Retomamos la tabla "usuarios".
Creamos la tabla:
create table usuarios (
nombre varchar(30),
clave varchar(10)
);
Podemos ingresar registros encriptando la clave:
insert into usuarios values ('MarioPerez',encode('Marito','octubre'));
494
Guardamos la clave para el siguiente usuario en una variable llamada
"@clavecodificada" y luego ingresamos el registro con la clave encriptada:
select @clavecodificada:=encode('River','SQL');
insert into usuarios values ('JuanJoseTorres',@clavecodificada);
Note que se muestran aquellas claves que fueron encriptadas con la contraseña
"SQL", las demás fueron mal desencriptadas porque la contraseña al encriptarlas
fue otra.
495