0% encontró este documento útil (0 votos)
5 vistas

Apunte de SQL

El documento proporciona una introducción al lenguaje SQL y su uso en la gestión de bases de datos relacionales, específicamente con MySQL. Se abordan temas como la creación y manipulación de bases de datos y tablas, la inserción y recuperación de registros, y los tipos de datos básicos en SQL. Además, se presentan ejemplos prácticos sobre cómo realizar estas operaciones en un entorno de servidor MySQL.

Cargado por

leonardo Pardo
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
5 vistas

Apunte de SQL

El documento proporciona una introducción al lenguaje SQL y su uso en la gestión de bases de datos relacionales, específicamente con MySQL. Se abordan temas como la creación y manipulación de bases de datos y tablas, la inserción y recuperación de registros, y los tipos de datos básicos en SQL. Además, se presentan ejemplos prácticos sobre cómo realizar estas operaciones en un entorno de servidor MySQL.

Cargado por

leonardo Pardo
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 495

1 - Introducción.

SQL, Structure Query Language (Lenguaje de Consulta Estructurado) es un


lenguaje de programacion para trabajar con base de datos relacionales como
MySQL, Oracle, etc.

MySQL es un interpretador de SQL, es un servidor de base de datos.

MySQL permite crear base de datos y tablas, insertar datos, modificarlos,


eliminarlos, ordenarlos, hacer consultas y realizar muchas operaciones, etc.,
resumiendo: administrar bases de datos.

Ingresando instrucciones en la linea de comandos o embebidas en un lenguaje


como PHP nos comunicamos con el servidor. Cada sentencia debe acabar con
punto y coma (;).

La sensibilidad a mayúsculas y minúsculas, es decir, si hace diferencia entre ellas,


depende del sistema operativo, Windows no es sensible, pero Linux si. Por
ejemplo Windows interpreta igualmente las siguientes sentencias:

create database administracion;


Create DataBase administracion;

Pero Linux interpretará como un error la segunda.

Se recomienda usar siempre minúsculas. Es más el sitio mysqlya.com.ar está


instalado sobre un servidor Linux por lo que todos los ejercicios deberán
respetarse mayúsculas y minúsculas.

2 - show databases
Una base de datos es un conjunto de tablas.

Una base de datos tiene un nombre con el cual accederemos a ella.

Vamos a trabajar en una base de datos ya creada en el sitio mysqlya.com.ar,


llamada "administracion".

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 base de datos almacena sus datos en tablas.

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 registro contiene un dato por cada columna de la tabla.

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

Gráficamente tenemos la tabla usuarios, que contiene dos campos llamados:


nombre y clave. Luego tenemos tres registros almacenados en esta tabla, el
primero almacena en el campo nombre el valor "MarioPerez" y en el campo clave
"Marito", y así sucesivamente con los otros dos registros.

Las tablas forman parte de una base de datos.

Nosotros trabajaremos con la base de datos llamada "administracion", que ya


hemos creado en el servidor mysqlya.com.ar.

Para ver las tablas existentes en una base de datos tipeamos:

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:

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

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;

Ahora aparece "usuarios" entre otras que ya pueden estar creadas.

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:

- nombre: que contendrá una cadena de hasta 30 caracteres de longitud, que


almacenará el nombre de usuario.

- clave: otra cadena de caracteres de 10 de longitud, que guardará la clave de


cada usuario.

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:

Field Type Null


_______________________________
nombre varchar(30) YES
clave varchar(10) YES

Esta es la estructura de la tabla "usuarios"; nos muestra cada campo, su tipo, lo


que ocupa en bytes y otros datos como la aceptación de valores nulos etc, que
veremos más adelante en detalle.

3
Para eliminar una tabla usamos "drop table". Tipeamos:

drop table usuarios;

Si tipeamos nuevamente:

drop table usuarios;

Aparece un mensaje de error, indicando que no existe, ya que intentamos borrar


una tabla inexistente.

Para evitar este mensaje podemos tipear:

drop table if exists usuarios;

En la sentencia precedente especificamos que elimine la tabla "usuarios" si existe.

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.

drop table if exists usuarios;


create table usuarios (
nombre varchar(30),
clave varchar(10)
);
describe usuarios;

Problemas:

I)

A) Queremos almacenar los datos de nuestros amigos.

1- Elimine la tabla "agenda" si existe:

drop table if exists agenda;

2- Cree una tabla llamada "agenda", debe tener los siguientes campos:
nombre varchar(20), domicilio varchar(30) y teléfono varchar(11)

create table agenda(


nombre varchar(20),
domicilio varchar(30),

4
telefono varchar(11)
);

3- Intente crearla nuevamente. Aparece mensaje de error.

4- Visualice las tablas existentes (show tables).

5- Visualice la estructura de la tabla "agenda" (describe agenda).

6- Elimine la tabla, si existe (drop table, if exists).

7- Intente eliminar la tabla sin la cláusula if exists (drop table agenda).


Debe aparecer un mensaje de error cuando no existe la tabla.

II)

A) Queremos almacenar información referente a nuestros libros.


1- Elimine la tabla "libros", si existe.

2- Cree una tabla llamada "libros".


Debe definirse con los siguientes campos:
titulo varchar(20), autor varchar(30) y editorial varchar(15)

3- Intente crearla nuevamente. Aparece mensaje de error.

4- Visualice las tablas existentes.

5- Visualice la estructura de la tabla "libros".

6- Elimine la tabla, si existe.

7- Intente eliminar la tabla.

4 - Carga de registros a una tabla y su recuperación (insert into - select)


Un registro es una fila de la tabla que contiene los datos propiamente dichos.
Cada registro tiene un dato por cada columna.

Recordemos como crear la tabla "usuarios":

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

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:

insert into usuarios (nombre, clave) values ('MarioPerez','Marito');

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.

La tabla usuarios ahora la podemos graficar de la siguiente forma:

Nombre clave
MarioPerez Marito

Es importante ingresar los valores en el mismo orden en que se nombran los


campos, si ingresamos los datos en otro orden, no aparece un mensaje de error y
los datos se guardan de modo incorrecto.

Note que los datos ingresados, como corresponden a campos de cadenas de


caracteres se colocan entre comillas simples. Las comillas simples son
OBLIGATORIAS.

Para ver los registros de una tabla usamos "select":

select nombre,clave from usuarios;

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:

drop table if exists usuarios;

Creamos la tabla:

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

6
Insertamos 3 registros:

insert into usuarios(nombre,clave) values ('MarioPerez','Marito');


insert into usuarios(nombre,clave) values ('MariaGarcia','Mary');
insert into usuarios(nombre,clave) values ('DiegoRodriguez','z8080');

Para ver los registros ejecutamos el comando select:

select nombre,clave from usuarios;

(Aclaración: Generalmente borraremos la tabla y luego la crearemos por si otro


usuario del sitio mysqlya.com.ar a modificado la tabla, para comprobar que no es
necesario siempre hacer drop y create puede borrar esas dos instrucciones y
luego ejecutar sucesivamente varios insert y verá como se van agregando los
registros a la tabla. Tener en cuenta que cuando hacemos drop se borra la tabla
por completo, su estructura y los registros cargados hasta el momento)

drop table if exists usuarios;

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

insert into usuarios(nombre,clave) values ('MarioPerez','Marito');


insert into usuarios(nombre,clave) values ('MariaGarcia','Mary');
insert into usuarios(nombre,clave) values ('DiegoRodriguez','z8080');

select nombre,clave from usuarios;

Problema:

Trabaje con la tabla "agenda".

1- Elimine la tabla "agenda", si existe:

drop table if exists agenda;

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).

create table agenda(


nombre varchar(20),
domicilio varchar(30),
telefono varchar(11)
);
3- Visualice las tablas existentes para verificar la creación de "agenda".
(show tables).

7
4- Visualice la estructura de la tabla "agenda". (describe).

5- Ingrese los siguientes registros:

insert into agenda (nombre, domicilio, telefono) values


('Alberto Mores','Colon 123','4234567');
insert into agenda (nombre, domicilio, telefono) values
('Juan Torres','Avellaneda 135','4458787');

6- Seleccione y muestre todos los registros de la tabla:


select nombre, domicilio, telefono from agenda;

7- Elimine la tabla "agenda", si existe:


drop table if exists agenda;

8- Intente eliminar la tabla nuevamente, sin especificar "si existe":


drop table agenda;

5 - Tipos de datos básicos de un campo de una tabla.


Ya explicamos que al crear una tabla debemos resolver qué campos (columnas)
tendrá y que tipo de datos almacenará cada uno de ellos, es decir, su estructura.
Estos son algunos tipos de datos básicos:

- varchar: se usa para almacenar cadenas de caracteres. Una cadena es una


secuencia de caracteres. Se coloca entre comillas (simples): 'Hola'. El tipo
"varchar" define una cadena de longitud variable en la cual determinamos el
máximo de caracteres. Puede guardar hasta 255 caracteres. Para almacenar
cadenas de hasta 30 caracteres, definimos un campo de tipo varchar(30). Si
asignamos una cadena de caracteres de mayor longitud que la definida, la cadena
se corta. Por ejemplo, si 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 caracteres.

- integer: se usa para guardar valores numéricos enteros, de -2000000000 a


2000000000 aprox. Definimos campos de este tipo cuando queremos representar,
por ejemplo, cantidades.

- float: se usa para almacenar valores numéricos decimales. Se utiliza como


separador el punto (.). Definimos campos de este tipo para precios, por ejemplo.

Antes de crear una tabla debemos pensar en sus campos y optar por el tipo de
dato adecuado para cada uno de ellos. Por ejemplo, si en un campo
almacenaremos 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 :

Para almacenar información de los libros de una librería necesitamos los


siguientes campos:

-titulo, cadena de caracteres de 40 de longitud,


-autor, cadena de caracteres de 30 de longitud,
-editorial, caracteres de 15 de longitud,
-precio, valor numérico con decimales y
-cantidad, valor numérico entero.

Al crear la tabla, entonces, elegimos el tipo de dato más adecuado para cada
campo:

create table libros(


titulo varchar(40),
autor varchar(20),
editorial varchar(15),
precio float,
cantidad integer
);

Vemos la estructura de la tabla:

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);

Veamos los registros cargados:

select * from libros;

Tengamos en cuenta que es lo mismo escribir:

select * from libros; que select codigo,titulo,autor,precio from libros;

9
Es una forma resumida de indicar que seleccione todos los campos de la tabla.

drop table if exists libros;


create table libros (
codigo integer,
titulo varchar (20),
autor varchar (30),
precio float
);
insert into libros(codigo,titulo,autor,precio) values (1,'MySQL a fondo','Rodriguez Pablo',70.52);
insert into libros(codigo,titulo,autor,precio) values (2,'PHP 5','Rios Juan',20);
insert into libros(codigo,titulo,autor,precio) values (3,'JSP 1.1','Rosales Ana',27.75);

select * from libros;

Problema:

Un videoclub que alquila películas en video almacena la información de sus


películas en una tabla llamada "peliculas"; para cada película necesita los
siguientes datos:

-nombre, cadena de caracteres de 20 de longitud,


-actor, cadena de caracteres de 20 de longitud,
-duración, valor numérico entero.
-cantidad de copias: valor entero.

1- Elimine la tabla, si existe:


drop table if exists peliculas;

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo:


create table peliculas(
nombre varchar(20),
actor varchar(20),
duracion integer,
cantidad integer
);

3- Vea la estructura de la tabla:


describe peliculas;

4- Ingrese los siguientes registros:

insert into peliculas (nombre, actor, duracion, cantidad)


values ('Mision imposible','Tom Cruise',120,3);
insert into peliculas (nombre, actor, duracion, cantidad)
values ('Mision imposible 2','Tom Cruise',180,2);
insert into peliculas (nombre, actor, duracion, cantidad)
values ('Mujer bonita','Julia R.',90,3);

10
insert into peliculas (nombre, actor, duracion, cantidad)
values ('Elsa y Fred','China Zorrilla',90,2);

5- Muestre todos los registros:


select * from peliculas;

6 - Recuperación de algunos campos (select)

Hemos aprendido cómo ver todos los registros de una tabla:

select * from libros;

El comando "select" recupera los registros de una tabla. Con el asterisco (*)
indicamos que seleccione todos los campos de la tabla que nombramos.

Podemos especificar el nombre de los campos que queremos ver separándolos


por comas:

select titulo,autor,editorial from libros;

En la sentencia anterior la consulta mostrará sólo los campos "titulo", "autor" y


"editorial". En la siguiente sentencia, veremos los campos correspondientes al
título y precio de todos los libros:

select titulo,precio from libros;

Para ver solamente la editorial y la cantidad de libros tipeamos:

select editorial,cantidad from libros;

Ejemplo

Trabajamos con la tabla "libros" que almacena los datos de los libros de una
librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla "libros":

create table libros(


titulo varchar(20),
autor varchar(30),
editorial varchar(15),
precio float,

11
cantidad integer
);

Veamos la estructura de la tabla:

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);

Para ver todos los campos de una tabla tipeamos:

select * from libros;

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:

select titulo,autor,editorial from libros;

La siguiente sentencia nos mostrará los títulos y precios de todos los libros:

select titulo,precio from libros;

Para ver solamente la editorial y la cantidad de libros tipeamos:

select editorial,cantidad from libros;

drop table if exists libros;


create table libros(
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
precio float,
cantidad integer
);
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);
select * from libros;
select titulo,autor,editorial from libros;

12
select titulo,precio from libros;
select editorial,cantidad from libros;

Problema:

Un videoclub que alquila películas en video almacena la información de sus


películas en alquiler en una tabla llamada "peliculas".

1- Elimine la tabla, si existe:

drop table if exists peliculas;

2- Cree la tabla:

create table peliculas(


titulo varchar(20),
actor varchar(20),
duracion integer,
cantidad integer
);

3- Vea la estructura de la tabla:

describe peliculas;

4- Ingrese los siguientes registros:

insert into peliculas (titulo, actor, duracion, cantidad)


values ('Mision imposible','Tom Cruise',120,3);
insert into peliculas (titulo, actor, duracion, cantidad)
values ('Mision imposible 2','Tom Cruise',180,2);
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);

5- Realice un "select" mostrando solamente el título y actor de todas las películas:

select titulo,actor from peliculas;

6- Muestre el título y duración de todas las peliculas.

7- Muestre el título y la cantidad de copias.

13
7 - Recuperación de registros específicos (select - where)

Hemos aprendido cómo ver todos los registros de una tabla:

select nombre, clave from usuarios;

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:

select nombre, clave from usuarios where nombre='MarioPerez';

Para las condiciones se utilizan operadores relacionales (tema que trataremos


más adelante en detalle). El signo igual(=) es un operador relacional. Para la
siguiente selección de registros especificamos una condición que solicita los
usuarios cuya clave es igual a 'bocajunior':

select nombre, clave from usuarios where clave='bocajunior';

Si ningún registro cumple la condición establecida con el "where", no aparecerá


ningún registro.

Ejemplo:

Borramos la tabla si existe

drop table if exists usuarios;

Creamos la tabla:

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

Vemos la estructura de la tabla:

describe usuarios;

Ingresamos algunos registros:

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');

Vemos todos los registros:

select nombre, clave from usuarios;

Realizamos una consulta especificando una condición, queremos ver el usuario


cuyo nombre es "Leonardo":

select nombre, clave from usuarios where nombre='Leonardo';

Realizamos un "select" de los usuarios cuya clave es 'bocajunior':

select nombre, clave from usuarios where clave='bocajunior';

Realizamos un "select" de los usuarios cuya clave es 'river':

select nombre, clave from usuarios where clave='river';

No aparece ninguno pues ningún registro cumple la condición.

drop table if exists usuarios;

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

describe usuarios;

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');

select nombre, clave from usuarios;

select nombre, clave from usuarios where nombre='Leonardo';

select nombre, clave from usuarios where clave='bocajunior';

select nombre, clave from usuarios where clave='river';

15
Problema:

Trabajamos con nuestra tabla "agenda".


1- Eliminamos "agenda", si existe:
drop table if exists agenda;

2- Creamos la tabla, con los siguientes campos:


nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11).

3- Visualice la estructura de la tabla "agenda".(describe).

4- Ingrese los siguientes registros:


'Alberto Mores','Colon 123','4234567',
'Juan Torres','Avellaneda 135','4458787',
'Mariana Lopez','Urquiza 333','4545454',
'Fernando Lopez','Urquiza 333','4545454'.

5- Seleccione todos los registros de la tabla. (select).

6- Seleccione el registro cuyo nombre sea 'Juan Torres'.

7- Seleccione el registro cuyo domicilio sea 'Colon 123'.

8- Muestre los datos de quienes tengan el teléfono '4545454'.

9- Elimine la tabla "agenda".

Otros problemas:

A) Trabaje con la tabla "libros".

1- Elimine la tabla si existe. (drop table- if exists),

2- Cree la tabla "libros". Debe tener la siguiente estructura:

create table libros (


titulo varchar(20),
autor varchar(30),
editorial varchar(15)
);

3- Visualice la estructura de la tabla "libros".

4- Ingrese los siguientes registros:

16
'El aleph','Borges','Planeta';
'Martin Fierro','Jose Hernandez','Emece';
'Aprenda PHP','Mario Molina','Emece';
'Cervantes','Borges','Paidos';

5- Muestre todos los registros. (select).

6- Seleccione los registros cuyo autor sea 'Borges'.

7- Seleccione los registros cuya editorial sea 'Emece'.

8- Seleccione los libros cuyo titulo sea 'Martin Fierro'.

9- Elimine la tabla "libros".

B) Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla llamada "articulos".

1- Elimine la tabla si existe.

2- Cree la tabla "articulos" con la siguiente estructura:


create table articulos(
codigo integer,
nombre varchar(20),
descripcion varchar(30),
precio float
);

3- Vea la estructura de la tabla (describe).

4- Ingrese algunos registros:


insert into articulos (codigo, nombre, descripcion, precio)
values (1,'impresora','Epson Stylus C45',400.80);
insert into articulos (codigo, nombre, descripcion, precio)
values (2,'impresora','Epson Stylus C85',500);
insert into articulos (codigo, nombre, descripcion, precio)
values (3,'monitor','Samsung 14',800);
insert into articulos (codigo, nombre, descripcion, precio)
values (4,'teclado','ingles Biswal',100);
insert into articulos (codigo, nombre, descripcion, precio)
values (5,'teclado','español Biswal',90);

5- Seleccione todos los datos de los registros cuyo nombre sea "impresora".

6- Muestre sólo el código, descripción y precio de los teclados.

17
8 - Operadores Relacionales = <> < <= > >=
Hemos aprendido a especificar condiciones de igualdad para seleccionar registros
de una tabla; por ejemplo:

select titulo,autor,editorial from libros where autor='Borges';

Utilizamos el operador relacional de igualdad.

Los operadores relacionales vinculan un campo con un valor para que MySQL
compare cada registro (el campo especificado) con el valor dado.

Los operadores relacionales son los siguientes:

= 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:

select titulo,autor,editorial from libros where autor<>'Borges';

Podemos comparar valores numéricos. Por ejemplo, queremos mostrar los libros
cuyos precios sean mayores a 20 pesos:

select titulo,autor,editorial,precio from libros where precio>20;

También, los libros cuyo precio sea menor o igual a 30:

select titulo,autor,editorial,precio from libros where precio<=30;

Ejemplo:

Borramos la tabla libros si existe

drop table if exists libros;

18
La creamos con la siguiente estructura:

create table libros(


titulo varchar(20),
autor varchar(30),
editorial varchar(15),
precio float
);

Por primera vez definimos un campo de tipo float.

Agregamos registros a la tabla:

insert into libros (titulo,autor,editorial,precio) values


('El aleph','Borges','Planeta',12.50);
insert into libros (titulo,autor,editorial,precio) values
('Martin Fierro','Jose Hernandez','Emece',16.00);
insert into libros (titulo,autor,editorial,precio) values
('Aprenda PHP','Mario Molina','Emece',35.40);
insert into libros (titulo,autor,editorial,precio) values
('Cervantes','Borges','Paidos',50.90);

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(.).

Seleccionamos todos los registros:

select titulo, autor,editorial,precio from libros;

Seleccionamos los registros cuyo autor sea diferente de 'Borges':

select titulo,autor,editorial,precio from libros where autor<>'Borges';

Seleccionamos los registros cuyo precio supere los 20 pesos:

select titulo,autor,editorial,precio from libros where precio>20;

Seleccionamos los libros cuyo precio es menor o igual a 30:

select titulo,autor,editorial,precio from libros where precio<=30;

Note que al comparar valores numéricos (en este caso de tipo float) no se utilizan
comillas.

19
drop table if exists libros;

create table libros(


titulo varchar(20),
autor varchar(30),
editorial varchar(15),
precio float
);

insert into libros (titulo,autor,editorial,precio) values ('El aleph','Borges','Planeta',12.50);


insert into libros (titulo,autor,editorial,precio) values ('Martin Fierro','Jose
Hernandez','Emece',16.00);
insert into libros (titulo,autor,editorial,precio) values ('Aprenda PHP','Mario Molina','Emece',35.40);
insert into libros (titulo,autor,editorial,precio) values ('Cervantes','Borges','Paidos',50.90);

select titulo, autor,editorial,precio from libros;

select titulo, autor,editorial,precio from libros where autor<>'Borges';

select titulo, autor,editorial,precio from libros where precio>20;

select titulo,autor,editorial,precio from libros where precio<=30;

Problema:

Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con ese nombre.

1- Elimine "articulos", si existe:


drop table if exists articulos;

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo integer,
nombre varchar(20),
descripcion varchar(30),
precio float,
cantidad integer
);

3- Vea la estructura de la tabla (describe).

4- Ingrese algunos registros:


insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (1,'impresora','Epson Stylus C45',400.80,20);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (2,'impresora','Epson Stylus C85',500,30);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (3,'monitor','Samsung 14',800,10);

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);

5- Seleccione todos los registros de la tabla. (select).

6- Muestre los datos de las impresoras.

7- Seleccione los artículos cuyo precio sea mayor o igual a 500:


select * from articulos
where precio>=500;

8- Seleccione los artículos cuya cantidad sea menor a 30:


select nombre,descripcion, precio,cantidad
from articulos
where cantidad<20;

9- Selecciones el nombre y descripción de los artículos que no cuesten $100:


select nombre, descripcion
from articulos
where precio<>100;

Otros problemas:

A) Un video club que alquila películas en video almacena la información de sus


películas
en alquiler en una tabla denominada "peliculas".

1- Elimine la tabla, si existe.

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo:


create table peliculas(
titulo varchar(20),
actor varchar(20),
duracion integer,
cantidad integer
);

3- Vea la estructura de la tabla:


describe peliculas;

4- Ingrese los siguientes registros:


insert into peliculas (titulo, actor, duracion, cantidad)
values ('Mision imposible','Tom Cruise',120,3);
insert into peliculas (titulo, actor, duracion, cantidad)
values ('Mision imposible 2','Tom Cruise',180,2);

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);

5- Seleccione las películas cuya duración no supere los 90 minutos:


select *from peliculas
where duracion<=90;

6- Seleccione todas las películas en las que el actor no sea 'Tom Cruise':
select * from peliculas
where actor<>'Tom Cruise';

7- Seleccione todas las películas de las que haya más de 2 copias:


select * from peliculas
where cantidad >2;

B) Trabaje con la tabla "agenda" en la que registra los datos de sus amigos.

1- Elimine "agenda", si existe.

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).

3- Visualice la estructura de la tabla.

4- Ingrese los siguientes registros:


Mores,Alberto,Colon 123,4234567,
Torres,Juan,Avellaneda 135,4458787,
Lopez,Mariana,Urquiza 333,4545454,
Lopez,Fernando,Urquiza 333,4545454.
Suarez,Mariana,Sarmiento 643,4445544.
Lopez,Ana,Sucre 309,4252587.

5- Seleccione todos los registros de la tabla.

6- Seleccione los amigos cuyo apellido sea 'Lopez'.

7- Seleccione los registros cuyo nombre NO sea 'Mariana'.

8- Seleccione los registros cuyo domicilio sea 'Colon 123'.

9- Muestre los datos de quienes tengan el teléfono '4545454'.

22
9 - Borrado de registros de una tabla (delete)

Para eliminar los registros de una tabla usamos el comando "delete":

delete from usuarios;

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':

delete from usuarios where nombre='Leonardo';

Si solicitamos el borrado de un registro que no existe, es decir, ningún registro


cumple con la condición especificada, no se borrarán registros, pues no encontró
registros con ese dato.

Ejemplo:

Trabajamos con la tabla "usuarios".

Eliminamos la tabla, si existe:

drop table if exists usuarios;

Creamos la tabla:

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

Ingresamos algunos registros:

insert into usuarios (nombre, clave) values ('Leonardo','payaso');


insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

Queremos eliminar el registro cuyo nombre de usuario es 'Leonardo':

23
delete from usuarios where nombre='Leonardo';

Veamos el contenido de la tabla:

select nombre,clave from usuarios;

Queremos eliminar los registros cuya clave es 'River':

delete from usuarios where clave='River';

Veamos el contenido de la tabla:

select nombre,clave from usuarios;

Eliminemos todos los registros:

delete from usuarios;

Veamos el contenido de la tabla:

select nombre,clave from usuarios;

drop table if exists usuarios;

create table usuarios (


nombre varchar(30),
clave varchar(10)
);
insert into usuarios (nombre, clave) values ('Leonardo','payaso');
insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

delete from usuarios where nombre='Leonardo';

select nombre,clave from usuarios;

delete from usuarios where clave='River';

select nombre,clave from usuarios;

delete from usuarios;

select nombre,clave from usuarios;

24
Problema:

Trabaje con la tabla "agenda" que registra la información referente a sus amigos.

1- Elimine la tabla (drop table) si existe (if exists).

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).

create table agenda(


apellido varchar(30),
nombre varchar(20),
domicilio varchar(30),
telefono varchar(11)
);

3- Visualice la estructura de la tabla "agenda" (describe).

4- Ingrese los siguientes registros (insert into):

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.

5- Elimine el registro cuyo nombre sea 'Juan'(delete - where).

6- Elimine los registros cuyo número telefónico sea igual a '4545454'.

Otros problemas:

A) Trabaje con la tabla "libros" en la cual almacena la información de sus libros


una librería.

1- Elimine la tabla.

2- Créela con los siguientes campos: titulo (cadena de 20 caracteres de longitud),


autor (cadena de 30), editorial (cadena de 15) y precio (float).

3- Visualice la estructura de la tabla "libros".

4- Ingrese los siguientes registros:

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;

5- Muestre todos los registros.

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)

8- Borre los registros cuyo precio sea menor a 20.

9- Borre los registros que cuyo precio sea mayor o igual a 40 pesos.

10- Elimine todos los registros de la tabla.

B) Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con ese nombre.

1- Elimine "articulos", si existe.

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo integer,
nombre varchar(20),
descripcion varchar(30),
precio float,
cantidad integer
);

3- Vea la estructura de la tabla (describe).

4- Ingrese algunos registros:


insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (1,'impresora','Epson Stylus C45',400.80,20);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (2,'impresora','Epson Stylus C85',500,30);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (3,'monitor','Samsung 14',800,10);
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);

5- Seleccione todos los registros de la tabla.

26
6- Elimine los artículos cuyo precio sea mayor o igual a 500.

7- Elimine todas las impresoras.

8- Elimine todos los artículos cuyo código sea diferente a 4.

10 - Modificación de registros de una tabla (update)


Para modificar uno o varios datos de uno o varios registros utilizamos "update"
(actualizar).

Por ejemplo, en nuestra tabla "usuarios", queremos cambiar los valores de todas
las claves, por "RealMadrid":

update usuarios set clave='RealMadrid';

Utilizamos "update" junto al nombre de la tabla y "set" junto con el campo a


modificar y su nuevo valor.

El cambio afectará a todos los registros.

Podemos modificar algunos registros, para ello debemos establecer condiciones


de selección con "where".

Por ejemplo, queremos cambiar el valor correspondiente a la clave de nuestro


usuario llamado 'MarioPerez', queremos como nueva clave 'Boca', necesitamos
una condición "where" que afecte solamente a este registro:

update usuarios set clave='Boca'


where nombre='MarioPerez';

Si no encuentra registros que cumplan con la condición del "where", ningún


registro es afectado.

Las condiciones no son obligatorias, pero si omitimos la cláusula "where", la


actualización afectará a todos los registros.

También se puede actualizar varios campos en una sola instrucción:

update usuarios set nombre='MarceloDuarte', clave='Marce'


where nombre='Marcelo';

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:

Trabajamos con la tabla "usuarios" que guarda el nombre de usuario y su clave.

Eliminamos la tabla, si existe:

drop table if exists usuarios;

Creamos la tabla:

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

Ingresamos algunos registros:

insert into usuarios (nombre, clave) values ('Leonardo','payaso');


insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

Visualizamos todos los registros:

select * from usuarios;

Para actualizar los valores de todas las claves, por 'RealMadrid' tipeamos:

update usuarios set clave='RealMadrid';

Visualizamos todos los registros para verificar la actualización:

select * from usuarios;

Cambiamos el valor correspondiente a la clave de nuestro usuario llamado


'MarioPerez', por 'Boca':

update usuarios set clave='Boca'


where nombre='MarioPerez';

Verificamos el cambio:

select nombre,clave from usuarios;

28
Cambiamos el valor correspondiente al nombre de usuario 'Gustavo' por
'GustavoGarcia':

update usuarios set nombre='GustavoGarcia'


where nombre='Gustavo';

Podemos actualizar varios campos en una sola instrucción:

update usuarios set nombre='MarceloDuarte', clave='Marce'


where nombre='Marcelo';

drop table if exists usuarios;

create table usuarios (


nombre varchar(30),
clave varchar(10)
);

insert into usuarios (nombre, clave) values ('Leonardo','payaso');


insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

select * from usuarios;

update usuarios set clave='RealMadrid';

select nombre,clave from usuarios;

update usuarios set nombre='GustavoGarcia'


where nombre='Gustavo';

update usuarios set nombre='MarceloDuarte', clave='Marce'


where nombre='Marcelo';

select nombre,clave from usuarios;

Problema:

Trabaje con la tabla "agenda" que almacena los datos de sus amigos.

1- Elimine la tabla si existe.

2- Cree la tabla:
create table agenda(
apellido varchar(30),
nombre varchar(20),
domicilio varchar(30),

29
telefono varchar(11)
);

3- Visualice la estructura de la tabla "agenda" (describe).

4- Ingrese los siguientes registros (insert into):


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.

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:

A) Trabaje con la tabla "libros" de una librería.

1- Elimine la tabla.

2- Créela con los siguientes campos: titulo (cadena de 20 caracteres de longitud),


autor (cadena de 30), editorial (cadena de 15) y precio (float).

3- Visualice la estructura de la tabla "libros".

4- Ingrese los siguientes registros:


El aleph,Borges,Planeta,15.00;
Martin Fierro,Jose Hernandez,Emece,25.50;
Aprenda PHP,Mario Molina,Emece,25.00;
Cervantes y el quijote,Borges,Paidos,25;
Matematica estas ahi, Paenza, Paidos,40.80;

30
5- Muestre todos los registros.

6- Modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza".
(1 registro afectado)

7- Nuevamente, modifique los registros cuyo autor sea igual a "Paenza",


por "Adrian Paenza". (ningún registro afectado).

8- Actualice el precio del libro de "Mario Molina" a 27 pesos:

9- Actualice el valor del campo "editorial" por "Emece S.A.", para todos los
registros cuya editorial sea igual a "Emece".

B) Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con ese nombre.

1- Elimine "articulos", si existe.

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo integer,
nombre varchar(20),
descripcion varchar(30),
precio float,
cantidad integer
);

3- Vea la estructura de la tabla (describe).

4- Ingrese algunos registros:


insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (1,'impresora','Epson Stylus C45',400.80,20);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (2,'impresora','Epson Stylus C85',500,30);
insert into articulos (codigo, nombre, descripcion, precio,cantidad)
values (3,'monitor','Samsung 14',800,10);
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);

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';

7- Actualice la cantidad a 50 y el precio a 550 del artículo con código 2:


update articulos set cantidad=50, precio=550
where codigo=2;

8- Actualice la cantidad a 100 de todos los registros con cantidad=1000


(no hay registros que cumplan la condición, ningún registro afectado):
update articulos set cantidad=100
where cantidad=1000;

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.

Veamos un ejemplo, si tenemos una tabla con datos de personas, el número de


documento puede establecerse como clave primaria, es un valor que no se repite;
puede haber personas con igual apellido y nombre, incluso el mismo domicilio
(padre e hijo por ejemplo), pero su documento será siempre distinto.

Si tenemos la tabla "usuarios", el nombre de cada usuario puede establecerse


como clave primaria, es un valor que no se repite; puede haber usuarios con igual
clave, pero su nombre de usuario será siempre distinto.

Establecemos que un campo sea clave primaria al momento de creación de la


tabla:

create table usuarios (


nombre varchar(20),
clave varchar(10),
primary key(nombre)
);

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).

Ingresamos algunos registros:

insert into usuarios (nombre, clave)


values ('Leonardo','payaso');
insert into usuarios (nombre, clave)
values ('MarioPerez','Marito');
insert into usuarios (nombre, clave)
values ('Marcelo','River');
insert into usuarios (nombre, clave)
values ('Gustavo','River');

Si intentamos ingresar un valor para el campo clave que ya existe, aparece un


mensaje de error indicando que el registro no se cargó pues el dato clave existe.
Esto sucede porque los campos definidos como clave primaria no pueden
repetirse.

Ingresamos un registro con un nombre de usuario repetido, por ejemplo:

insert into usuarios (nombre, clave)


values ('Gustavo','Boca');

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.

Al establecer una clave primaria estamos indexando la tabla, es decir, creando un


índice para dicha tabla; a este tema lo veremos más adelante.

Eljemplo:

Trabajamos con la tabla "usuarios" que contiene el nombre de usuario y su clave.

Eliminamos la tabla, si existe:

drop table if exists usuarios;

Creamos la tabla:

create table usuarios (


nombre varchar(20),
clave varchar(10),
primary key (nombre)
);

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.

Ingresamos algunos registros:

insert into usuarios (nombre, clave) values ('Leonardo','payaso');


insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

Al intentar ingresar un valor repetido para el campo clave, aparece un mensaje de


error indicando que el registro no se cargó pues el dato está duplicado; veámoslo
en un ejemplo, ingresemos un registro con un nombre de usuario repetido:

insert into usuarios (nombre, clave)


values ('Gustavo','Boca');

drop table if exists usuarios;

create table usuarios (


nombre varchar(20),
clave varchar(10),
primary key (nombre)
);

describe usuarios;

insert into usuarios (nombre, clave) values ('Leonardo','payaso');


insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','River');

insert into usuarios (nombre, clave) values ('Gustavo','Boca');

Problema:

Trabaje con la tabla "libros" de una librería.

1- Elimine la tabla si existe.

2- Créela con los siguientes campos y clave: codigo (integer),


titulo (cadena de 20 caracteres de longitud), autor (cadena de 30),
editorial (cadena de 15), codigo será clave primaria.

34
create table libros(
codigo integer,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key(codigo)
);

3- Visualice la estructura de la tabla "libros", compruebe la clave primaria.

4- Ingrese los siguientes registros:


1,El aleph,Borges,Planeta;
2,Martin Fierro,Jose Hernandez,Emece;
3,Aprenda PHP,Mario Molina,Emece;
4,Cervantes y el quijote,Borges,Paidos;
5,Matematica estas ahi, Paenza, Paidos;

5- Seleccione todos los registros.

6- Ingrese un registro con código no repetido y nombre de autor repetido.

7- Ingrese un registro con código no repetido y título y editorial repetidos.

8- Intente ingresar un registro que repita el campo clave (aparece mensaje de


error por clave repetida).

Otros problemas:

A) Una empresa almacena los datos de sus clientes en una tabla llamada
"clientes".

1- Elimine la tabla "clientes" si existe:


drop table if exists clientes;

2- Créela con los siguientes campos y clave:


create table clientes(
documento varchar(8),
apellido varchar(20),
nombre varchar(20),
domicilio varchar(30),
telefono varchar (11),
primary key(documento)
);

3- Visualice la estructura de la tabla para comprobar la clave primaria establecida.

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.

6- Ingrese un cliente con código no repetido y apellido y nombre repetido.

7- Ingrese un cliente con código no repetido y domicilio repetido.

8- Intente ingresar un registro con documento repetido (aparece mensaje de error


por clave repetida).

B) Un instituto de enseñanza almacena los datos de sus estudiantes


en una tabla llamada "alumnos".

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla con la siguiente estructura:


create table alumnos(
legajo varchar(4) not null,
documento varchar(8) not null,
apellido varchar(30),
nombre varchar(30),
domicilio varchar(30),
primary key (legajo)
);
3- Ingrese los siguientes registros:
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('A233','22345345','Perez','Mariana','Colon 234');
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('A567','23545345','Morales','Marcos','Avellaneda 348');
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('B654','24356345','Gonzalez','Analia','Caseros 444');
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('A642','20254125','Torres','Ramiro','Dinamarca 209');
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('B509','20445778','Miranda','Carmen','Uspallata 999');
insert into alumnos (legajo,documento,apellido,nombre,domicilio)
values('C777','28111444','Figueroa','Natalia','Sarmiento 856');

36
4- Seleccione todos los registros.

5- Ingrese 2 alumnos con igual nombre y apellido pero distinto legajo.

6- Intente ingresar un registro que repita el campo clave ("legajo").


Aparece mensaje de error por clave repetida).

12 - Campo entero con autoincremento.


Un campo de tipo entero puede tener otro atributo extra 'auto_increment'. Los
valores de un campo 'auto_increment', se inician en 1 y se incrementan en 1
automáticamente.

Se utiliza generalmente en campos correspondientes a códigos de identificación


para generar valores únicos para cada nuevo registro que se inserta.

Sólo puede haber un campo "auto_increment" y debe ser clave primaria (o estar
indexado).

Para establecer que un campo autoincremente sus valores automáticamente, éste


debe ser entero (integer) y debe ser clave primaria:

create table libros(


codigo int auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);

Para definir un campo autoincrementable colocamos "auto_increment" luego de la


definición del campo al crear la tabla.

Hasta ahora, al ingresar registros, colocamos el nombre de todos los campos


antes de los valores; es posible ingresar valores para algunos de los campos de la
tabla, pero recuerde que al ingresar los valores debemos tener en cuenta los
campos que detallamos y el orden en que lo hacemos.

Cuando un campo tiene el atributo "auto_increment" no es necesario ingresar


valor para él, porque se inserta automáticamente tomando el último valor como
referencia, o 1 si es el primero.

Para ingresar registros omitimos el campo definido como "auto_increment", por


ejemplo:

37
insert into libros (titulo,autor,editorial)
values('El aleph','Borges','Planeta');

Este primer registro ingresado guardará el valor 1 en el campo correspondiente al


código.

Si continuamos ingresando registros, el código (dato que no ingresamos) se


cargará automáticamente siguiendo la secuencia de autoincremento.

Un campo "auto_increment" funciona correctamente sólo cuando contiene


únicamente valores positivos. Más adelante explicaremos cómo definir un campo
con sólo valores positivos.

Está permitido ingresar el valor correspondiente al campo "auto_increment", por


ejemplo:

insert into libros (codigo,titulo,autor,editorial)


values(6,'Martin Fierro','Jose Hernandez','Paidos');

Pero debemos tener cuidado con la inserción de un dato en campos


"auto_increment". Debemos tener en cuenta que:

- si el valor está repetido aparecerá un mensaje de error y el registro no se


ingresará.
- si el valor dado saltea la secuencia, lo toma igualmente y en las siguientes
inserciones, continuará la secuencia tomando el valor más alto.
- si el valor ingresado es 0, no lo toma y guarda el registro continuando la
secuencia.
- si el valor ingresado es negativo (y el campo no está definido para aceptar sólo
valores positivos), lo ingresa.

Para que este atributo funcione correctamente, el campo debe contener solamente
valores positivos; más adelante trataremos este tema.

Problema:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla estableciendo como clave primaria y "auto_increment" el campo


"codigo":

create table libros(

38
codigo integer auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);

Al visualizar la estructura de la tabla:

describe libros;

vemos que en la columna "EXTRA" del campo "codigo" aparece "auto_increment",


esto significa que el campo es autoincrementable, en la columna "KEY" aparece
"PRI", es clave primaria.

Ingresamos algunos registros:

insert into libros (titulo,autor,editorial)


values('El aleph','Borges','Planeta');

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.

Si mostramos los registros:

select * from libros;

vemos que este primer registro ingresado guardó el valor 1 en el campo


correspondiente al código, comenzó la secuencia en 1.

Ingresamos más registros:

insert into libros (titulo,autor,editorial)


values('Martin Fierro','Jose Hernandez','Emece');
insert into libros (titulo,autor,editorial)
values('Aprenda PHP','Mario Molina','Emece');
insert into libros (titulo,autor,editorial)
values('Cervantes y el quijote','Borges','Paidos');
insert into libros (titulo,autor,editorial)
values('Matematica estas ahi', 'Paenza', 'Paidos');

Seleccionamos todos los registros:

select codigo,titulo,autor,editorial from libros;

39
Vemos que el código, dato que no ingresamos, se cargó automáticamente
siguiendo la secuencia de autoincremento.

Está permitido ingresar el valor correspondiente al campo "auto_increment", por


ejemplo:

insert into libros (codigo,titulo,autor,editorial)


values(6,'Martin Fierro','Jose Hernandez','Paidos');

Pero debemos tener cuidado con la inserción de un dato en campos


"auto_increment".

Veamos los distintos casos.

Si ingresamos un valor repetido, aparecerá un mensaje de error y el registro no se


ingresará:

insert into libros (codigo,titulo,autor,editorial)


values(2,'Martin Fierro','Jose Hernandez','Planeta');

Si ingresamos un valor que no sigue la secuencia, el dato es válido, lo toma, por


ejemplo:

insert into libros (codigo,titulo,autor,editorial)


values(15,'Harry Potter y la piedra filosofal','J.K. Rowling','Emece');

El siguiente registro insertado tomará el valor más alto para seguir la secuencia
(en este caso 16):

insert into libros (titulo,autor,editorial)


values('Harry Potter y la camara secreta','J.K. Rowling','Emece');

Si ingresamos 0, no lo toma y guarda el registro continuando la secuencia (17 en


este caso):

insert into libros (codigo,titulo,autor,editorial)


values(0,'Alicia en el pais de las maravillas','Lewis Carroll','Planeta');

Si ingresamos un valor negativo (y el campo no está definido para aceptar sólo


valores positivos), lo ingresa:

insert into libros (codigo,titulo,autor,editorial)


values(-5,'Alicia a traves del espejo','Lewis Carroll','Planeta');

40
drop table if exists libros;

create table libros(


codigo integer auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);

describe libros;

insert into libros (titulo,autor,editorial)


values('El aleph','Borges','Planeta');

select * from libros libros;

insert into libros (titulo,autor,editorial)


values('Martin Fierro','Jose Hernandez','Emece');
insert into libros (titulo,autor,editorial)
values('Aprenda PHP','Mario Molina','Emece');
insert into libros (titulo,autor,editorial)
values('Cervantes y el quijote','Borges','Paidos');
insert into libros (titulo,autor,editorial)
values('Matematica estas ahi', 'Paenza', 'Paidos');

select codigo,titulo,autor,editorial from libros;

insert into libros (codigo,titulo,autor,editorial)


values(6,'Martin Fierro','Jose Hernandez','Paidos');

insert into libros (codigo,titulo,autor,editorial)


values(2,'Martin Fierro','Jose Hernandez','Planeta');

insert into libros (codigo,titulo,autor,editorial)


values(15,'Harry Potter y la piedra filosofal','J.K. Rowling','Emece');

insert into libros (titulo,autor,editorial)


values('Harry Potter y la camara secreta','J.K. Rowling','Emece');

insert into libros (codigo,titulo,autor,editorial)


values(0,'Alicia en el pais de las maravillas','Lewis Carroll','Planeta');

insert into libros (codigo,titulo,autor,editorial)


values(-5,'Alicia a traves del espejo','Lewis Carroll','Planeta');

select * from libros;

41
Problema:

Una farmacia guarda información referente a sus medicamentos en una tabla


llamada "medicamentos".

1- Elimine la tabla,si existe:


drop table if exists medicamentos;

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo integer auto_increment,
nombre varchar(20),
laboratorio varchar(20),
precio float,
cantidad integer,
primary key (codigo)
);

3- Visualice la estructura de la tabla "medicamentos" (describe).

4- Ingrese los siguientes registros (insert into):


insert into medicamentos (nombre, laboratorio,precio,cantidad)
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);

5- Verifique que el campo "código" generó los valores de modo automático:


select codigo,nombre,laboratorio,precio,cantidad
from medicamentos;

6- Intente ingresar un registro con un valor de clave primaria repetido.

7- Ingrese un registro con un valor de clave primaria no repetido salteando la


secuencia:
insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad)
values(12,'Paracetamol 500','Bago',1.90,200);

8- Ingrese el siguiente registro:


insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Bayaspirina','Bayer',2.10,150);
Note que sigue la secuencia.

42
Otros problemas:

Un videoclub almacena información sobre sus películas en una tabla llamada


"peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


-codigo (entero), autoincremento,
-titulo (cadena de 30),
-actor (cadena de 20),
-duracion (entero),
-clave primaria: codigo.

3- Visualice la estructura de la tabla "peliculas".

4- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','xxx',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','xxx',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('La vida es bella','zzz',220);

5- Seleccione todos los registros y verifique la carga automática de los códigos.

6- Actualice las películas cuyo código es 3 colocando en "actor" 'Daniel R.'

7- Elimine la película 'La vida es bella'.

8- Elimine todas las películas cuya duración sea igual a 120 minutos.

9- Visualice los registros.

10- Ingrese el siguiente registro, sin valor para la clave primaria:


insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);
Note que sigue la secuencia tomando el último valor generado, aunque ya no esté.

11- Ingrese el siguiente registro, con valor para la clave primaria:


insert into peliculas (codigo,titulo,actor,duracion)
values(1,'Tootsie','D. Hoffman',90);
Lo acepta porque la clave no está repetida.

43
12- Intente ingresar un registro con valor de clave repetida.

13- Ingrese el siguiente registro, sin valor para la clave primaria:


insert into peliculas (titulo,actor,duracion)
values('Un oso rojo','Julio Chavez',100);
Note que sigue la secuencia.

13 - Comando truncate table.


Aprendimos que para borrar todos los registro de una tabla se usa "delete" sin
condición "where".

También podemos eliminar todos los registros de una tabla con "truncate table".
Por ejemplo, queremos vaciar la tabla "libros", usamos:

truncate table libros;

La sentencia "truncate table" 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.

La diferencia con "delete" es la velocidad, es más rápido "truncate table" que


"delete" (se nota cuando la cantidad de registros es muy grande) ya que éste borra
los registros uno a uno.

Otra diferencia es la siguiente: cuando la tabla tiene un campo "auto_increment",


si borramos todos los registros con "delete" y luego ingresamos un registro, al
cargarse el valor en el campo autoincrementable, continúa con la secuencia
teniendo en cuenta el valor mayor que se había guardado; si usamos "truncate
table" para borrar todos los registros, al ingresar otra vez un registro, la secuencia
del campo autoincrementable vuelve a iniciarse en 1.

Por ejemplo, tenemos la tabla "libros" con el campo "codigo" definido


"auto_increment", y el valor más alto de ese campo es "5", si borramos todos los
registros con "delete" y luego ingresamos un registro sin valor de código, se
guardará el valor "6"; si en cambio, vaciamos la tabla con "truncate table", al
ingresar un nuevo registro sin valor para el código, iniciará la secuencia en 1
nuevamente.

44
Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla:

create table libros(


codigo integer auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);

Ingresamos algunos registros:

insert into libros (titulo,autor,editorial)


values('Martin Fierro','Jose Hernandez','Planeta');
insert into libros (titulo,autor,editorial)
values('Aprenda PHP','Mario Molina','Emece');
insert into libros (titulo,autor,editorial)
values('Cervantes y el quijote','Borges','Paidos');
insert into libros (titulo,autor,editorial)
values('Matematica estas ahi', 'Paenza', 'Paidos');
insert into libros (titulo,autor,editorial)
values('El aleph', 'Borges', 'Emece');

Eliminemos todos los registros con "delete":

delete from libros;

Veamos el resultado:

select * from libros;

La tabla ya no contiene registros.

Ingresamos un nuevo registro:

insert into libros (titulo,autor,editorial)


values('Antología poetica', 'Borges', 'Emece');

45
Veamos el resultado:

select * from libros;

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".

Ahora vaciemos la tabla:

truncate table libros;

Veamos qué sucede si ingresamos otro registro sin valor para el código:

insert into libros (titulo,autor,editorial)


values('Antología poetica', 'Borges', 'Emece');

Vemos que la secuencia de "codigo" empezó en 1 nuevamente.

Ejecutamos entonces:

select * from libros;

drop table if exists libros;


create table libros(
codigo integer auto_increment,
titulo varchar(20),
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);
insert into libros (titulo,autor,editorial)
values('Martin Fierro','Jose Hernandez','Planeta');
insert into libros (titulo,autor,editorial)
values('Aprenda PHP','Mario Molina','Emece');
insert into libros (titulo,autor,editorial)
values('Cervantes y el quijote','Borges','Paidos');
insert into libros (titulo,autor,editorial)
values('Matematica estas ahi', 'Paenza', 'Paidos');
insert into libros (titulo,autor,editorial)
values('El aleph', 'Borges', 'Emece');
delete from libros;
select * from libros;
insert into libros (titulo,autor,editorial)
values('Antología poetica', 'Borges', 'Emece');
select * from libros;
truncate table libros;
insert into libros (titulo,autor,editorial)
values('Antología poetica', 'Borges', 'Emece');
select * from libros;

46
Problema:

Una farmacia guarda información referente a sus medicamentos en una tabla


llamada "medicamentos".

1- Elimine la tabla, si existe:


drop table if exists medicamentos;

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo integer auto_increment,
nombre varchar(20),
laboratorio varchar(20),
precio float,
cantidad integer,
primary key (codigo)
);

3- Ingrese los siguientes registros:


insert into medicamentos (nombre, laboratorio,precio,cantidad)
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);

4- Elimine todos los registros con "delete":


delete from medicamentos;

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;

8- Ingrese el siguiente registro:


insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Buscapina','Roche',4.10,200);

47
9- Vea los registros para verificar que al cargar el código reinició la secuencia en
1.

Otros problemas:

Un videoclub almacena información sobre sus películas en una tabla llamada


"peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


-codigo (entero), autoincremento,
-titulo (cadena de 30),
-actor (cadena de 20),
-duracion (entero),
-clave primaria: codigo.

3- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','xxx',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','xxx',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('La vida es bella','zzz',220);

4- Seleccione todos los registros y verifique la carga automática de los códigos.

5- Elimine todos los registros:


delete from peliculas;

6- Ingrese el siguiente registro, sin valor para la clave primaria:


insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);

7- Vea los registros para verificar que al generar el valor para "codigo" continuó la
secuencia:
select *from peliculas;

8- Elimine todos los registros vaciando la tabla:


truncate table peliculas;

9- Ingrese el siguiente registro:


insert into peliculas (titulo,actor,duracion)

48
values('Elsa y Fred','China Zorrilla',90);

10- Muestre el registro ingresado para verificar que inició la secuencia


nuevamente para el campo "codigo":
select * from peliculas;

14 - Valores null.

Analizaremos la estructura de una tabla que vemos al utilizar el comando


"describe". Tomamos como ejemplo la tabla "libros":

Field Type Null Key Default Extra


______________________________________________________
codigo int(11) 7 b.. NO PRI auto_increment
titulo varchar(20) 11 b.. YES (NULL)
autor varchar(30) 11 b.. YES (NULL)
editorial varchar(15) 11 b.. YES (NULL)
precio float 5 b.. YES (NULL)

La primera columna indica el tipo de dato de cada campo.

La segunda columna "Null" especifica si el campo permite valores nulos; vemos


que en el campo "codigo", aparece "NO" y en las demás "YES", esto significa que
el primer campo no acepta valores nulos (porque es clave primaria) y los otros si
los permiten.

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".

La quinta columna "Extra", muestra algunos atributos extra de los campos; el


campo "codigo" es "auto_increment".

Vamos a explicar los valores nulos.

"null' significa "dato desconocido" o "valor inexistente". No es lo mismo que un


valor 0, una cadena vacía o una cadena literal "null".

A veces, puede desconocerse o no existir el dato correspondiente a algún campo


de un registro. En estos casos decimos que el campo puede contener valores

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.

En contraposición, tenemos campos que no pueden estar vacíos jamás, por


ejemplo, los campos que identifican cada registro, como los códigos de
identificación, que son clave primaria.

Por defecto, es decir, si no lo aclaramos en la creación de la tabla, los campos


permiten valores nulos.

Imaginemos que ingresamos los datos de un libro, para el cual aún no hemos
definido el precio:

insert into libros (titulo,autor,editorial,precio)


values ('El aleph','Borges','Planeta',null);

Note que el valor "null" no es una cadena de caracteres, no se coloca entre


comillas.

Si un campo acepta valores nulos, podemos ingresar "null" cuando no conocemos


el valor.

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:

create table libros(


codigo int auto_increment,
titulo varchar(20) not null
autor varchar(30),
editorial varchar(15),
precio float,
primary key (codigo)
);

Entonces, para que un campo no permita valores nulos debemos especificarlo


luego de definir el campo, agregando "not null". Por defecto, los campos permiten
valores nulos, pero podemos especificarlo igualmente agregando "null".

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):

select * from libros


where precio is null;

La sentencia anterior tendrá una salida diferente a la siguiente:

select * from libros


where precio=0;

Con la primera sentencia veremos los libros cuyo precio es igual a "null"
(desconocido); con la segunda, los libros cuyo precio es 0.

Igualmente para campos de tipo cadena, las siguientes sentencias "select" no


retornan los mismos registros:

select * from libros where editorial is null;


select * from libros where editorial='';

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:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla estableciendo con la siguiente estructura:

create table libros(


codigo integer auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio float,
primary key(codigo)
);

Al visualizar la estructura de la tabla con "describe", vemos lo siguiente:

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 algunos registros:

insert into libros (titulo,autor,editorial,precio)


values('El aleph','Borges','Planeta',null);

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" en un campo que no lo permite (titulo),


aparece un mensaje de error indicando tal situación:

insert into libros (titulo,autor,editorial,precio)


values (null,'Paenza','Paidos',10.30);

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:

insert into libros (codigo,titulo,autor,editorial,precio)


values (null,'El quijote de la mancha', 'Cervantes Saavedra', 'Emece',25.50);

Podemos ingresar valores nulos en los campos que lo permiten, por ejemplo, en
"editorial":

insert into libros (titulo,autor,editorial,precio)


values ('Harry Potter y la piedra filosofal', 'J.K. Rowling',null,30.00);

Ingresemos otros valores que nos servirán luego para verificar que los valores
"null" son diferentes de 0 y de cadenas vacías.

insert into libros (titulo,autor,editorial,precio)


values ('Matematica estas ahi','Paenza','Paidos',0);
insert into libros (titulo,autor,editorial,precio)
values ('Martin Fierro','Jose Hernandez','',22.50);

Explicamos que "null" no es lo mismo que una cadena vacía o un valor 0.

52
Para recuperar los registros que contengan el valor "null" en el campo "precio"
tipeamos:

select * from libros


where precio is null;

La salida será diferente a:

select * from libros


where precio=0;

Verifiquemos que las siguientes sentencias no retornan el mismo resultado:

select * from libros


where editorial is null;
select *from libros
where editorial='';

Con la primera sentencia recuperamos los libros cuya editorial es "null"; con la
segunda, los libros cuya editorial guarda una cadena vacía.

drop table if exists libros;


create table libros(
codigo integer auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio float,
primary key(codigo)
);
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',null);
insert into libros (titulo,autor,editorial,precio)
values ('Matematica estas ahi','Paenza','Paidos',0);
insert into libros (titulo,autor,editorial,precio)
values ('Martin Fierro','Jose Hernandez','',22.50);
insert into libros (titulo,autor,editorial,precio)
values ('Harry Potter y la piedra filosofal', 'J.K. Rowling',null,30.00);
select * from libros
where precio is null;
select * from libros
where precio=0;
select * from libros
where editorial is null;
select *from libros
where editorial='';

53
Problema:

Retome la tabla llamada "medicamentos" que almacena la información de los


productos que se venden en una farmacia.

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo integer auto_increment,
nombre varchar(20) not null,
laboratorio varchar(20),
precio float,
cantidad integer not null,
primary key (codigo)
);

3- Visualice la estructura de la tabla "medicamentos".

4- Ingrese los siguientes registros:


insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Sertal gotas','Roche',5.2,100);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Sertal compuesto','Roche',7.1,150);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Buscapina','Roche',null,200);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Amoxidal 500','Bayer',15.60,0);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Amoxidal jarabe','Bayer',25,120);
insert into medicamentos (nombre,laboratorio,precio,cantidad)
values('Amoxinil',null,25,120);
insert into medicamentos (nombre, laboratorio,precio,cantidad)
values('Bayaspirina','',0,150);

5- Verifique que el campo "codigo" generó los valores de modo automático


(select).
6- Recupere los registros que contengan valor "null" en el campo "laboratorio",
luego los que tengan una cadena vacía en el mismo campo. Note que el resultado
es diferente:
select * from medicamentos where laboratorio is null;
select * from medicamentos where laboratorio='';

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.

9- Ingrese el siguiente registro con valor "null" para el campo correspondiente al


código:
insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad)
values(null,'Benadryl comprimidos','Bayer',10.20,null);
No muestra un mensaje de error. Si recuperamos todos los registros, verá que
almacenó el siguiente valor de la secuencia de autoincremento.

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.

2- Créela con la siguiente estructura:


-codigo (entero, autoincremento),

55
-titulo (cadena de 30, not null),
-actor (cadena de 20),
-duracion (entero),
-clave primaria (codigo).

3- Visualice la estructura de la tabla.

4- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel R.',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel R.',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',150);
insert into peliculas (titulo,actor,duracion)
values('Titanic','L. Di Caprio',220);
insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','R. Gere-J. Roberts',200);

5- Recupere todos los registros para verificar la carga automática de los códigos.

6- Ingrese un registro con valor nulo para el campo clave primaria:


insert into peliculas (codigo,titulo,actor,duracion)
values(null,'Elsa y Fred','China Zorrilla',90);

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='';

15 - Valores numéricos sin signo (unsigned)


Hemos visto algunos atributos extra para los campos.

Los campos de tipo entero pueden tener el atributo "auto_increment", que


incrementa automáticamente el valor del campo en 1.

Los campos de cualquier tipo aceptan el atributo "null" y "not null" con lo cual
permiten o no valores nulos.

Otro atributo que permiten los campos de tipo numérico es "unsigned".

El atributo "unsigned" (sin signo) permite sólo valores positivos.

Si necesitamos almacenar edades, por ejemplo, nunca guardaremos valores


negativos, entonces sería adecuado definir un campo "edad" de tipo entero sin
signo:

edad integer unsigned;

Si necesitamos almacenar el precio de los libros, definimos un campo de tipo "float


unsigned" porque jamás guardaremos un valor negativo.

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:

Trabaje con la tabla "libros" de una librería.

Elimine la tabla, si existe:

drop table if exists libros;

Cree la tabla con la siguiente estructura:

create table libros(


codigo integer unsigned auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio float unsigned,
cantidad integer unsigned,
primary key (codigo)
);
Al definir los campos especificamos si un campo numérico es "unsigned".

El atributo "unsigned" (sin signo) sólo puede agregarse a un campo de tipo


numérico (enteros o comas flotantes) permitiendo para dicho campo sólo valores
positivos.

Si visualizamos la estructura de la tabla con "describe", vemos que en el tipo de


dato aparece este atributo:

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.

Para almacenar la cantidad de libros disponibles, definimos un campo de tipo


"integer unsigned" porque el menor valor posible será 0, nunca negativos.

drop table if exists libros;

create table libros(


codigo integer unsigned auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio float unsigned,
cantidad integer unsigned,
primary key (codigo)
);
describe libros;

Problema:

Trabaje con la tabla que almacena los datos sobre películas.

1- Elimine la tabla "peliculas", si existe.

2- Tenga en cuenta el rango de valores que almacenará cada campo:


-codigo: entero a partir de 1, autoincrementable,
-titulo: caracteres de 40 de longitud, no nulo,
-actor: cadena de 20,
-duracion: entero positivo,
-clave primaria: codigo.

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)
);

4- Visualice la estructura de la tabla.

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.

1- Elimine la tabla "visitantes", si existe.

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.

3- Visualice la estructura de la tabla.

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.

Los valores que podemos guardar son:

A) TEXTO: Para almacenar texto usamos cadenas de caracteres. Las cadenas se


colocan entre comillas simples. Podemos almacenar dígitos con los que no se
realizan operaciones matemáticas, por ejemplo, códigos de identificación,
números de documentos, números telefónicos. Tenemos los siguientes tipos:
varchar, char y text.

B) NUMEROS: 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 el tipo integer. Para
almacenar valores con decimales utilizamos: float o decimal.

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.

17 - Tipos de datos (texto)


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.

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 almacenar TEXTO usamos cadenas de caracteres. Las cadenas se colocan


entre comillas simples. Podemos almacenar dígitos con los que no se realizan
operaciones matemáticas, por ejemplo, códigos de identificación, números de
documentos, números telefónicos. Tenemos los siguientes tipos:

1) varchar(x): define una cadena de caracteres de longitud variable en la cual


determinamos el máximo de caracteres con el argumento "x" que va entre
paréntesis. Su rango va de 1 a 255 caracteres. Un varchar(10) ocupa 11 bytes,
pues en uno de ellos almacena la longitud de la cadena. Ocupa un byte más que
la cantidad definida.

2) char(x): define una cadena de longitud fija, su rango es de 1 a 255 caracteres.


Si la cadena ingresada es menor a la longitud definida (por ejemplo cargamos
'Juan' en un char(10)), almacena espacios en blanco a la derecha, tales espacios
se eliminan al recuperarse el dato. Un char(10) ocupa 10 bytes, pues al ser fija su
longitud, no necesita ese byte adicional donde guardar la longitud. Por ello, si la
longitud es invariable, es conveniente utilizar el tipo char; caso contrario, el tipo
varchar.

Ocupa tantos bytes como se definen con el argumento "x". Si ingresa un


argumento mayor al permitido (255) aparece un mensaje indicando que no se
permite y sugiriendo que use "blob" o "text". Si omite el argumento, coloca 1 por
defecto.

3) blob o text: bloques de datos de 60000 caracteres de longitud aprox. No lo


veremos por ahora.

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.

Tipo Bytes de almacenamiento


__________________________________
char(x) x
varchar(x) x+1

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.

Eliminamos la tabla "visitantes", si existe.

Creamos con la siguiente estructura:

create table visitantes(


nombre varchar(30),
edad integer unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra float unsigned
);

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.

drop table if exists visitantes;

create table visitantes(


nombre varchar(30),
edad integer unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra float unsigned
);

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:

- mediumint(x): va de –8000000 a 8000000 aprox. Sin signo va de 0 a 16000000


aprox.

- smallint(x): va de –30000 a 30000 aprox., sin signo, de 0 a 60000 aprox.

- tinyint(x): define un valor entero pequeño, cuyo rango es de -128 a 127. El tipo
sin signo va de 0 a 255.

- bool o boolean: sinónimos de tinyint(1). Un valor cero se considera falso, los


valores distintos de cero, verdadero.

- bigint(x): es un entero largo. Va de –9000000000000000000 a


9000000000000000000 aprox. Sin signo es de 0 a 10000000000000000000.

Para almacenar valores con decimales utilizamos:

2) float (t,d): número de coma flotante. Su rango es de -3.4e+38 a –1.1e-38 (9


cifras).

3) decimal o numeric (t,d): el primer argumento indica el total de dígitos y el


segundo, la cantidad de decimales. El rango depende de los argumentos, también
los bytes que ocupa. Si queremos almacenar valores entre 0.00 y 99.99 debemos
definir el campo como tipo "decimal (4,2)". Si no se indica el valor del segundo
argumento, por defecto es 0. Para los tipos "float" y "decimal" se utiliza el punto
como separador de decimales.

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.

Tipo Bytes de almacenamiento


_______________________________________
tinyint 1
smallint 2
mediumint 3
int 4
bigint 8

float 4
decimal(t,d) t+2 si d>0, t+1 si d=0 y d+2 si t<d

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla con la siguiente estructura:

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 smallint unsigned,
primary key (codigo)
);

Note que definimos el campo "cantidad" de tipo "smallint unsigned", esto es


porque los valores para este campo serán siempre positivos (mayores o iguales a
0), además la cantidad disponible no superará los 60000 aprox., así que no es
adecuado usar int (cuyo rango llega hasta 4000 millones aprox.), así ocupamos
menos espacio (3 bytes para mediumint contra 4 bytes para int). Es importante
elegir el tipo de dato más preciso.

Como en el campo "precio" almacenaremos valores entre 0.00 y 999.99 definimos


el campo como tipo "decimal (5,2)", así evitamos tantos decimales innecesarios
que teníamos antes con el tipo "float".

64
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 smallint unsigned,
primary key (codigo)
);

describe libros;

Problema:

Un comercio que envía pizzas y empanadas a domicilio registra los pedidos


diariamente en una tabla llamada "pedidos" con los siguientes datos:
- numero de pedido, autoincrementable, entero positivo comienza en 1 y menor a
200 aprox.
- nombre: pizza o empanada,
- tipo: por ejemplo, si es pizza: especial, muzarela, etc., si son empanadas:
salteñas, picantes, árabes, etc.
- precio: precio por unidad, valor con decimales que no supera los $99.99 y será
siempre mayor a 0,
- cantidad: cantidad de artículos, entero positivo desde 1 e inferior a 200 aprox.
- domicilio del cliente.

1- Elimine la tabla "pedidos" si existe.

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo.

Otros problemas:

A) El departamento de Meteorología de una ciudad tiene almacenados en una


tabla las estadísticas de
temperatura y precipitaciones de varias ciudades del mundo. La tabla tiene
registrados los
siguientes datos:

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

1- Elimine la tabla "estadisticas".

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.

B) Un instituto de física que realiza investigaciones acerca de los gases guarda en


una tabla las
temperaturas críticas y la presión crítica de los mismos. La tabla contiene estos
registros:

Gas Temperatura Crítica Presión Crítica


________________________________________________________
Helio -269.7 2.26
Hidrógeno -239.9 12.8
Nitrógeno -147.1 33.5
Oxígeno -120.0 50.1
Dióx. de carb. 31.3 72.9
Amoníaco 132.4 111.5
Vapor de agua 374.2 218.0

1- Elimine la tabla "gases" si existe.

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:

Número de Cuenta Documento Nombre Saldo


______________________________________________________________
1234 22555666 Perez Luis 2000.60
2566 33558778 Pereyra Maria 5050.00
3456 34567765 Lopez Susana 10.00
3900 34590697 Torres Marcos -50.50
4560 35098098 Juarez Ana -232.00

1- Elimine la tabla "cuentas" si existe. 2- Cree la tabla eligiendo el tipo de dato


adecuado para almacenar los datos descriptos arriba: - Número de cuenta: entero
positivo, no nulo, - Documento del propietario de la cuenta: cadena de caracteres
de 8 de longitud (siempre 8), no nulo - Nombre del propietario de la cuenta:
cadena de caracteres, - Saldo de la cuenta: valores positivos y negativos altos.

19 - Tipos de datos (fechas y horas)


Para guardar fechas y horas dispone de varios tipos:

1) date: representa una fecha con formato "YYYY-MM-DD". El rango va de "1000-


01-01" a "9999-12-31".

2) datetime: almacena fecha y hora, su formato es "YYYY-MM-DD HH:MM:SS". El


rango es de "1000-01-01 00:00:00" a "9999-12-31 23:59:59".

3) time: una hora. Su formato es "HH:MM:SS". El rango va de "-838:59:59" a


"838:59:59".

4) year(2) y year(4): un año. Su formato es "YYYY" o "YY". Permite valores desde


1901 a 2155 (en formato de 4 dígitos) y desde 1970 a 2069 (en formato de 2
dígitos).

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.

Si ingresamos un valor numérico 0, se convierte en "0000"; entre 1 y 69, se


convierte a valores "year" entre 2001 a 2069; entre 70 y 99, es convertido a
valores "year" de 1970 a 1999.

Para almacenar valores de tipo fecha se permiten como separadores "/", "-" y ".".

Si ingresamos '06-12-31' (año de 2 dígitos), lo toma como '2006-12-31'.

67
Si ingresamos '2006-2-1' (mes y día de 1 dígito), lo toma como '2006-02-01'.

Si ingresamos '20061231' (cadena sin separador), lo toma como '2006-12-31'.

Si ingresamos 20061231 (numérico), lo toma como '2006-12-31'.

Si ingresamos '20061231153021' (cadena sin separadores), lo toma como '2006-


12-31 15:30:21'.

Si ingresamos '200612311530' (cadena sin separadores con un dato faltante) no lo


reconoce como fechahora y almacena ceros.

Si ingresamos '2006123' (cadena sin separadores con un dato faltante) no lo


reconoce como fecha y almacena ceros.

Si ingresamos '2006-12-31 11:30:21' (valor date time) en un campo 'date', toma


sólo la parte de la fecha, la hora se corta, se guarda '2006-12-31'.

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".

Tipo Bytes de almacenamiento


_______________________________________
date 3
datetime 8
time 3
year 1

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".

Eliminamos la tabla "vehiculos" si existe:

drop table if exists vehiculos;

Creamos la tabla con la siguiente estructura:

create table vehiculos(


patente char(6) not null,
tipo char (4),
horallegada time not null,

68
horasalida time
);

Hemos definido el campo "patente" de tipo "char" y no "varchar" porque la cadena


de caracteres siempre tendrá la misma longitud (6 caracteres), con esta definición
ocupamos 6 bytes, si lo hubiésemos definido como "varchar(6)" ocuparía 7 bytes.
Lo mismo sucede con el campo "tipo", en el cual almacenaremos "auto" o "moto",
necesitamos 4 caracteres fijos. Para los campos que registran la hora de llegada y
de salida de cada vehículo usamos "time" porque solamente almacenaremos
horas, no fechas.

Ingresamos algunos registros:

insert into vehiculos (patente,tipo,horallegada) values ('ACD123','auto','8:30');


insert into vehiculos (patente,tipo,horallegada) values('BGF234','moto','8:35');
insert into vehiculos (patente,tipo,horallegada) values('KIU467','auto','9:40');

Vemos los registros cargados:

select * from vehiculos;

Note que no ingresamos los segundos y colocó por defecto "00" para ellos.

Actualizamos la hora de salida del vehículo con patente "ACD123":

update vehiculos set horasalida='11:45'


where patente='ACD123';

Ingresemos un registro con la hora, sin los minutos:

insert into vehiculos values('LIO987','auto','10',null);

veamos lo que sucedió:

select * from vehiculos;

almacenó el valor ingresado como si fueran segundos.

Ingresamos un valor de horas y minutos sin separador:

insert into vehiculos values('GTR987','auto','1010',null);

incluye el separador, almacena "10:10".

Si ingresamos un valor "datetime" (fecha y hora), almacena solamente la hora:

69
insert into vehiculos values('HTR234','auto','2006-12-15 12:15',null);

Si ingresamos un separador diferente al permitido, por ejemplo "/", guarda


solamente el último valor y lo coloca como segundos:

insert into vehiculos values('KUY246','auto','12/15',null);

almacena "00:00:15".

drop table if exists vehiculos;


create table vehiculos(
patente char(6) not null,
tipo char (4),
horallegada time not null,
horasalida time
);
insert into vehiculos (patente,tipo,horallegada) values ('ACD123','auto','8:30');
insert into vehiculos (patente,tipo,horallegada) values('BGF234','moto','8:35');
insert into vehiculos (patente,tipo,horallegada) values('KIU467','auto','9:40');
select * from vehiculos;
update vehiculos set horasalida='11:45'
where patente='ACD123';
insert into vehiculos values('LIO987','auto','10',null);
select * from vehiculos;
insert into vehiculos values('GTR987','auto','1010',null);
insert into vehiculos values('HTR234','auto','2006-12-15 12:15',null);
insert into vehiculos values('KUY246','auto','12/15',null);
select * from vehiculos;

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.).

1- Elimine la tabla si existe.

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);

4- Seleccione todos los autos cuyo modelo sea menor a "1995":


select * from autos
where modelo<1995;

5- Muestre la marca y modelo de los autos que no sean de "1970":


select marca,modelo from autos
where modelo<>1970;

6- Ingrese un auto con el valor para "modelo" de tipo numérico:


insert into autos values('Peugeot 505',1995,'Carlos Lopez',88000);

Otros problemas:

Una empresa almacena los datos de sus empleados en una tabla "empleados".

1- Elimine la tabla, si existe:


drop table if exists empleados;

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo:


create table empleados(
nombre varchar(20),
documento char(8),
sexo char(1),
domicilio varchar(30),
fechaingreso date
);

3- Ingrese algunos registros:


insert into empleados
values('Juan Perez','22333444','m','Colon 123','1990-10-08');
insert into empleados
values('Ana Acosta','23333444','f','Caseros 987','1995-12-18');
insert into empleados
values('Lucas Duarte','25333444','m','Sucre 235','2005-05-15');
insert into empleados
values('Pamela Gonzalez','26333444','f','Sarmiento 873','1999-02-12');
insert into empleados
values('Marcos Juarez','30333444','m','Rivadavia 801','2002-09-22');

71
4- Seleccione todos los datos de los empleados que ingresaron a la empresa
antes del 2000:
select * from empleados
where fechaingreso<'2000';

5- Muestre el nombre y la fecha de ingreso de los empleados de sexo masculino:


select nombre,fechaingreso from empleados
where sexo='m';

6- Modifique la fecha de ingreso del empleado con documento "22333444" a


"1990-10-18":
update empleados set fechaingreso='1990-10-18'
where documento='22333444';

7- Ingrese un empleado con valor para "fechaingreso" en la cual coloque 2 digitos


correspondientes al año:
insert into empleados
values('Susana Duarte','30123456','f','Sucre 1234','99-02-12');

8- Ingrese un empleado colocando sólo un dígito en la parte de la fecha


correspondiente al mes y día:
insert into empleados
values('Daniel Herrero','30000001','m',null,'1980-2-03');

9- Ingrese una fecha de ingreso sin separadores:


insert into empleados
values('Ana Juarez','31123123','f',null,'19900306');

10- Ingrese un valor de tipo fecha y hora:


insert into empleados
values('Juan Mores','32222333','m',null,'1990-03-06 10:15');
Sólo guarda la parte de la fecha.

11- Ingrese un valor que MySQL no reconozca como fecha:


insert into empleados
values('Hector Perez','34444555','m',null,'1990036');
Almacenará ceros.

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.

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.

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.

Tipo Valor por defecto Cláusula "default"


__________________________________________________________________
caracter not null cadena vacía permite
numerico not null 0 permite
fecha not null 0000-00-00 permite
hora not null 00:00:00 permite
auto_increment siguiente de la sec., empieza en 1 no permite
carac.,numer.,fecha,hora null null permite

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

73
drop table if exists libros;

Creamos la tabla con la siguiente estructura:

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)
);

Veamos en algunos ejemplos qué sucede cuando al ingresar un registro no


colocamos valores para algunos campos:

insert into libros (titulo,autor,precio)


values('El aleph','Borges',23.6);

En el campo "codigo" ingresará el siguiente valor de la secuencia porque es


"auto_increment"; en el campo "editorial" almacenará "null", porque el campo
acepta valores nulos y en el campo "cantidad" ingresará 0 porque es el valor por
defecto de los campos numéricos que no admiten valores nulos.

Ingresamos otro registro con algunos valores explícitos:

insert into libros (autor,editorial,cantidad)


values('Borges','Planeta',100);

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" y en el campo "precio" guardará "null" porque es el valor por
defecto de los campos no definidos como "not null.

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,precio)
values('El aleph','Borges',23.6);
select * from libros;

74
insert into libros (autor,editorial,cantidad)
values('Borges','Planeta',100);

select * from libros;

Problema:

Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


-codigo (entero sin signo, autoincrementable),
-titulo (cadena de 30, not nulo),
-actor (cadena de 20),
-duracion (entero positivo hasta 200 apox.),
-clave primaria (codigo).

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".

1- Elimine la tabla, si existe.

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.

Veamos los distintos tipos de datos inválidos.

Para campos de tipo caracter:

-valor numérico: si en un campo definido de tipo caracter ingresamos un valor


numérico, lo convierte automáticamente a cadena. Por ejemplo, si guardamos 234
en un varchar, almacena '234'.

-mayor longitud: si intentamos guardar una cadena de caracteres mayor a la


longitud definida, la cadena se corta guardando sólo la cantidad de caracteres que
quepa. Por ejemplo, si 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.

Para campos numéricos:

-cadenas: si en un campo numérico ingresamos una cadena, lo pasa por alto y


coloca 0. Por ejemplo, si en un campo de tipo "integer" guardamos 'abc',
almacenará 0.

-valores fuera de rango: si en un campo numérico intentamos guardar un valor


fuera de rango, se almacena el valor límite del rango más cercano (menor o
mayor). Por ejemplo, si definimos un campo 'tinyint' (cuyo rango va de -128 a 127)
e intentamos guardar el valor 200, se almacenará 127, es decir el máximo
permitido del rango; si intentamos guardar -200, se guardará -128, el mínimo
permitido por el rango. Otro ejemplo, si intentamos guardar el valor 1000.00 en un
campo definido como decimal(5,2) guardará 999.99 que es el mayor del rango.

-valores incorrectos: si cargamos en un campo definido de tipo decimal un valor


con más decimales que los permitidos en la definición, el valor es redondeado al
más cercano. Por ejemplo, si cargamos en un campo definido como decimal(4,2)
el valor 22.229, se guardará 22.23, si cargamos 22.221 se guardará 22.22.

Para campos definidos auto_increment el tratamiento es el siguiente:

- 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.

- Si ingresamos un valor existente, aparece un mensaje de error indicando que el


valor ya existe.

Para campos de fecha y hora:

-valores incorrectos: si intentamos almacenar un valor que MySql no reconoce


como fecha (sea fuera de rango o un valor inválido), convierte el valor en ceros
(según el tipo y formato). Por ejemplo, si intentamos guardar '20/07/2006' en un
campo definido de tipo "date", se almacena '0000-00-00'. Si intentamos guardar
'20/07/2006 15:30' en un campo definido de tipo "datetime", se almacena '0000-00-
00 00:00:00'. Si intentamos almacenar un valor inválido en un campo de tipo
"time", se guarda ceros. Para "time", si intentamos cargar un valor fuera de rango,
se guarda el menor o mayor valor permitido (según sea uno u otro el más
cercano).

Para campos de cualquier tipo:

-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:

Tipo Valor inválido Resultado


_____________________________________________________________
caracter null/ not null 123 '123'
caracter null/ not null mayor longitud se corta
caracter not null null error
numérico null/ not null '123' 0
numérico null/ not null fuera de rango límite más cercano
numérico not null null error
numérico decimal null/ not null más decimales que los definidos redondea al más cercano
num. auto_incr. c/signo null/not null 0 siguiente de la secuencia
num. auto_incr. s/signo null/not null todos los menores a 1 siguiente de la secuencia
num. auto_incr. c/s signo null null siguiente de la secuencia
num. auto_incr. c/s signo null/not null valor existente error
fecha fuera de rango 0000-00-00
fecha '20-07-2006' (otro orden) 0000-00-00
hora fuera de rango límite más cercano
fecha y hora not null null error

78
Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla con la siguiente estructura:

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)
);

Ingresemos algunos registros con valores inválidos y veamos qué sucede:

insert into libros (titulo,autor,editorial,precio)


values ('Alicia en el pais de las maravillas',555,'Planeta',23.45);

En el campo "titulo" ingresamos una cadena de más de 20 caracteres (que es la


longitud definida para el campo), como resultado, corta la cadena ingresada. En el
campo "autor" ingresamos un valor numérico, lo convierte a cadena.

Ingresemos otro registro:

insert into libros (titulo,autor,editorial,precio,cantidad)


values ('Matematica estas ahi','Paenza','Planeta','abc',20000000);

En el campo "precio" ingresamos una cadena, la pasa por alto y coloca 0. En el


campo "cantidad" ingresamos un valor fuera de rango, entonces guarda el valor
límite más cercano del rango (16777215).

Ingresemos otro registro:

insert into libros (titulo,editorial,precio)


values ('Alegoria','Planeta',3333.50);

Como cargamos en el campo "precio" (decimal 5,2) un fuera de rango, almacenó


el máximo valor permitido por el rango (999.99).

79
Ingresemos otro registro:

insert into libros (titulo,editorial,precio)


values ('Alegoria','Planeta',33.567);

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).

Ingresemos otro registro:

insert into libros (codigo,titulo)


values (2,'El gato con botas');

Aparece un mensaje de error indicando que la clave está duplicada.

Ingresemos otros registros:

insert into libros (codigo,titulo)


values (0,'El gato con botas');
insert into libros (codigo,titulo)
values (-5,'Robin Hood');

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.

Veamos qué sucede con los valores "null":

insert into libros (codigo,titulo)


values (null,'Alicia a traves del espejo');

Si intentamos ingresar "null" para el código, lo pasa por alto y sigue la secuencia.

Otro ejemplo:

insert into libros (titulo,autor)


values (null,'Borges');

Aparece un mensaje de error indicando que el campo "titulo" no acepta valores


nulos.

Otro ejemplo:
insert into libros (titulo,autor,cantidad)
values ('Antologia poetica','Borges',null);

Muestra un mensaje de error indicando que el campo "cantidad" no acepta valores


nulos.

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".

1- Elimine la tabla "empleados" si existe.

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)
);

3- Intente ingresar la fecha "20-10-2005" para la fecha de ingreso:


insert into empleados (documento,fechaiIngreso,fechanacimiento)
values('22333444','20-10-2005',null);
Se almacenan ceros.

4- Intente almacenar "null" en "fechaingreso":


insert into empleados (documento,fechaingreso,fechanacimiento)
values('22333444',null,'2005-10-10');
Muestra un mensaje de error.

5- Intente almacenar valores nulos en los campos "documento" y " nombre".

6- Almacene un valor numérico en un campo de tipo caracter.

7- Almacene en "documento" el valor "22.345.678".

Otros problemas:

Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


create table peliculas(
codigo int unsigned auto_increment,
titulo varchar(15) not null,
actor varchar(20),
duracion tinyint unsigned,
primary key (codigo)
);

3- Ingrese el siguiente registro:


insert into peliculas values(-10,'Mision imposible','Tom Cruise',120);

4- Muestre los registros para ver qué valor se guardó en "codigo".

5- Intente ingresar el siguiente registro (error por clave duplicada):


insert into peliculas values(1,'Mision imposible 2','Tom Cruise',120);

6- Intente ingresar el siguiente registro:


insert into peliculas values(null,'Mision imposible 2','Tom Cruise',120);

82
7- Muestre los registros para ver qué valor se guardó en "codigo".

8- Intente ingresar el siguiente registro (no ingresa, el campo "título" no admite


valores nulos):
insert into peliculas values(3,null,'Tom Cruise',120);

9- Ingrese el siguiente registro:


insert into peliculas values(5,'Harry Potter y la camara secreta','Daniel R.',150);

10- Muestre los registros para ver qué se almacenó en "titulo" (cadena cortada).

11- Ingrese el siguiente registro:


insert into peliculas values(10,'Elsa y Fred','China Zorrilla',12345);

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).

22 - Atributo default en una columna de una tabla.


Si al insertar registros no se especifica un valor para un campo, se inserta su valor
por defecto implícito según el tipo de dato del campo. Por ejemplo:

insert into libros (titulo,autor,editorial,precio,cantidad)


values('Java en 10 minutos','Juan Pereyra','Paidos',25.7,100);

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.

Si omitimos el valor correspondiente al autor:

insert into libros (titulo,editorial,precio,cantidad)


values('Java en 10 minutos','Paidos',25.7,200);

MySQL insertará "null", porque el valor por defecto de un campo (de cualquier
tipo) que acepta valores nulos, es "null".

Lo mismo sucede si no ingresamos el valor del precio:

insert into libros (titulo,autor,editorial,cantidad)


values('Java en 10 minutos','Juan Pereyra',Paidos',150);

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:

insert into libros (autor,editorial,precio,cantidad)


values ('Borges','Paidos',25.7,200);

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).

Si omitimos el valor correspondiente a la cantidad:

insert into libros (titulo,autor,editorial,precio)


values('Alicia a traves del espejo','Lewis Carroll','Emece',34.5);

el valor que se almacenará será 0, porque el campo "precio" es de tipo numérico


"not null" y el valor por defecto de los tipos numéricos que no aceptan valores
nulos es 0.

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":

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) default 'Desconocido',
precio decimal(5,2) unsigned default 1.11,
cantidad int unsigned not null,
primary key (codigo)
);

Si al ingresar un nuevo registro omitimos los valores para el campo "autor" y


"precio", MySQL insertará los valores por defecto definidos con la palabra clave
"default":

insert into libros (titulo,editorial,cantidad)


values('Java en 10 minutos','Paidos',200);

MySQL insertará el registro con el siguiente valor de la secuencia en "codigo", con


el título, editorial y cantidad ingresados, en "autor" colocará "Desconocido" y en
precio "1.11".

Entonces, si al definir el campo explicitamos un valor mediante la cláusula


"default", ése será el valor por defecto; sino insertará el valor por defecto implícito
según el tipo de dato del campo.

84
Los campos definidos "auto_increment" no pueden explicitar un valor con "default",
tampoco los de tipo "blob" y "text".

Los valores por defecto implícitos son los siguientes:

-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:

-para campos numéricos no declarados "auto_increment": 0;

-para campos numéricos definidos "auto_increment": el valor siguiente de la


secuencia, comenzando en 1;

-para los tipos cadena: cadena vacía.

Ahora al visualizar la estructura de la tabla con "describe" podemos entender un


poco más lo que informa cada columna:

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:

insert into libros (titulo,autor,precio,cantidad)


values ('El gato con botas',default,default,100);

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

85
Creamos la tabla con la siguiente estructura:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
editorial varchar(15),
autor varchar(30) default 'Desconocido',
precio decimal(5,2) unsigned default 1.11,
cantidad mediumint unsigned not null,
primary key (codigo)
);

Ingresamos algunos registros omitiendo algunos campos para ver cómo trabaja la
cláusula "default".

insert into libros (titulo,autor,editorial,precio,cantidad)


values('Java en 10 minutos','Juan Pereyra','Paidos',25.7,100);

Como no ingresamos valor para el campo "codigo", se insertará el valor por


defecto implícito, como "codigo" es un campo "auto_increment", el valor por
defecto es el siguiente de la secuencia.

Si omitimos el valor correspondiente al título:

insert into libros (autor,editorial,precio,cantidad)


values('Juan Perez','Planeta',28.50,50);

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.

Lo mismo sucede si no ingresamos un valor para la editorial:

insert into libros (titulo,autor,precio,cantidad)


values('Aprenda PHP','Alberto Lopez',55.40,150);

Se almacenará una cadena vacía.

Si omitimos el valor correspondiente al autor:

insert into libros (titulo,editorial,precio,cantidad)


values ('El gato con botas','Emece',15.6,150);

Se guardará "Desconocido" ya que éste es el valor por defecto que explicitamos al


definir el campo.

86
Si omitimos el valor correspondiente al precio:

insert into libros (titulo,autor,editorial,cantidad)


values ('El aleph','Borges','Emece',200);

Se guardará "1.11" ya que éste es el valor por defecto que explicitamos al definir
el campo.

Si omitimos el valor correspondiente a la cantidad:

insert into libros (titulo,autor,editorial,precio)


values('Alicia a traves del espejo','Lewis Carroll', 'Emece',34.5);

el valor que se almacenará será 0, porque con la cláuslua "default" establecimos


este valor por defecto para este campo.

También podemos usar "default" para dar el valor por defecto a los campos en
sentencias "insert", por ejemplo:

insert into libros (titulo,autor,editorial,precio,cantidad)


values ('El gato con botas',default,'Planeta',default,100);

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
editorial varchar(15),
autor varchar(30) default 'Desconocido',
precio decimal(5,2) unsigned default 1.11,
cantidad mediumint unsigned not null,
primary key (codigo)
);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Java en 10 minutos','Juan Pereyra','Paidos',25.7,100);
insert into libros (autor,editorial,precio,cantidad)
values('Juan Perez','Planeta',28.50,50);
insert into libros (titulo,autor,precio,cantidad)
values('Aprenda PHP','Alberto Lopez',55.40,150);
insert into libros (titulo,editorial,precio,cantidad)
values ('El gato con botas','Emece',15.6,150);
insert into libros (titulo,autor,editorial,cantidad)
values ('El aleph','Borges','Emece',200);
insert into libros (titulo,autor,editorial,precio)
values('Alicia a traves del espejo','Lewis Carroll', 'Emece',34.5);
insert into libros (titulo,autor,editorial,precio,cantidad)
values ('El gato con botas',default,'Planeta',default,100);
select * from libros;

87
Problema:

Un comercio que envía pizzas y empanadas a domicilio registra los pedidos


diariamente en una tabla llamada "pedidos" con los siguientes datos:

- numero de pedido, autoincrementable, entero positivo comienza en 1 y menor a


200 aprox.
- nombre: pizza o empanada, por defecto "empanada",
- tipo: por ejemplo, si es pizza: especial, muzarela, etc., si son empanadas:
arabes, pollo, jamón y queso, criollas, etc.
- precio: precio por unidad, valor con decimales que no supera los $99.99 y será
siempre mayor a 0, por defecto "1",
- cantidad: cantidad de articulos, entero positivo desde 1 e inferior a 200 aprox.,
por defecto "12"
- domicilio del cliente.

1- Elimine la tabla "pedidos" si existe.

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo.

3- Ingrese los siguientes registros:


insert into pedidos (nombre,tipo,precio,cantidad,domicilio)
values('piza','muzarela','4.00',3,'Sarmiento 235');
insert into pedidos (tipo,precio,cantidad,domicilio)
values('arabe','1.00',24,'Urquiza 296');
insert into pedidos (nombre,tipo,domicilio)
values('empanada','salteña','Colon 309');
insert into pedidos (tipo,domicilio)
values('arabe','San Martin 444');
insert into pedidos (nombre,tipo,precio,domicilio)
values('piza','especial','4.00','Avellaneda 395');

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.

1- Elimine la tabla "visitantes", si existe.

2- Cree la tabla con la siguiente estructura:

create table visitantes( nombre varchar(30) not null,


edad tinyint unsigned,

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".

5- Muestre todos los registros.

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.

1- Elimine la tabla "prestamos" 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,
devuelto char(1) default 'n'
);

3- Ingrese algunos registros:


insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion)
values ('Manual de 1 grado','23456789','2006-08-10','2006-08-12');
insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion)
values ('Alicia en el pais de las maravillas','23456789','2006-08-12','2006-08-14');
insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion)
values ('El aleph','22543987','2006-08-15','2006-08-17');
insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion)
values ('Manual de geografia 5 grado','25555666','2006-08-30','2006-09-01');

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.

Cualquier campo numérico puede tener otro atributo extra "zerofill".


"zerofill" rellena con ceros los espacios disponibles a la izquierda.
Por ejemplo, creamos la tabla "libros", definiendo los campos "codigo" y "cantidad"
con el atributo "zerofill":

create table libros(


codigo int(6) zerofill auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
cantidad smallint zerofill,
primary key (codigo)
);

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.

Si especificamos "zerofill" a un campo numérico, se coloca automáticamente el


atributo "unsigned".

Cualquier valor negativo ingresado en un campo definido "zerofill" es un valor


inválido.

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

90
Creamos la tabla:

create table libros(


codigo int(6) zerofill auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
cantidad smallint zerofill,
primary key (codigo)
);

Visualizamos la estructura de la tabla:

describe libros;

Vemos que en la columna "Type" se muestra el atributo "zerofill" en los campos en


los cuales lo especificamos.

Ingresemos algunos registros:

insert into libros (titulo,autor,editorial,precio,cantidad)


values('Martin Fierro','Jose Hernandez','Planeta',34.5,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',45.7,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Borges','Paidos',23,40);

Veamos cómo se guardaron los datos:

select * from libros;

Los valores de código están rellenados a la izquierda con ceros; también los del
campo "cantidad".

Probemos ingresar un valor para código saltando la secuencia:

insert into libros (codigo,titulo,autor,editorial,precio,cantidad)


values('545','El aleph', 'Borges', 'Emece',33,20);

Veamos cómo lo guardó:

select * from libros;

Ingresemos un valor negativo para los campos definidos "zerofill":

91
insert into libros (codigo,titulo,autor,editorial,precio,cantidad)
values(-400,'Matematica estas ahi', 'Paenza', 'Paidos',15.2,-100);

Veamos lo que sucedió:

select * from libros;

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".

drop table if exists libros;


create table libros(
codigo int(6) zerofill auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,
cantidad smallint zerofill,
primary key (codigo)
);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Martin Fierro','Jose Hernandez','Planeta',34.5,200);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Aprenda PHP','Mario Molina','Emece',45.7,50);
insert into libros (titulo,autor,editorial,precio,cantidad)
values('Cervantes y el quijote','Borges','Paidos',23,40);
select * from libros;
insert into libros (codigo,titulo,autor,editorial,precio,cantidad)
values('545','El aleph', 'Borges', 'Emece',33,20);
select * from libros;
insert into libros (codigo,titulo,autor,editorial,precio,cantidad)
values(-400,'Matematica estas ahi', 'Paenza', 'Paidos',15.2,-100);
select * from libros;

Problema:

Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".

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)
);

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".

4- Ingrese los siguientes registros:


insert into cuentas (numero,documento,nombre,saldo)
values(1234,'22333444','Juan Perez',2000.60);
insert into cuentas (numero,documento,nombre,saldo)
values(2566,'23333444','Maria Pereyra',5050);
insert into cuentas (numero,documento,nombre,saldo)
values(5987,'24333444','Marcos Torres',200);
insert into cuentas (numero,documento,nombre,saldo)
values(14434,'25333444','Ana Juarez',8000.60);

5- Vea cómo se guardaron los números de cuenta:


select * from cuentas;

6- Ingrese un valor negativo para el número de cuenta:


insert into cuentas (numero,documento,nombre,saldo)
values(-1234,'27333444','Luis Duarte',2800);
note que no lo toma y sigue la secuencia.

Otros problemas:

Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


create table peliculas(
codigo int(4) zerofill auto_increment,
titulo varchar(30) not null,
actor varchar(20),
duracion tinyint zerofill default 90,
primary key (codigo)
);
3- Vea la estructura de la tabla:
describe peliculas;
note que el atributo "zerofill" aparece en los campos "codigo" y "duracion", en la
columna que describe el tipo de cada dato.

4- Ingrese algunos registros.

5- Ingrese un valor de código negativo.

6- Ingrese un valor de duración negativo.

93
24 - Columnas calculadas.

Es posible obtener salidas en las cuales una columna sea el resultado de un


cálculo y no un campo de una tabla.

Si queremos ver los títulos, precio y cantidad de cada libro escribimos la siguiente
sentencia:

select titulo,precio,cantidad
from libros;

Si queremos saber el monto total en dinero de un título podemos multiplicar el


precio por la cantidad por cada título, pero también podemos hacer que MySQL
realice el cálculo y lo incluya en una columna extra en la salida:

select titulo, precio,cantidad,precio*cantidad


from libros;

Si queremos saber el precio de cada libro con un 10% de descuento podemos


incluir en la sentencia los siguientes cálculos:

select titulo, precio,precio*0.1,precio-(precio*0.1)


from libros;

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

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,
cantidad smallint unsigned,
primary key (codigo)
);

94
Ingresamos algunos registros:

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','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);

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:

select titulo, precio,cantidad,precio*cantidad


from libros;

Para saber el precio de cada libro con un 10% de descuento podemos incluir en la
sentencia los siguientes cálculos:

select titulo, precio,precio*0.1,precio-(precio*0.1)


from libros;

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 smallint 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);

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".

1- Elimine la tabla "empleados" si existe.

2- Cree una tabla llamada "empleados" con la estructura necesaria para


almacenar la siguiente información:
- nombre del empleado,
- documento,
- sexo,
- domicilio,
- sueldo básico (hasta 9999.99),
- hijos a cargo,
- clave primaria: documento.

3- Ingrese algunos registros:


insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Juan Perez','22333444','m',300,1);
insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Ana Acosta','21333444','f',400,2);
insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Alberto Lopez','24333444','m',600,0);
insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Carlos Sanchez','30333444','m',550,3);
insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Mariana Torres','23444555','f',600,1);
insert into empleados (nombre,documento,sexo,sueldobasico,hijos)
values ('Marcos Garcia','23664555','m',1500,2);

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):

select nombre, sueldobasico,hijos,(200*hijos),sueldobasico+(200*hijos)


from empleados;

Otros problemas:

Un comercio vende artículos de librería y papelería. Almacena en una tabla los


siguientes datos:
- codigo: int unsigned auto_increment, clave primaria,
- nombre: varchar(30),
- precio: decimal(5,2),
- cantidad: smallint unsigned.

1- Elimine la tabla, si existe.

2- Cree la tabla con la estructura necesaria para almacenar los datos descriptos
anteriormente.

3- Ingrese los siguientes registros:


insert into articulos (nombre,precio,cantidad)
values ('lapices coloresx6',1.4,100);
insert into articulos (nombre,precio,cantidad)
values ('lapices coloresx12',2.5,100);
insert into articulos (nombre,precio,cantidad)
values ('lapices coloresx24',4.7,100);
insert into articulos (nombre,precio,cantidad)
values ('goma tinta',0.2,150);
insert into articulos (nombre,precio,cantidad)
values ('birome',1.2,200);
insert into articulos (nombre,precio,cantidad)
values ('escuadra',3.2,200);
insert into articulos (nombre,precio,cantidad)
values ('compás plástico',5,200);
insert into articulos (nombre,precio,cantidad)
values ('compás metal',8.4,250);

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;

5- El gerente de dicho comercio necesita saber cuánto dinero hay invertido en


cada artículo, para ello, necesitamos multiplicar el precio de cada artículo por la
cantidad:
select nombre,precio,cantidad,precio*cantidad
from articulos;

25 - Funciones para el manejo de cadenas.


RECUERDE que NO debe haber espacios entre un nombre de función y los
paréntesis porque MySQL puede confundir una llamada a una función con una
referencia a una tabla o campo que tenga el mismo nombre de una función.

MySQL tiene algunas funciones para trabajar con cadenas de caracteres. Estas
son algunas:

-ord(caracter): Retorna el código ASCII para el caracter enviado como argumento.


Ejemplo:

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".

-concat(cadena1,cadena2,...): devuelve la cadena resultado de concatenar los


argumentos. Ejemplo:

select concat('Hola,',' ','como esta?');

retorna "Hola, como esta?".

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".

-find_in_set(cadena,lista de cadenas): devuelve un valor entre de 0 a n


(correspondiente a la posición), si la cadena envidada como primer argumento
está presente en la lista de cadenas enviadas como segundo argumento. La lista
de cadenas enviada como segundo argumento es una cadena formada por
subcadenas separadas por comas. Devuelve 0 si no encuentra "cadena" en la
"lista de cadenas". Ejemplo:

select find_in_set('hola','como esta,hola,buen dia');

retorna 2, porque la cadena "hola" se encuentra en la lista de cadenas, en la


posición 2.

-length(cadena): retorna la longitud de la cadena enviada como argumento.


Ejemplo:

select length('Hola');

devuelve 4.

- locate(subcadena,cadena): retorna la posición de la primera ocurrencia de la


subcadena en la cadena enviadas como argumentos. Devuelve "0" si la
subcadena no se encuentra en la cadena. Ejemplo:

select locale('o','como le va');

retorna 2.

- position(subcadena in cadena): funciona como "locate()". Devuelve "0" si la


subcadena no se encuentra en la cadena. Ejemplo:

select position('o' in 'como le va');

retorna 2.

- locate(subcadena,cadena,posicioninicial): retorna la posición de la primera


ocurrencia de la subcadena enviada como primer argumentos en la cadena
enviada como segundo argumento, empezando en la posición enviada como
tercer argumento. Devuelve "0" si la subcadena no se encuentra en la cadena.

99
Ejemplos:

select locate('ar','Margarita',1);

retorna 1.

select locate('ar','Margarita',3);

retorna 5.

- instr(cadena,subcadena): retorna la posición de la primera ocurrencia de la


subcadena enviada como segundo argumento en la cadena enviada como primer
argumento. Ejemplo:

select instr('como le va','om');

devuelve 2.

- lpad(cadena,longitud,cadenarelleno): retorna la cadena enviada como primer


argumento, rellenada por la izquierda con la cadena enviada como tercer
argumento hasta que la cadena retornada tenga la longitud especificada como
segundo argumento. Si la cadena es más larga, la corta. Ejemplo:

select lpad('hola',10,'0');

retorna "000000hola".

- rpad(cadena,longitud,cadenarelleno): igual que "lpad" excepto que rellena por la


derecha.

- left(cadena,longitud): retorna la cantidad (longitud) de caracteres de la cadena


comenzando desde la inquierda, primer caracter. Ejemplo:

select left('buenos dias',8);

retorna "buenos d".

- right(cadena,longitud): retorna la cantidad (longitud) de caracteres de la cadena


comenzando desde la derecha, último caracter. Ejemplo:

select right('buenos dias',8);

retorna "nos dias".

- substring(cadena,posicion,longitud): retorna una subcadena de tantos caracteres


de longitud como especifica en tercer argumento, de la cadena enviada como

100
primer argumento, empezando desde la posición especificada en el segundo
argumento. Ejemplo:

select substring('Buenas tardes',3,5);

retorna "enas".

- substring(cadena from posicion for longitud): variante de


"substring(cadena,posicion,longitud)". Ejemplo:

select substring('Buenas tardes' from 3 for 5);

- mid(cadena,posicion,longitud): igual que "substring(cadena,posicion,longitud)".

Ejemplo:

select mid('Buenas tardes' from 3 for 5);

retorna "enas".

- substring(cadena,posicion): retorna la subcadena de la cadena enviada como


argumento, empezando desde la posición indicada por el segundo argumento.
Ejemplo:

select substring('Margarita',4);

retorna "garita".

-substring(cadena from posicion): variante de "substring(cadena,posicion)".


Ejemplo:

select substring('Margarita' from 4);

retorna "garita".

-substring_index(cadena,delimitador,ocurrencia): retorna la subcadena de la


cadena enviada como argumento antes o después de la "ocurrencia" de la cadena
enviada como delimitador. Si "ocurrencia" es positiva, retorna la subcadena
anterior al delimitador (comienza desde la izquierda); si "ocurrencia" es negativa,
retorna la subcadena posterior al delimitador (comienza desde la derecha).
Ejemplo:

select substring_index( 'margarita','ar',2);

retorna "marg", todo lo anterior a la segunda ocurrencia de "ar".

select substring_index( 'margarita','ar',-2);

101
retorna "garita", todo lo posterior a la segunda ocurrencia de "ar".

-ltrim(cadena): retorna la cadena con los espacios de la izquierda eliminados.


Ejemplo:

select ltrim(' Hola ');

retorna

"Hola "
.

- rtrim(cadena): retorna la cadena con los espacios de la derecha eliminados.


Ejemplo:

select rtrim(' Hola ');

retorna

" Hola"
.

-trim([[both|leading|trailing] [subcadena] from] cadena): retorna una cadena igual a


la enviada pero eliminando la subcadena prefijo y/o sufijo. Si no se indica ningún
especificador (both, leading o trailing) se asume "both" (ambos). Si no se
especifica prefijos o sufijos elimina los espacios. Ejemplos:

select trim(' Hola ');

retorna 'Hola'.

select trim (leading '0' from '00hola00');

retorna "hola00".

select trim (trailing '0' from '00hola00');

retorna "00hola".

select trim (both '0' from '00hola00');

retorna "hola".

select trim ('0' from '00hola00');

retorna "hola".

102
select trim (' hola ');

retorna "hola".

-replace(cadena,cadenareemplazo,cadenareemplazar): retorna la cadena con


todas las ocurrencias de la subcadena reemplazo por la subcadena a reemplazar.
Ejemplo:

select replace('xxx.mysql.com','x','w');

retorna "www.mysql.com'.

-repeat(cadena,cantidad): devuelve una cadena consistente en la cadena repetida


la cantidad de veces especificada. Si "cantidad" es menor o igual a cero, retorna
una cadena vacía. Ejemplo:

select repeat('hola',3);

retorna "holaholahola".

-reverse(cadena): devuelve la cadena invirtiendo el order de los caracteres.


Ejemplo:

select reverse('Hola');

retorna "aloH".

-insert(cadena,posicion,longitud,nuevacadena): retorna la cadena con la nueva


cadena colocándola en la posición indicada por "posicion" y elimina la cantidad de
caracteres indicados por "longitud". Ejemplo:

select insert('buenas tardes',2,6,'xx');

retorna ""bxxtardes".

-lcase(cadena) y lower(cadena): retornan la cadena con todos los caracteres en


minúsculas. Ejemplo:

select lower('HOLA ESTUDIAnte');

retorna "hola estudiante".

select lcase('HOLA ESTUDIAnte');

retorna "hola estudiante".

103
-ucase(cadena) y upper(cadena): retornan la cadena con todos los caracteres en
mayúsculas. Ejemplo:

select upper('HOLA ESTUDIAnte');

retorna "HOLA ESTUDIANTE".

select ucase('HOLA ESTUDIAnte');

retorna "HOLA ESTUDIANTE".

-strcmp(cadena1,cadena2): retorna 0 si las cadenas son iguales, -1 si la primera


es menor que la segunda y 1 si la primera es mayor que la segunda. Ejemplo:

select strcmp('Hola','Chau');

retorna 1.

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:

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)
);

Ingresamos algunos registros:

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);

Usamos la función "concat_ws()":

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.

Usamos la función "left()":

select left(titulo,15)
from libros;

la salida muestra los títulos con los primeros 15 caracteres.

Empleamos la función "insert()":

select titulo,insert(editorial,1,0,'edit. ')


from libros;

retorna el nombre de las editoriales agregando al inicio la cadena "Edit. ".

Usamos las funciones "lower()" y "upper()":

select lower(titulo), upper(editorial)


from libros;

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);
select concat_ws('-',titulo,autor)
from libros;
select left(titulo,15)
from libros;
select titulo,insert(editorial,1,0,'edit. ')
from libros;
select lower(titulo), upper(editorial)
from libros;

105
26 - Funciones matemáticas.

Los operadores aritméticos son "+","-","*" y "/". Todas las operaciones


matemáticas retornan "null" en caso de error. Ejemplo:

select 5/0;

MySQL tiene algunas funciones para trabajar con números. Aquí presentamos
algunas.

RECUERDE que NO debe haber espacios entre un nombre de función y los


paréntesis porque MySQL puede confundir una llamada a una función con una
referencia a una tabla o campo que tenga el mismo nombre de una función.

-abs(x): retorna el valor absoluto del argumento "x". Ejemplo:

select abs(-20);

retorna 20.

-ceiling(x): redondea hacia arriba el argumento "x". Ejemplo:

select ceiling(12.34),

retorna 13.

-floor(x): redondea hacia abajo el argumento "x". Ejemplo:

select floor(12.34);

retorna 12.

-greatest(x,y,..): retorna el argumento de máximo valor.

-least(x,y,...): con dos o más argumentos, retorna el argumento más pequeño.

-mod(n,m): significa "módulo aritmético"; retorna el resto de "n" dividido en "m".


Ejemplos:

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.

-power(x,y): retorna el valor de "x" elevado a la "y" potencia. Ejemplo:

select power(2,3);

retorna 8.

-rand(): retorna un valor de coma flotante aleatorio dentro del rango 0 a 1.0.

-round(x): retorna el argumento "x" redondeado al entero más cercano. Ejemplos:

select round(12.34);

retorna 12.

select round(12.64);

retorna 13.

-srqt(): devuelve la raiz cuadrada del valor enviado como argumento.

-truncate(x,d): retorna el número "x", truncado a "d" decimales. Si "d" es 0, el


resultado no tendrá parte fraccionaria. Ejemplos:

select truncate(123.4567,2);

retorna 123.45;

select truncate (123.4567,0);

retorna 123.

Todas retornan null en caso de error.

107
Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:

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)
);

Ingresamos algunos registros:

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);

Usamos la función "ceiling(x)":

select titulo, ceiling(precio),floor(precio)


from libros;

Usamos la función "round(x)":

select titulo, round(precio)


from libros;

Empleamos la función "truncate(x,d)":

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;

27 - Funciones para el uso de fecha y hora.


MySQL tiene algunas funciones para trabajar con fechas y horas. Estas son
algunas:

-adddate(fecha, interval expresion): retorna la fecha agregándole el intervalo


especificado. Ejemplos: adddate('2006-10-10',interval 25 day) retorna "2006-11-
04". adddate('2006-10-10',interval 5 month) retorna "2007-03-10".

-adddate(fecha, dias): retorna la fecha agregándole a fecha "dias". Ejemplo:


adddate('2006-10-10',25), retorna "2006-11-04".

-addtime(expresion1,expresion2): agrega expresion2 a expresion1 y retorna el


resultado.

-current_date: retorna la fecha de hoy con formato "YYYY-MM-DD" o


"YYYYMMDD".

-current_time: retorna la hora actual con formato "HH:MM:SS" o "HHMMSS".

-date_add(fecha,interval expresion tipo) y date_sub(fecha,interval expresion tipo):


el argumento "fecha" es un valor "date" o "datetime", "expresion" especifica el
valor de intervalo a ser añadido o substraído de la fecha indicada (puede empezar
con "-", para intervalos negativos), "tipo" indica la medida de adición o
substracción. Ejemplo: date_add('2006-08-10', interval 1 month) retorna "2006-09-
10"; date_add('2006-08-10', interval -1 day) retorna "2006-09-09"; date_sub('2006-
08-10 18:55:44', interval 2 minute) retorna "2006-08-10 18:53:44"; date_sub('2006-
08-10 18:55:44', interval '2:3' minute_second) retorna "2006-08-10 18:52:41". Los

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).

-datediff(fecha1,fecha2): retorna la cantidad de días entre fecha1 y fecha2.

-dayname(fecha): retorna el nombre del día de la semana de la fecha. Ejemplo:


dayname('2006-08-10') retorna "thursday".

-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.

-extract(tipo from fecha): extrae partes de una fecha.

Ejemplos:

extract(year from '2006-10-10'), retorna "2006".


extract(year_month from '2006-10-10 10:15:25') retorna "200610".
extract(day_minute from '2006-10-10 10:15:25') retorna "101015";

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).

-hour(hora): retorna la hora para el dato dado, en el rango de 0 a 23.

Ejemplo: hour('18:25:09') retorna "18";

-minute(hora): retorna los minutos de la hora dada, en el rango de 0 a 59.

-monthname(fecha): retorna el nombre del mes de la fecha dada.

Ejemplo: monthname('2006-08-10') retorna "August".

-month(fecha): retorna el mes de la fecha dada, en el rango de 1 a 12.

-now() y sysdate(): retornan la fecha y hora actuales.

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".

-period_diff(p1,p2): retorna el número de meses entre los períodos "p1" y "p2", en


el formato "YYMM" o "YYYYMM". Los argumentos de período no son fechas sino
un año y un mes. Ejemplo: period_diff('200608','200602') retorna 6.

-second(hora): retorna los segundos para la hora dada, en el rango de 0 a 59.

-sec_to_time(segundos): retorna el argumento "segundos" convertido a horas,


minutos y segundos. Ejemplo: sec_to_time(90) retorna "1:30".

-timediff(hora1,hora2): retorna la cantidad de horas, minutos y segundos entre


hora1 y hora2.

-time_to_sec(hora): retorna el argumento "hora" convertido en segundos.

-to_days(fecha): retorna el número de día (el número de día desde el año 0).

-weekday(fecha): retorna el índice del día de la semana para la fecha pasada


como argumento. Los índices son: 0=lunes, 1=martes,... 6=domingo). Ejemplo:
weekday('2006-08-10') retorna 3, o sea jueves.

-year(fecha): retorna el año de la fecha dada, en el rango de 1000 a 9999.


Ejemplo: year('06-08-10') retorna "2006".

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:

-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.

Eliminamos la tabla "prestamos" si existe:

drop table if exists prestamos;

111
Creamos 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'
);

Los libros se prestan por 5 días.

Ingresamos un registro con los 3 primeros datos y calculamos con una función la
fecha de devolución:

insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion) values


('Manual de 1 grado','23456789','2006-08-10',date_add('2006-08-10', interval 5
day));

Con un "select" vemos cómo quedó almacenado el registro ingresado


anteriormente:
select * from prestamos;

Ingresemos otros registros de la misma manera:

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));

Ahora utilizaremos la función "current_date" para la fecha de préstamo:

insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion) values


('Atlas universal','24000111',current_date,date_add(current_date, interval 5 day));

drop table if exists prestamos;


create table prestamos(
titulo varchar(40) not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
devuelto char(1) default 'n'
);
insert into prestamos (titulo,documento,fechaPrestamo,fechaDevolucion)

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".

1- Elimine la tabla "empleados" si existe.

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)
values ('22333111','Juan Perez','m','Colon 123','1990-02-01','1970-05-10',550);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('25444444','Susana Morales','f','Avellaneda 345','1995-04-01','1975-11-
06',650);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)
values ('20111222','Hector Pereyra','m','Caseros 987','1995-04-01','1965-03-
25',510);
insert into empleados
(documento,nombre,sexo,domicilio,fechaIngreso,fechaNacimiento,sueldoBasico)

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;

5- También es política de la empresa, aumentar el 1% del sueldo básico a los


empleados, cada vez que cumplen un año más de servicio. Necesitamos los
nombres, fecha de ingreso a la empresa y sueldo básico de todos los empleados
que cumplen un año más de servicio en el mes de agosto, y una columna
calculando el incremento del sueldo:
select nombre,fechaIngreso,sueldoBasico,
(sueldoBasico+sueldoBasico*0.01) as 'Sueldo Incrementado'
from empleados
where month(fechaIngreso)=8;

6- Actualizamos el sueldo aumentando el 1% a los empleados que cumplen un


año de servicio en el mes de agosto:
select nombre,fechaIngreso,sueldoBasico,
(sueldoBasico+sueldoBasico*0.01) as 'Sueldo Incrementado'
from empleados
where month(fechaIngreso)=8;

7- Verifique si la actualización se realizó:


select nombre, sueldobasico
from empleados

114
where month(fechaIngreso)=8;

8- Si el empleado cumple 10,20,30,40... años de servicio, se le regala una placa


recordatoria. La secretaria de Gerencia necesita saber la cantidad de años de
servicio que cumplen los empleados que ingresaron en el mes de agosto para
encargar dichas placas:
select nombre,fechaIngreso,
year(current_date)-year(fechaIngreso) as 'Años de servicio'
from empleados
where month(fechaIngreso)=8;

En la sentencia anterior, extraemos el año de las fechas actual y de ingreso con la


función "year ()" y las restamos, para calcular los años de servicio.

Otros problemas:

A) Un instituto de enseñanza almacena los datos de sus estudiantes en una tabla


llamada "alumnos".

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla con la siguiente estructura:


create table alumnos(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
fechaNacimiento date,
primary key (documento)
);

3- Ingrese los siguientes registros:


insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('22345345','Mariana Perez','Colon 234','1986-10-08');
insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('23545345','Marcos Morales','Avellaneda 348','1985-12-18');
insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('24356345','Analia Gonzalez','Caseros 444','1976-06-28');
insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('20254125','Ramiro Torres','Dinamarca 209','1978-01-28');
insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('20445778','Carmen Miranda','Uspallata 999','1980-05-30');
insert into alumnos (documento,nombre,domicilio,fechaNacimiento)
values('28111444','Natalia Figueroa','Sarmiento 856','1986-04-29');

4- El institulo quiere conocer las edades de los alumnos:


select nombre, fechaNacimiento, current_date as 'Fecha actual',

115
(year(current_date)-year(fechaNacimiento)) -
(right(current_date,5)<right(fechaNacimiento,5)) as 'Edad'
from alumnos;

En la sentencia anterior con "year()" extraemos la parte correspondiente al año de


ambas fechas (actual y de nacimiento) y con "right()" extraemos los 5 primeros
caracteres que representan la parte del mes y día de ambas fechas; la
comparación retorna 1 ó 0, lo que corresponde a la diferencia de 1 año a restar de
la edad si el dia de la fecha actual es anterior que la fecha de nacimiento.
Finalmente, se coloca un alias para usar como título de la columna para hacerlo
más comprensible.

B) La empresa que provee de luz a los usuarios de un municipio la luz. Almacena


en una tabla
algunos datos de los usuarios:
- documento, cadena siempre de 8 caracteres, no nulo,
- monto a pagar, valor con decimales positivo,
- fecha de vencimiento.
Si la boleta no se paga hasta el día del vencimiento, inclusive, se incrementa al
monto, un 1% del
monto cada día de atraso.

1- Elimine la tabla, si existe.

2- Cree la tabla.

3- Ingrese algunos registros con fechas de vencimiento anterior a la fecha actual


(vencidas) y
posteriores a la fecha actual (no vencidas).

4- Muestre el documento del usuario, la fecha de vencimiento, la fecha actual (en


que efectúa el pago), el monto, la cantidad de días de atraso (respecto de la fecha
de vencimiento), el recargo y el total a pagar con el recargo:

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.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha datetime,
primary key(numero)
);
3- Ingrese algunos registros:
insert into visitas (nombre,mail,fecha)
values ('Ana Maria Lopez','[email protected]','2006-10-10 10:10');
insert into visitas (nombre,mail,fecha)
values ('Gustavo Gonzalez','[email protected]','2006-10-10
21:30');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-10-11 15:45');
insert into visitas (nombre,mail,fecha)
values ('Fabiola Martinez','[email protected]','2006-10-12 08:15');
insert into visitas (nombre,mail,fecha)
values ('Fabiola Martinez','[email protected]','2006-09-12 20:45');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-12 16:20');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-09-15 16:25');

4- Se necesita el nombre de los usuarios y la hora de visita:


select nombre,time(fecha) from visitas;

5- Se necesita conocer el nombre de los usuarios y el nombre del mes de cada


visita:
select nombre,monthname(fecha)
from visitas;

6- Se necesita saber la cantidad de visitas por día (lunes, martes...), mostrando el


nombre del día:
select dayname(fecha),count(*)
from visitas
group by dayname(fecha);

117
28 - Cláusula order by del select.

Podemos ordenar el resultado de un "select" para que los registros se muestren


ordenados por algún campo, para ello usamos la cláusula "order by".

Por ejemplo, recuperamos los registros de la tabla "libros" ordenados por el título:

select codigo,titulo,autor,editorial,precio from libros order by titulo;

Aparecen los registros ordenados alfabéticamente por el campo especificado.

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":

select codigo,titulo,autor,editorial,precio from libros order by 5;

Por defecto, si no aclaramos en la sentencia, los ordena de manera ascendente


(de menor a mayor). Podemos ordenarlos de mayor a menor, para ello agregamos
la palabra clave "desc":

select codigo,titulo,autor,editorial,precio from libros order by editorial desc;

También podemos ordenar por varios campos, por ejemplo, por "titulo" y
"editorial":

select codigo,titulo,autor,editorial,precio from libros order by titulo, 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:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:


drop table if exists libros;

Creamos la tabla estableciendo como clave primaria y "auto_increment" el campo


"codigo":

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;

Ingresamos algunos registros:

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);

Recuperamos los registros de la tabla "libros" ordenados por el título:

select codigo,titulo,autor,editorial,precio
from libros
order by titulo;

Aparecen los registros ordenados alfabéticamente por el campo especificado.

Ordenamos por "precio", colocando el número de orden del campo (5):

select codigo,titulo,autor,editorial,precio
from libros
order by 5;

Ordenamos los libros por 2 campos, "titulo" y "editorial":

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;

drop table if exists libros;


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)
);
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 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;
select codigo,titulo,autor,editorial,precio
from libros
order by titulo asc, editorial desc;

Problema:

Trabaje con la tabla llamada "medicamentos" que almacena la información de los


productos que vende
una farmacia.

1- Elimine la tabla, si existe.

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)
);

3- Visualice la estructura de la tabla "medicamentos".

4- Ingrese los siguientes registros (insert into):


insert into medicamentos (nombre, laboratorio,precio,cantidad)
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- Ordene los registros por precio, de mayor a menor.

6- Ordene los medicamentos por número del campo "cantidad".

7- Ordene los registros por "laboratorio" (descendente) y cantidad (ascendente).

Otros problemas:

A) Trabaje con la tabla "peliculas" que guarda información de películas de video en


alquiler.

1- Elimine la tabla, si existe.

2- Créela con la siguiente estructura:


-codigo (entero, sin signo, autoincrementable),
-titulo (cadena de 40),
-actor (cadena de 20),
-duracion (integer sin signo, máximo valor 200 aprox.),
-clave primaria (codigo).

121
3- Visualice la estructura de la tabla "peliculas".

4- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel R.',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel R.',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);
insert into peliculas (titulo,actor,duracion)
values('Tootsie','D. Hoffman',90);
insert into peliculas (titulo,actor,duracion)
values('Un oso rojo','Julio Chavez',100);

5- Ordene los registros por el campo "actor".

6- Muestre las películas ordenadas por la duración, de mayor a menor.

B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha date,
primary key(numero)
);

3- Ingrese algunos registros:


insert into visitas (nombre,mail,fecha)
values ('Ana Maria Lopez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Gustavo Gonzalez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-10-11');
insert into visitas (nombre,mail,fecha)

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');

4- Ordene los rergistros por fecha, en orden descendente:


select * from visitas
order by fecha desc;

5- Ordene por nombre en forma ascendente y fecha en orden descendente:


select * from visitas
order by nombre asc,fecha asc;

29 - Operadores Lógicos (and - or - not)


Hasta el momento, hemos aprendido a establer una condición con "where"
utilizando operadores relacionales. Podemos establecer más de una condición con
la cláusula "where", para ello aprenderemos los operadores lógicos.

Son los siguientes:

- and, significa "y",


- or, significa "y/o",
- xor, significa "o",
- not, significa "no", invierte el resultado
- (), paréntesis

Los operadores lógicos se usan para combinar condiciones.

Queremos recuperar todos los registros cuyo autor sea igual a "Borges" y cuyo
precio no supere los 20 pesos, para ello necesitamos 2 condiciones:

select * from libros


where (autor='Borges') and
(precio<=20);

Los registros recuperados en una sentencia que une 2 condiciones con el


operador "and", cumplen con las 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';

En la sentencia anterior usamos el operador "or", indicamos que recupere los


libros en los cuales el valor del campo "autor" sea "Borges" y/o el valor del campo
"editorial" sea "Planeta", es decir, seleccionará los registros que cumplan con la
primera condición, con la segunda condición o con ambas condiciones.

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":

select * from libros


where (autor='Borges') xor
(editorial='Planeta');

En la sentencia anterior usamos el operador "xor", indicamos que recupere los


libros en los cuales el valor del campo "autor" sea "Borges" o el valor del campo
"editorial" sea "Planeta", es decir, seleccionará los registros que cumplan con la
primera condición o con la segunda condición pero no los que cumplan con ambas
condiciones. Los registros recuperados con una sentencia que une 2 condiciones
con el operador "xor", cumplen 1 de las condiciones, no ambas.

Queremos recuperar los libros que no cumplan la condición dada, por ejemplo,
aquellos cuya editorial NO sea "Planeta":

select * from libros


where not (editorial='Planeta');

El operador "not" invierte el resultado de la condición a la cual antecede.

Los registros recuperados en una sentencia en la cual aparece el operador "not",


no cumplen con la condición a la cual afecta el "NO".

Los paréntesis se usan para encerrar condiciones, para que se evalúen como una
sola expresión.

Cuando explicitamos varias condiciones con diferentes operadores lógicos


(combinamos "and", "or") permite establecer el orden de prioridad de la
evaluación; además permite diferenciar las expresiones más claramente.

Por ejemplo, las siguientes expresiones devuelven un resultado diferente:

select * from libros


where (autor='Borges') or

124
(editorial='Paidos' and precio<20);

select*from libros
where (autor='Borges' or editorial='Paidos') and
(precio<20);

Si bien los paréntesis no son obligatorios en todos los casos, se recomienda


utilizarlos para evitar confusiones.

El orden de prioridad de los operadores lógicos es el siguiente: "not" se aplica


antes que "and" y "and" antes que "or", si no se especifica un orden de evaluación
mediante el uso de paréntesis.

El orden en el que se evalúan los operadores con igual nivel de precedencia es


indefinido, por ello se recomienda usar los paréntesis.

Ejemplo :

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe.

Creamos la tabla con la siguiente estructura:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(15),
precio decimal(5,2),
primary key(codigo)
);

Ingresamos algunos registros:

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);

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:

select * from libros


where autor='Borges' and
precio<=20;

Muestra un registro, porque sólo uno cumple con ambas condiciones.

Seleccionamos los libros cuyo autor sea "Paenza" y/o cuya editorial sea "Planeta":

select * from libros


where autor='Paenza' or
editorial='Planeta';

Muestra 3 registros, 1 de ellos cumple con la primera condición, 1 con la segunda


y 1 con ambas.

Queremos ver los libros cuyo autor sea "Borges" o cuya editorial sea "Planeta":

select * from libros


where (autor='Borges') xor
(editorial='Planeta');

Muestra 2 registros, 1 cumple con la primera condición y 1 con la segunda. Los


registros que cumplen con ambas condiciones no fueron seleccionados porque
usamos el operador "xor".

Establecemos la condición que la editorial sea igual a "Planeta", y recuperamos


con un "select" los libros que no cumplan la condición:

select * from libros


where not (editorial='Planeta');

Muestra 4 registros que NO cumplen con la condición.

Los paréntesis sirven para establecer el orden de prioridad de evaluación de las


condiciones.

Analicemos los siguientes ejemplos, estas sentencias devuelven resultados


distintos:

select * from libros

126
where (autor='Borges') or
(editorial='Paidos' and precio<20);

select * from libros


where (autor='Borges' or editorial='Paidos')
and (precio<20);

En el primer caso selecciona primero los libros de "Paidos" con precio<20 y


también los de "Borges", sin considerar el precio.

En el segundo caso selecciona los libros de "Borges" y/o "Paidos", si tienen


precio<20.

El libro con código 5, no aparece en la segunda consulta porque el precio no es


<20; si en la primera porque la condición referida al precio afecta a los libros de
"Paidos".

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(15),
precio decimal(5,2),
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 autor='Borges' and
precio<=20;
select * from libros
where autor='Paenza' or
editorial='Planeta';

select * from libros


where (autor='Borges') xor
(editorial='Planeta');
select * from libros
where not (editorial='Planeta');
select * from libros
where (autor='Borges') or

127
(editorial='Paidos' and precio<20);
select * from libros
where (autor='Borges' or editorial='Paidos')
and (precio<20);

Problema:

Trabaje con la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe.

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) unsigned,
cantidad int unsigned,
primary key(codigo)
);

3- Visualice la estructura de la tabla "medicamentos".

4- Ingrese los siguientes registros (insert into):


insert into medicamentos (nombre, laboratorio,precio,cantidad)
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 códigos y nombres de los medicamentos cuyo laboratorio sea


'Roche' y cuyo precio sea menor a 5:
select codigo,nombre
from medicamentos
where laboratorio='Roche' and
precio<5;
Quedó seleccionado 1 registro, es el único que cumple con ambas condiciones.

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".

8- Muestre todos los medicamentos cuyo laboratorio NO sea "Bayer" y cuya


cantidad sea=100:
select * from medicamentos
where not laboratorio='Bayer' and
cantidad=100;

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:

A) Trabajamos con la tabla "peliculas" de un video club que alquila películas en


video.

1- Elimine la tabla, si existe.

2- Créela con la siguiente estructura:


-codigo (entero sin signo, autoincrementable),
-titulo (cadena de 30),
-actor (cadena de 20),
-duracion (entero sin signo no mayor a 200),
-clave primaria (codigo).

3- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel R.',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel R.',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);
insert into peliculas (titulo,actor,duracion)
values('Tootsie','D. Hoffman',90);
insert into peliculas (titulo,actor,duracion)
values('Un oso rojo','Julio Chavez',100);
insert into peliculas (titulo,actor,duracion)
values('Elsa y Fred','China Zorrilla',110);

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.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha datetime,
primary key(numero)
);

3- Ingrese algunos registros:


insert into visitas (nombre,mail,pais,fecha)
values ('Ana Maria Lopez','[email protected]','Argentina','2006-10-10
10:10');
insert into visitas (nombre,mail,pais,fecha)
values ('Gustavo Gonzalez','[email protected]','Chile','2006-10-
10 21:30');
insert into visitas (nombre,mail,pais,fecha)
values ('Juancito','[email protected]','Argentina','2006-10-11 15:45');
insert into visitas (nombre,mail,pais,fecha)
values ('Fabiola Martinez','[email protected]','Mexico','2006-10-12
08:15');
insert into visitas (nombre,mail,pais,fecha)
values ('Fabiola Martinez','[email protected]','Mexico','2006-09-12
20:45');
insert into visitas (nombre,mail,pais,fecha)
values ('Juancito','[email protected]','Argentina','2006-09-12 16:20');
insert into visitas (nombre,mail,pais,fecha)
values ('Juancito','[email protected]','Argentina','2006-09-15 16:25');

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;

30 - Otros operadores relacionales (between - in)


Hemos visto los operadores relacionales:

= (igual), <> (distinto), > (mayor), < (menor), >= (mayor o igual), <= (menor o
igual), is null/is not null (si un valor es NULL o no).

Existen otros que simplifican algunas consultas:

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":

select * from libros


where precio>=20 and precio<=40;

Podemos usar "between":

select * from libros


where precio between 20 and 40;

"between" significa "entre". Averiguamos si el valor de un campo dado (precio)


está entre los valores mínimo y máximo especificados (20 y 40 respectivamente).

Si agregamos el operador "not" antes de "between" el resultado se invierte.

Para recuperar los libros cuyo autor sea 'Paenza' o 'Borges' usamos 2
condiciones:

select * from libros


where autor='Borges' or autor='Paenza';

132
Podemos usar "in":

select * from libros


where autor in('Borges','Paenza');

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:

select * from libros where autor<>'Borges' and autor<>'Paenza';

También podemos usar "in" :

select * from libros


where autor not in ('Borges','Paenza');

Con "in" averiguamos si el valor del campo está incluido en la lista, con "not"
antecediendo la condición, invertimos el resultado.

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe.

Creamos la tabla con la siguiente estructura:

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)
);

Ingresamos algunos registros:

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)

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:

select * from libros


where precio>=20 and
precio<=40;

Ahora usamos "between" y confirmamos que la salida es la misma:

select * from libros


where precio between 20 and 40;

Recuperamos los libros cuyo autor es 'Paenza' o 'Borges' usando 2 condiciones:

select * from libros


where autor='Borges' or
autor='Paenza';

Usamos "in" y obtenemos el mismo resultado:

select * from libros


where autor in('Borges','Paenza');

Seleccionamos los libros cuyo autor no es 'Paenza' ni 'Borges' usamos:

select * from libros


where autor<>'Borges' and
autor<>'Paenza';

Realizamos la misma consulta, pero esta vez con "in" :

select * from libros


where autor not in ('Borges','Paenza');

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(15),
precio decimal(5,2) unsigned,

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:

Trabaje con la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe.

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) unsigned,
cantidad int unsigned,
primary key(codigo)
);

3- Visualice la estructura de la tabla "medicamentos".

4- Ingrese los siguientes registros:


insert into medicamentos (nombre,laboratorio,precio,cantidad)

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;

6- Seleccione los registros cuyo laboratorio sea "Bayer" o "Bago":


select * from medicamentos
where laboratorio in ('Bayer','Bago');

7- Elimine los registros cuya cantidad esté entre 100 y 200:


delete from medicamentos
where cantidad between 100 and 200;

Otros problemas:

Una concesionaria de autos vende autos usados y almacena la información en


una tabla
llamada "autos".

1- Elimine la tabla "autos" si existe.

2- Cree la tabla con la siguiente estructura:


create table autos(
patente char(6),
marca varchar(20),
modelo char(4),
precio decimal(8,2) unsigned,
primary key(patente)
);
3- Ingrese los siguientes registros:
insert into autos(patente,marca,modelo,precio)
values('ACD123','Fiat 128','1970',15000);
insert into autos(patente,marca,modelo,precio)
values('ACG234','Renault 11','1990',40000);
insert into autos(patente,marca,modelo,precio)

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;

31 - Búsqueda de patrones (like y not like)


Hemos realizado consultas utilizando operadores relacionales para comparar
cadenas. Por ejemplo, sabemos recuperar los libros cuyo autor sea igual a la
cadena "Borges":

select * from libros


where autor='Borges';

Los operadores relacionales nos permiten comparar valores numéricos y cadenas


de caracteres. Pero al realizar la comparación de cadenas, busca coincidencias de
cadenas completas.

Imaginemos que tenemos registrados estos 2 libros:

El Aleph de Borges; Antologia poetica de J.L. Borges;

Si queremos recuperar todos los libros cuyo autor sea "Borges", y especificamos
la siguiente condición:

select * from libros


where autor='Borges';

sólo aparecerá el primer registro, ya que la cadena "Borges" no es igual a la


cadena "J.L. Borges".

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".

Entonces, podemos comparar trozos de cadenas de caracteres para realizar


consultas. Para recuperar todos los registros cuyo autor contenga la cadena
"Borges" debemos tipear:

select * from libros


where autor like "%Borges%";

El símbolo "%" (porcentaje) reemplaza cualquier cantidad de caracteres


(incluyendo ningún caracter). Es un caracter comodín. "like" y "not like" son
operadores de comparación que señalan igualdad o diferencia.

Para seleccionar todos los libros que comiencen con "A":

select * from libros


where titulo like 'A%';

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.

Para seleccionar todos los libros que no comiencen con "A":

select * from libros


where titulo not like 'A%';

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:

select * from libros


where autor like "%Carrol_";

Si necesitamos buscar un patrón en el que aparezcan los caracteres comodines,


por ejemplo, queremos ver todos los registros que comiencen con un guión bajo, si
utilizamos '_%', mostrará todos los registros porque lo interpreta como "patrón que
comienza con un caracter cualquiera y sigue con cualquier cantidad de
caracteres". Debemos utilizar "\_%", esto se interpreta como 'patrón que comienza
con guión bajo y continúa con cualquier cantidad de caracteres". Es decir, si
queremos incluir en una búsqueda de patrones los caracteres comodines,
debemos anteponer al caracter comodín, la barra invertida "\", así lo tomará como
caracter de búsqueda literal y no como comodín para la búsqueda. Para buscar el
caracter literal "%" se debe colocar "\%".

138
Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe.

Creamos la tabla con la siguiente estructura:

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)
);

Ingresamos algunos registros:

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('Antologia poetica','J.L. Borges','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','Bioy Casare- J.L. Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)
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);

Recuperamos los libros cuyo autor sea igual a la cadena "Borges":

select * from libros


where autor='Borges';

Nos devuelve 1 registro.

Recuperamos todos los registros cuyo autor contenga la cadena "Borges":

select * from libros

139
where autor like '%Borges%';

El resultado nos devuelve 3 registros.

Para seleccionar todos los libros que comiencen con "A":

select * from libros


where titulo like 'A%';

Para seleccionar todos los libros que no comiencen con "A":

select * from libros


where titulo not like 'A%';

Queremos los libros de "Lewis Carroll" y no recordamos si se escribe "Carroll" o


"Carrolt", entonces tipeamos:

select * from libros


where autor like '%Carrol_';

Buscamos todos los libros de "Harry Potter":

select * from libros


where titulo like '%Harry Potter%';

Todos los libros sobre "PHP":

select * from libros


where titulo like '%PHP%';

drop table if exists libros;


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)
);
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('Antologia poetica','J.L. Borges','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','Bioy Casare- J.L. Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)

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%';

select * from libros


where titulo like '%PHP%';

Problema:

Trabaje con la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe:


drop table if exists medicamentos;

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo int unsigned auto_increment,
nombre varchar(20) not null,
laboratorio varchar(20),
precio decimal(6,2) unsigned,
cantidad int unsigned,
primary key(codigo)
);

3- Visualice la estructura de la tabla "medicamentos".

4- Ingrese los siguientes registros:


insert into medicamentos (nombre, laboratorio,precio)
values('Sertal gotas','Roche',5.2);
insert into medicamentos (nombre, laboratorio,precio)
values('Buscapina','Roche',4.10);
insert into medicamentos (nombre, laboratorio,precio)
values('Amoxidal 500','Bayer',15.60);
insert into medicamentos (nombre, laboratorio,precio)

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);

5- Recupere los medicamentos cuyo nombre comiencen con "Amox":


select codigo,nombre,laboratorio,precio
from medicamentos
where nombre like 'Amox%';
Quedaron 3 registros seleccionados.

6- Recupere los medicamentos "Paracetamol" cuyo precio sea menor a 2:


select codigo,nombre,laboratorio,precio
from medicamentos
where nombre like 'Paracetamol%' and
precio<2;

7- Busque todos los medicamentos cuyo precio tenga .10 centavos:


select codigo,nombre,laboratorio,precio
from medicamentos
where precio like '%.1%';

8- Muestre todos los medicamentos que no contengan la cadena "compuesto":


select codigo,nombre,laboratorio,precio
from medicamentos
where nombre not like'%compuesto%';

9- Elimine todos los registros cuyo laboratorio contenga la letra "y":


delete from medicamentos
where laboratorio like '%y%';

10- Cambie el precio por 5, al "Paracetamol" cuyo precio es mayor a 2:


update medicamentos set precio=5
where nombre like 'Paracetamol%' and
precio>2;

142
Otros problemas:

A) Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Créela con la siguiente estructura:


-codigo (entero sin signo, autoincrementable),
-titulo (cadena de 30), not null,
-actor (cadena de 20),
-duracion (entero sin signo no mayor a 200 aprox.),
-clave primaria (codigo).

3- Visualice la estructura de la tabla "peliculas".

4- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel R.',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel R.',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);
insert into peliculas (titulo,actor,duracion)
values('Tootsie','D. Hoffman',90);
insert into peliculas (titulo,actor,duracion)
values('Un oso rojo',null,100);
insert into peliculas (titulo,actor,duracion)
values('Elsa y Fred','China Zorrilla',110);
insert into peliculas (titulo,actor,duracion)
values('Mrs. Johns','Richard Gere',180);

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;

9- Cambie el valor de la duración a 100 en las películas en las cuales el campo


"actor" comience con "D":
update peliculas set duracion=100
where actor like 'D%';

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%';

11- Vea si existen películas con títulos nulos:


select * from peliculas
where titulo like null;

12- Vea si existen películas con valor nulo en el campo "actor":


select * from peliculas
where actor like null;

B) Trabaje con la tabla "usuarios" que almacena el nombre y clave de cada


usuario.

1- Elimine la tabla, si existe.


- Créela con la siguiente estructura:
-nombre (cadena de 20),
-clave (cadena de 10),
-clave primaria (clave).

3- Visualice la estructura de la tabla "usuarios".

4- Ingrese los siguientes registros:


insert into usuarios (nombre, clave) values ('Leonardo','payaso');
insert into usuarios (nombre, clave) values ('MarioPerez','Marito');
insert into usuarios (nombre, clave) values ('Marcelo','River');
insert into usuarios (nombre, clave) values ('Gustavo','Boca');
insert into usuarios (nombre, clave) values ('MarcosMercado','RealMadrid');
insert into usuarios (nombre, clave) values ('Susana','chapita');
insert into usuarios (nombre, clave) values ('Gonzalo','Z80');
insert into usuarios (nombre, clave) values ('GustavoPereyra','RealMadrid');

144
5- Busque los registros cuya clave contenga sólo 5 letras:
select * from usuarios
where clave like '_____';

6- Busque los registros cuyo nombre de usuario termine con "o":


select * from usuarios
where nombre like '%o';

32 - Búsqueda de patrones (regexp)


Los operadores "regexp" y "not regexp" busca patrones de modo similar a "like" y
"not like".

Para buscar libros que contengan la cadena "Ma" usamos:

select titulo from libros


where titulo regexp 'Ma';

Para buscar los autores que tienen al menos una "h" o una "k" o una "w" tipeamos:

select autor from libros


where autor regexp '[hkw]';

Para buscar los autores que no tienen ni "h" o una "k" o una "w" tipeamos:

select autor from libros


where autor not regexp '[hkw]';

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:

select autor from libros


where autor regexp '[a-d]';

Para ver los títulos que comienzan con "A" tipeamos:

select titulo from libros


where titulo regexp '^A';

Para ver los títulos que terminan en "HP" usamos:

select titulo from libros


where titulo regexp 'HP$';

145
Para buscar títulos que contengan una "a" luego un caracter cualquiera y luego
una "e" utilizamos la siguiente sentencia:

select titulo from libros


where titulo regexp 'a.e';

El punto (.) identifica cualquier caracter.

Podemos mostrar los títulos que contienen una "a" seguida de 2 caracteres y
luego una "e":

select titulo from libros


where titulo regexp 'a..e';

Para buscar autores que tengan 6 caracteres exactamente usamos:

select autor from libros


where autor regexp '^......$';

Para buscar autores que tengan al menos 6 caracteres usamos:

select autor from libros


where autor regexp '......';

Para buscar títulos que contengan 2 letras "a" usamos:

select titulo from libros


where titulo regexp 'a.*a';

El asterisco indica que busque el caracter inmediatamente anterior, en este caso


cualquiera porque hay un punto.

Ejemplo:

Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe.

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:

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('Antologia poetica','J.L. Borges','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','Bioy Casare- J.L. Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)
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);

Para buscar libros cuyos títulos contengan la cadena "Ma" usamos:

select titulo from libros


where titulo regexp 'Ma';

Retorna 4 registros.

Para buscar los registros cuyos autores tienen al menos una "h" o una "k" o una
"w" tipeamos:

select titulo,autor from libros


where autor regexp '[hkw]';

4 registros devueltos.

Para buscar los libros cuyos autores no tienen ni "h" o una "k" o una "w" tipeamos:

select titulo,autor from libros


where autor not regexp '[hkw]';

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.

Para ver los títulos que comienzan con "A" tipeamos:

select titulo from libros


where titulo regexp '^A';

Devuelve 3 registros.

Para ver los títulos que terminan en "HP" usamos:

select titulo from libros


where titulo regexp 'HP$';

Retorna 2 registros.

Para buscar títulos que contengan una "a" luego un caracter cualquiera y luego
una "e" utilizamos la siguiente sentencia:

select titulo from libros


where titulo regexp 'a.e';

Retorna 2 registros.

Podemos mostrar los títulos que contienen una "a" seguida de 2 caracteres y
luego una "e":

select titulo from libros


where titulo regexp 'a..e';

Selecciona 3 registros.

Para buscar autores que tengan 6 caracteres exactamente usamos:

select autor from libros


where autor regexp '^......$';

Devuelve 1 registro.

Para buscar autores que tengan al menos 6 caracteres usamos:

select autor from libros


where autor regexp '......';

148
Selecciona 9 registros.

Para buscar títulos que contengan 2 letras "a" usamos:

select titulo from libros


where titulo regexp 'a.*a';

Selecciona 6 registros.

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,
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('Antologia poetica','J.L. Borges','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','Bioy Casare- J.L. Borges','Paidos',35.40);
insert into libros (titulo,autor,editorial,precio)
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 titulo from libros
where titulo regexp 'Ma';
select titulo,autor from libros
where autor regexp '[hkw]';
select titulo,autor from libros
where autor not regexp '[hkw]';
select autor from libros
where autor regexp '[a-d]';
select titulo from libros
where titulo regexp '^A';
select titulo from libros
where titulo regexp 'HP$';
select titulo from libros
where titulo regexp 'a.e';
select titulo from libros
where titulo regexp 'a..e';
select autor from libros
where autor regexp '^......$';

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.

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table agenda(
apellido varchar(30),
nombre varchar(20) not null,
domicilio varchar(30),
telefono varchar(11),
mail varchar(30)
);

3- Ingrese los siguientes registros:


insert into agenda values('Perez','Juan','Sarmiento
345','4334455','[email protected]');
insert into agenda values('Garcia','Ana','Urquiza
367','4226677','[email protected]');
insert into agenda values('Lopez','Juan','Avellaneda
900',null,'[email protected]');
insert into agenda values('Juarez','Mariana','Sucre
123','0525657687','[email protected]');
insert into agenda values('Molinari','Lucia','Peru
1254','4590987','[email protected]');
insert into agenda values('Ferreyra','Patricia','Colon 1534','4585858',null);
insert into agenda values('Perez','Susana','San Martin 333',null,null);
insert into agenda values('Perez','Luis','Urquiza
444','0354545256','[email protected]');
insert into agenda values('Lopez','Maria','Salta
314',null,'[email protected]');

4- Busque todos los mails que contengan la cadena "gmail":


select *from agenda
where mail regexp 'gmail';

5- Busque los nombres que no tienen "z" ni "g":


select * from agenda
where nombre not regexp '[zg]';

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]';

7- Seleccione los apellidos que terminen en "ez":


select * from agenda
where apellido regexp 'ez$';

8- Seleccione los apellidos, nombres y domicilios de los amigos cuyos apellidos


contengan 2 letras "i":
select apellido,nombre,domicilio from agenda
where nombre regexp 'i.*i';

9- Seleccione los teléfonos que tengan 7 caracteres exactamente:


select * from agenda
where telefono regexp '^.......$';

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:

Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con ese nombre.

1- Elimine "articulos", si existe:


drop table if exists articulos;

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo int unsigned auto_increment,
nombre varchar(25) not null,
descripcion varchar(30),
precio decimal(6,2) unsigned,
cantidad tinyint unsigned,
primary key(codigo)
);

3- Ingrese algunos registros:


insert into articulos (nombre, descripcion, precio,cantidad)
values ('impresora','Epson Stylus C45',400.80,20);
insert into articulos (nombre, descripcion, precio,cantidad)

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);

4- Seleccione todos los artículos que comienzan con "impresora":


select * from articulos
where nombre regexp '^impresora';

5-Busque los artículos en los cuales el campo "descripcion" no tienen "H" ni "W":
select * from articulos
where descripcion not regexp '[hw]';

6- Seleccione las descripciones que contengan una letra "s" seguida de un


caracter cualquiera y luego una "n":
select * from articulos
where descripcion regexp 's.n';

33 - Contar registros (count)


Existen en MySQL funciones que nos permiten contar registros, calcular sumas,
promedios, obtener valores máximos y mínimos. Veamos algunas de ellas.

Imaginemos que nuestra tabla "libros" contiene muchos registros. Para averiguar
la cantidad sin necesidad de contarlos manualmente usamos la función "count()":

select count(*) from libros;

La función "count()" cuenta la cantidad de registros de una tabla, incluyendo los


que tienen valor nulo.

Para saber la cantidad de libros de la editorial "Planeta" tipeamos:

select count(*) from libros


where editorial='Planeta';

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":

select count(*) from libros

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:

select count(precio) from libros;

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.

Tenga en cuenta que no debe haber espacio entre el nombre de la función y el


paréntesis, porque puede confundirse con una referencia a una tabla o campo.
Las siguientes sentencias son distintas:

select count(*) from libros;


select count (*) from libros;

La primera es correcta, la segunda incorrecta.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

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,
cantidad mediumint unsigned,
primary key(codigo)
);

Ingresamos algunos registros:

insert into libros (titulo,autor,editorial,precio,cantidad)


values('El aleph','Borges','Planeta',15,100);

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);

Para averiguar la cantidad de registros de la tabla "libros" usamos la función


"count(*)":

select count(*) from libros;

Retorna 9.

Para saber la cantidad de libros de la editorial "Planeta" tipeamos:

select count(*) from libros


where editorial='Planeta';

Para averiguar la cantidad de libros que contienen la cadena "Borges" tipeamos:

select count(*) from libros where autor like '%Borges%';

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:

select count(precio) from libros;

Retorna 8, ya que uno de los libros tiene precio nulo y no se contabilizó.

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.

1- Elimine la tabla "visitantes", si existe.

2- Créela con la siguiente estructura:


create table visitantes(
nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra decimal (6,2) unsigned
);

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);

4- Solicite la cantidad de visitantes al stand (10 registros):


select count(*) from visitantes;

5- Solicite la cantidad de visitantes que tienen teléfono (valor no nulo) (8 registros):


select count(telefono)
from visitantes;

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".

6- Muestre la cantidad de visitantes de sexo masculino que acudieron al stand (3):


select count(*) from visitantes where sexo='m';

7- Muestre la cantidad de mujeres mayores de 25 años que acudieron al stand (4):


select count(*) from visitantes
where sexo='f' and
edad>25;

8- Muestre la cantidad de visitantes que no son de "Cordoba" (5):


select count(*) from visitantes
where ciudad<>'Cordoba';

9- Muestre la cantidad de visitantes que realizaron alguna compra (7):

156
select count(*) from visitantes
where montocompra<>0;

10- Muestre la cantidad de visitantes que no realizaron compras (3):


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".

1- Elimine la tabla "prestamos" si existe.

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.

3- Ingrese los siguientes registros:


insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Manual de 1 grado','23456789','2006-07-10','2006-07-12');
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('El aleph','22245679','2006-07-15',null);
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Alicia en el pais de las maravillas','24456789','2006-07-20','2006-07-22');
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Manual de biologia','25456789','2006-08-14',null);
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Manual de geografia 5 grado','27456789','2006-08-21','2006-08-25');
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Antologia poetica','28456789','2006-08-26','2006-08-27');
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Manual de 1 grado','23456789','2006-08-26','2006-08-28');
insert into prestamos (titulo,documento,fechaprestamo,fechadevuelto)
values ('Manual de 1 grado','30456789','2006-09-01','2006-09-03');

4- Cuente la cantidad de veces que se prestó el libro "Manual de 1 grado":


select count(*) from prestamos
where titulo='Manual de 1 grado';

157
5- Cuente la cantidad de libros devueltos (contando por fechadevuelto):
select count(fechadevuelto)
from prestamos;

6- Cuente la cantidad de veces que se le prestaron libros a la persona con


documento "23456789":
select count(*)
from prestamos
where documento='23456789';

7- Cuente la cantidad de libros prestados en el mes de agosto:


select count(*)
from prestamos
where month(fechaprestamo)=8;

B) Trabaje con la tabla "agenda" que registra la información referente a sus


amigos.

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table agenda(
apellido varchar(30),
nombre varchar(20) not null,
domicilio varchar(30),
telefono varchar(11),
mail varchar(30)
);

3- Ingrese los siguientes registros:


insert into agenda values('Perez','Juan','Sarmiento
345','4334455','[email protected]');
insert into agenda values('Garcia','Ana','Urquiza
367','4226677','[email protected]');
insert into agenda values('Lopez','Juan','Avellaneda
900',null,'[email protected]');
insert into agenda values('Juarez','Mariana','Sucre
123','0525657687','[email protected]');
insert into agenda values('Molinari','Lucia','Peru
1254','4590987','[email protected]');
insert into agenda values('Ferreyra','Patricia','Colon 1534','4585858',null);
insert into agenda values('Perez','Susana','San Martin 333',null,null);
insert into agenda values('Perez','Luis','Urquiza
444','0354545256','[email protected]');

158
insert into agenda values('Lopez','Maria','Salta
314',null,'[email protected]');

4- Cuente cuántos de sus amigos tienen mail:


select count(mail)
from agenda;

5-Cuente cuántos de sus amigos tienen teléfono:


select count(telefono)
from agenda;

6- Cuente cuántos se apellidan "Perez":


select count(*)
from agenda
where apellido like '%Perez%';

34 - Funciones de agrupamiento (count - max - min - sum - avg)


Existen en MySQL funciones que nos permiten contar registros, calcular sumas,
promedios, obtener valores máximos y mínimos. Ya hemos aprendido "count()",
veamos otras.

La función "sum()" retorna la suma de los valores que contiene el campo


especificado. Por ejemplo, queremos saber la cantidad de libros que tenemos
disponibles para la venta:

select sum(cantidad) from libros;

También podemos combinarla con "where". Por ejemplo, queremos saber cuántos
libros tenemos de la editorial "Planeta":

select sum(cantidad) from libros


where editorial ='Planeta';

Para averiguar el valor máximo o mínimo de un campo usamos las funciones


"max()" y "min()" respectivamente. Ejemplo, queremos saber cuál es el mayor
precio de todos los libros:

select max(precio) from libros;

Queremos saber cuál es el valor mínimo de los libros de "Rowling":

select min(precio) from libros


where autor like '%Rowling%';

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":

select avg(precio) from libros


where titulo like '%PHP%';

Estas funciones se denominan "funciones de agrupamiento" porque operan sobre


conjuntos de registros, no con datos individuales.

Tenga en cuenta que no debe haber espacio entre el nombre de la función y el


paréntesis, porque puede confundirse con una referencia a una tabla o campo.
Las siguientes sentencias son distintas:

select count(*) from libros;


select count (*) from libros;

La primera es correcta, la segunda incorrecta.

Ejemplo:
Trabajamos con la tabla "libros" que registra la información de los libros que vende
una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

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,
cantidad mediumint unsigned,
primary key(codigo)
);

Ingresamos algunos registros:

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)

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);

Para conocer la suma de las cantidades de libros que tenemos disponibles


tipeamos:

select sum(cantidad) from libros;

Retorna 1220; verifique la suma, sumando los valores de todos los registros del
campo "cantidad".

Solicitamos la suma de las cantidades de los libros de la editorial "Planeta":

select sum(cantidad) from libros


where editorial ='Planeta';

Retorna 250; verifique el total sumando las cantidades de los libros cuya editorial
sea "Planeta".

Si queremos saber cuál es el mayor precio de los libros usamos:

select max(precio) from libros;

Devuelve 46.

Verifiquemos lo anterior realizando una consulta ordenada por precio de forma


descendente:

select * from libros


order by precio desc;

Para obtener el valor mínimo de los libros de "Rowling" utilizamos la siguiente


sentencia:

select min(precio) from libros


where autor like '%Rowling%';

161
Retorna 45.

Verifiquemos el resultado realizando una consulta "select" con la condición


anterior ordenada por precio:

select * from libros


where autor like '%Rowling%'
order by 5;

Solicitamos el promedio del precio de los libros que tratan sobre "PHP":

select avg(precio) from libros


where titulo like '%PHP%';

Retorna 24.50...

Verifiquemos el resultado seleccionado los libros de "PHP" y calculando el


promedio manualmente:

select * from libros


where titulo like '%PHP%';

Recuerde que no debe haber espacio entre el nombre de la función y el


paréntesis. Pruebe las siguientes sentencias:

select count(*) from libros;


select count (*) from libros;

La segunda no se ejecuta, aparece un mensaje de error.

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);

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);

select sum(cantidad) from libros;


select sum(cantidad) from libros
where editorial ='Planeta';
select max(precio) from libros;
select * from libros
order by precio desc;
select min(precio) from libros
where autor like '%Rowling%';
select * from libros
where autor like '%Rowling%'
order by 5;
select avg(precio) from libros
where titulo like '%PHP%';
select * from libros
where titulo like '%PHP%';
select count(*) from libros;
select count (*) 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.

1- Elimine la tabla "visitantes", si existe.

2- Créela con la siguiente estructura:


create table visitantes(
nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra decimal (6,2) unsigned
);

Note que no tiene clave primaria, no la necesita.

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);

4- Solicite la cantidad de visitantes al stand (10 registros):


select count(*) from visitantes;

5- Muestre la suma de la compra de todos los visitantes de "Alta Gracia" (78.5):


select sum(montocompra) from visitantes
where ciudad='Alta Gracia';

6- Muestre el valor máximo de las compras efectuadas (53.50):


select max(montocompra) from visitantes;

7- Muestre la edad menor de los visitantes (20):


select min(edad) from visitantes;

8- Muestre el promedio de edades de los visitantes (33.66):


select avg(edad) from visitantes;

9- Muestre el promedio del monto de compra (24.55):


select avg(montocompra) from visitantes;

164
Otros problemas:

A) Una academia de informática dicta distintos cursos y almacena en una tabla


llamada "inscripciones" la siguiente información: nombre del curso, documento del
alumno, fecha en que se inscribe el alumno, monto del pago (algunos dejan una
seña, otros pagan el curso completo).

1- Elimine la tabla si existe.

2- cree la tabla:
create table inscripciones(
nombre varchar(30),
documento char(8),
fechainscripto date,
pago decimal(5,2) unsigned not null
);

3- Ingrese algunos registros:


insert into inscripciones values('PHP básico', '22333444','2006-08-10',50);
insert into inscripciones values('PHP básico', '23333444','2006-08-10',50);
insert into inscripciones values('PHP básico', '24333444','2006-08-11',30);
insert into inscripciones values('PHP experto', '25333444','2006-08-11',0);
insert into inscripciones values('PHP experto', '26333444','2006-08-12',200);
insert into inscripciones values('JavaScript básico', '22333444','2006-08-10',100);
insert into inscripciones values('Operador de PC', '27333444','2006-08-12',10);
insert into inscripciones values('Operador de PC', '28333444','2006-08-13',50);
insert into inscripciones values('Operador de PC', '29333444','2006-08-14',40);
insert into inscripciones values('Operador de PC', '30333444','2006-08-14',0);
insert into inscripciones values('Diseño web', '29333444','2006-08-14',200);
insert into inscripciones values('Diseño web', '30333444','2006-08-14',0);

4- calcule la cantidad de inscriptos para el curso de "Operador de PC":


select count(*)
from inscripciones
where nombre='Operador de PC';

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';

6- Calcule el promedio de los pagos de los inscriptos:


select avg(pago)
from inscripciones;

7- Muestre el máximo y el mínimo valor de pago, sin considerar quienes no pagan:


select max(pago),min(pago)

165
from inscripciones
where pago>0;

8- Vea en cuántos cursos se inscribió el alumno con documento "22333444" y


cuánto abonó en total:
select count(*) as 'cantidad',
sum(pago) as 'Abono'
from inscripciones
where documento='22333444';

B) Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Créela con la siguiente estructura:


-codigo (entero sin signo, autoincrementable),
-titulo (cadena de 30), not null,
-actor (cadena de 20),
-duracion (entero sin signo no mayor a 200 aprox.),
-clave primaria (codigo).

3- Ingrese los siguientes registros:


insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel R.',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel R.',190);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Mujer bonita','Richard Gere',120);
insert into peliculas (titulo,actor,duracion)
values('Tootsie','D. Hoffman',90);
insert into peliculas (titulo,actor,duracion)
values('Un oso rojo',null,100);
insert into peliculas (titulo,actor,duracion)
values('Elsa y Fred','China Zorrilla',110);
insert into peliculas (titulo,actor,duracion)
values('Mrs. Johns','Richard Gere',180);

4- Muestre el valor de duración más grande:


select max(duracion)from peliculas;

5- Muestre el promedio de duración de las películas:


select avg(duracion) from peliculas;

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';

C) Una concesionaria de autos vende autos usados y almacena la información en


una tabla llamada "autos".

1- Elimine la tabla "autos" si existe.

2- Cree la tabla con la siguiente estructura:


create table autos(
patente char(6),
marca varchar(20),
modelo char(4),
precio decimal(8,2) unsigned,
primary key(patente)
);

3- Ingrese los siguientes registros:


insert into autos
values('ACD123','Fiat 128','1970',15000);
insert into autos
values('ACG234','Renault 11','1990',40000);
insert into autos
values('BCD333','Peugeot 505','1990',80000);
insert into autos
values('GCD123','Renault Clio','1990',70000);
insert into autos
values('BCC333','Renault Megane','1998',95000);
insert into autos
values('BVF543','Fiat 128','1975',20000);

4- Muestre el valor del auto más caro y más barato:


select max(precio), min(precio)
from autos;

167
5- Muestre el valor de auto más caro de 1990:
select max(precio)
from autos
where modelo='1990';

6- Muestre el promedio de los precios de los autos "Fiat 128":


select avg(precio)
from autos
where marca='Fiat 128';

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;

D) Un comercio guarda la información de sus ventas en una tabla llamada


"facturas" en la que registra el número de factura, la descripción de los items
comprados, el precio por unidad de los items y la cantidad.

1- Elimine la tabla si existe.

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);

4- Cuente la cantidad de items de la factura número "2002":


select count(*)
from facturas
where numero='2002';

5- Sume la cantidad de productos de la factura número "2002":


select sum(cantidad)

168
from facturas
where numero='2002';

6- Muestre el total en dinero de la factura "504":


select sum(cantidad*precioporunidad)
from facturas
where numero='504';

35 - Agrupar registros (group by)


Hemos aprendido que las funciones de agrupamiento permiten contar registros,
calcular sumas y promedios, obtener valores máximos y mínimos. También dijimos
que dichas funciones operan sobre conjuntos de registros, no con datos
individuales.

Generalmente esta funciones se combinan con la sentencia "group by", que


agrupa registros para consultas detalladas.

Queremos saber la cantidad de visitantes de cada ciudad, podemos tipear la


siguiente sentencia:

select count(*) from visitantes


where ciudad='Cordoba';

y repetirla con cada valor de "ciudad":

select count(*) from visitantes


where ciudad='Alta Gracia';
select count(*) from visitantes
where ciudad='Villa Dolores';
...

Pero hay otra manera, utilizando la cláusula "group by":

select ciudad, count(*)


from visitantes
group by ciudad;

Entonces, para saber la cantidad de visitantes que tenemos en cada ciudad


utilizamos la función "count()", agregamos "group by" y el campo por el que
deseamos que se realice el agrupamiento, también colocamos el nombre del
campo a recuperar.

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):

select ciudad, count(telefono)


from visitantes
group by ciudad;

Como resultado aparecen los nombres de las ciudades y la cantidad de registros


de cada una, sin contar los que tienen teléfono nulo. Recuerde la diferencia de los
valores que retorna la función "count()" cuando enviamos como argumento un
asterisco o el nombre de un campo: en el primer caso cuenta todos los registros
incluyendo los que tienen valor nulo, en el segundo, los registros en los cuales el
campo especificado es no nulo.

Para conocer el total de las compras agrupadas por sexo:

select sexo, sum(montocompra)


from visitantes
group by sexo;

Para saber el máximo y mínimo valor de compra agrupados por sexo:

select sexo, max(montocompra) from visitantes


group by sexo;
select sexo, min(montocompra) from visitantes
group by sexo;

Se pueden simplificar las 2 sentencias anteriores en una sola sentencia, ya que


usan el mismo "group by":

select sexo, max(montocompra),


min(montocompra)
from visitantes
group by sexo;

Para calcular el promedio del valor de compra agrupados por ciudad:

select ciudad, avg(montocompra) from visitantes


group by ciudad;

170
Podemos agrupar por más de un campo, por ejemplo, vamos a hacerlo por
"ciudad" y "sexo":

select ciudad, sexo, count(*) from visitantes


group by ciudad,sexo;

También es posible limitar la consulta con "where".

Vamos a contar y agrupar por ciudad sin tener en cuenta "Cordoba":

select ciudad, count(*) from visitantes


where ciudad<>'Cordoba'
group by ciudad;

Podemos usar las palabras claves "asc" y "desc" para una salida ordenada:

select ciudad, count(*) from visitantes


group by ciudad desc;

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.

Eliminamos la tabla, si existe:

drop table if exists visitantes;

Creamos la tabla:

create table visitantes(


nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra decimal (6,2) unsigned
);

Ingresamos 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);

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);

Para saber la cantidad de visitantes que tenemos de cada ciudad tipeamos:

select ciudad, count(*)


from visitantes
group by ciudad;

El resultado muestra los nombres de las distintas ciudades y la cantidad de


registros de cada una.

Necesitamos conocer la cantidad visitantes con teléfono no nulo, de cada ciudad:

select ciudad, count(telefono)


from visitantes
group by ciudad;

Queremos conocer el total de las compras agrupadas por sexo:

select sexo, sum(montocompra) from visitantes


group by sexo;

Para obtener el máximo y mínimo valor de compra agrupados por sexo:

select sexo, max(montocompra) from visitantes


group by sexo;
select sexo, min(montocompra) from visitantes
group by sexo;

Se pueden simplificar las 2 sentencias anteriores en una sola sentencia, ya que


usan el mismo "group by":

172
select sexo, max(montocompra),
min(montocompra)
from visitantes
group by sexo;

Queremos saber el promedio del valor de compra agrupados por ciudad:

select ciudad, avg(montocompra) from visitantes


group by ciudad;

Contamos los registros y agrupamos por 2 campos, "ciudad" y "sexo":

select ciudad, sexo, count(*) from visitantes


group by ciudad,sexo;

Limitamos la consulta, no incluimos los visitantes de "Cordoba", contamos y


agrupar por ciudad:

select ciudad, count(*) from visitantes


where ciudad<>'Cordoba'
group by ciudad;

Usando la palabra clave "desc" obtenemos la salida ordenada en forma


descendente:

select ciudad, count(*) from visitantes


group by ciudad desc;

drop table if exists visitantes;


create table visitantes(
nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra decimal (6,2) unsigned
);
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);

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".

1- Elimine la tabla "clientes", si existe.

2- Créela con la siguiente estructura:


create table clientes (
codigo int unsigned auto_increment,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11),
primary key(codigo)
);

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');

4- Obtenga el total de los registros (10):


select count(*) from clientes;

5- Obtenga el total de los registros que no tienen valor nulo en los teléfonos (8):
select count(telefono) from clientes;

6- Obtenga la cantidad de clientes agrupados por ciudad y provincia, ordenados


por provincia:
select ciudad,provincia, count(*) from clientes
group by ciudad, provincia
order by provincia;

Otros problemas:

A) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,

175
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha date,
primary key(numero)
);

3- Ingrese algunos registros:


insert into visitas (nombre,mail,fecha)
values ('Ana Maria Lopez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Gustavo Gonzalez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-10-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');

4- Obtenga el total de visitas.

5- Cantidad de visitas agrupadas por fecha:


select fecha,count(*) from visitas
group by fecha;

6- Cantidad de visitas agrupadas por nombre y mes:


select nombre,month(fecha),count(*)
from visitas
group by nombre,month(fecha);

B) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".

1- Elimine la tabla "empleados" si existe:


drop table if exists 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)
);

3- Ingrese algunos registros:


insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldoBasico)
values ('22333111','Juan Perez','m','Colon 123','1990-02-01','1970-05-10',550);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldoBasico)
values ('25444444','Susana Morales','f','Avellaneda 345','1995-04-01','1975-11-
06',650);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldoBasico)
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);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldoBasico)
values ('30154269','Oscar Mendez','m','Colon 1245','2004-06-23','1984-05-
14',300);

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;

5- Se necesita conocer la cantidad de empleados agrupados por año de ingreso a


la empresa:
select year(fechaingreso),count(*)
from empleados
group by year(fechaingreso);

C) Un comercio guarda la información de sus ventas en una tabla llamada


"facturas" en la que registra el número de factura, la descripción de los items
comprados, el precio por unidad de los items y la cantidad.

1- Elimine la tabla si existe.

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);

4- Cuente la cantidad de items por factura:


select numero, count(*)
from facturas
group by numero;

5- Sume la cantidad de productos de las facturas:


select numero,sum(cantidad)
from facturas
group by numero;

6- Muestre el total en dinero de las facturas:


select numero,sum(cantidad*precioporunidad)
from facturas
group by numero;

178
36 - Selección de un grupo de registros (having)

Así como la cláusula "where" permite seleccionar (o rechazar) registros


individuales; la cláusula "having" permite seleccionar (o rechazar) un grupo de
registros.

Si queremos saber la cantidad de libros agrupados por editorial usamos la


siguiente instrucción ya aprendida:

select editorial, count(*) from libros


group by editorial;

Si queremos saber la cantidad de libros agrupados por editorial pero considerando


sólo algunos grupos, por ejemplo, los que devuelvan un valor mayor a 2, usamos
la siguiente instrucción:

select editorial, count(*) from libros


group by editorial
having count(*)>2;

Se utiliza "having", seguido de la condición de búsqueda, para seleccionar ciertas


filas retornadas por la cláusula "group by".
Veamos otros ejemplos. Queremos el promedio de los precios de los libros
agrupados por editorial:

select editorial, avg(precio) from libros


group by editorial;

Ahora, sólo queremos aquellos cuyo promedio supere los 25 pesos:

select editorial, avg(precio) from libros


group by editorial
having avg(precio)>25;

En algunos casos es posible confundir las cláusulas "where" y "having". Queremos


contar los registros agrupados por editorial sin tener en cuenta a la editorial
"Planeta".

Analicemos las siguientes sentencias:

select editorial, count(*) from libros


where editorial<>'Planeta'
group by editorial;
select editorial, count(*) from libros
group by editorial
having editorial<>'Planeta';

179
Ambas devuelven el mismo resultado, pero son diferentes.

La primera, selecciona todos los registros rechazando los de 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".

No debemos confundir la cláusula "where" con la cláusula "having"; la primera


establece condiciones para la selección de registros de un "select"; la segunda
establece condiciones para la selección de registros de una salida "group by".

Veamos otros ejemplos combinando "where" y "having".

Queremos la cantidad de libros, sin considerar los que tienen precio nulo,
agrupados por editorial, sin considerar la editorial "Planeta":

select editorial, count(*) from libros


where precio is not null
group by editorial
having editorial<>'Planeta';

Aquí, selecciona los registros rechazando los que no cumplan con la 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".

Generalmente se usa la cláusula "having" con funciones de agrupamiento, esto no


puede hacerlo la cláusula "where". Por ejemplo queremos el promedio de los
precios agrupados por editorial, de aquellas editoriales que tienen más de 2 libros:

select editorial, avg(precio) from libros


group by editorial
having count(*) > 2;

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:

select editorial, max(precio) from libros


group by editorial
having max(precio)>=30;

Esta misma sentencia puede usarse empleando un "alias", para hacer referencia a
la columna de la expresión:

select editorial, max(precio) as 'mayor' from libros


group by editorial
having mayor>=30;

180
Ejemplo :
Trabajamos con la tabla "libros" que registra los datos de una librería.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla:

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)
);

Agregamos algunos registros:

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);

Queremos averiguar la cantidad de libros agrupados por editorial:

select editorial, count(*) from libros


group by editorial;

Queremos conocer la cantidad de libros agrupados por editorial pero considerando


sólo los que devuelvan un valor mayor a 2, tipeamos:

181
select editorial, count(*) from libros
group by editorial
having count(*)>2;

Necesitamos el promedio de los precios de los libros agrupados por editorial:

select editorial, avg(precio)


from libros
group by editorial;

Ahora, sólo queremos aquellos cuyo promedio supere los 25 pesos:

select editorial, avg(precio)


from libros
group by editorial
having avg(precio)>25;

Queremos contar los registros agrupados por editorial sin tener en cuenta a la
editorial "Planeta". Tipeamos y analicemos las siguientes sentencias:

select editorial, count(*) from libros


where editorial<>'Planeta'
group by editorial;
select editorial, count(*) from libros
group by editorial
having editorial<>'Planeta';

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".

Probamos combinar condiciones "where" y "having". Queremos la cantidad de


libros, sin tener en cuenta los que tienen precio nulo, agrupados por editorial,
rechazando los de editorial "Planeta":

select editorial, count(*) from libros


where precio is not null
group by editorial
having editorial<>'Planeta';

Para obtener el promedio de los precios agrupados por editorial, de aquellas


editoriales que tienen más de 2 libros tipeamos:

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:

select editorial, max(precio)


from libros
group by editorial
having max(precio)>=30;

Para esta misma sentencia podemos utilizar un "alias" para hacer referencia a la
columna de la expresión:

select editorial, max(precio) as 'mayor'


from libros
group by editorial
having mayor>=30;

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 editorial, count(*) from libros
group by editorial;
select editorial, count(*) from libros

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".

1- Elimine la tabla "clientes", si existe.

2- Créela con la siguiente estructura:


create table clientes (
codigo int unsigned auto_increment,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11),
primary key(codigo)
);

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)

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');

4- Obtenga el total de los registros agrupados por provincia:


select provincia, count(*)
from clientes
group by provincia;

5- Obtenga el total de los registros agrupados por ciudad y provincia:


select ciudad, provincia, count(*)
from clientes
group by ciudad,provincia;

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.

1- Elimine la tabla "visitantes", si existe.

2- Créela con la siguiente estructura:


create table visitantes(
nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
ciudad varchar(20),
telefono varchar(11),
montocompra decimal(6,2)
);

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);

4- Obtenga el total de las compras agrupados por ciudad y sexo:


select ciudad, sexo, sum(montocompra)
from visitantes
group by ciudad, sexo;

5- Obtenga el total de las compras agrupados por ciudad y sexo, considerando


sólo las sumas
superiores a 50 pesos:

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.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
puntaje tinyint unsigned,
primary key(numero)
);
El puntaje va de 0 a 10.

3- Ingrese algunos registros:


insert into visitas (nombre,mail,pais,puntaje)
values ('Ana Maria Lopez','[email protected]','Argentina',9);
insert into visitas (nombre,mail,pais,puntaje)
values ('Gustavo Gonzalez','[email protected]','Chile',8);
insert into visitas (nombre,mail,pais,puntaje)
values ('Juancito','[email protected]','Mexico',5);
insert into visitas (nombre,mail,pais,puntaje)
values ('Fabiola Martinez','[email protected]','Chile',9);

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);

4- Muestre el promedio de los puntajes agrupados por pais, considerando sólo


aquellos países que tiene más de 1 visita:
select pais, avg(puntaje) from visitas
group by pais
having count(*)>=2;

5- Muestre el promedio de los puntajes agrupados por pais, considerando sólo


aquellos países cuyo promedio es mayor a 8:
select pais, avg(puntaje) from visitas
group by pais
having avg(puntaje)>8;

C) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".

1- Elimine la tabla "empleados" si existe:


drop table if exists 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)
);

3- Ingrese algunos registros:


insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('22333111','Juan Perez','m','Colon 123','1990-02-01','1970-05-10',550);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)
values ('25444444','Susana Morales','f','Avellaneda 345','1995-04-01','1975-11-
06',650);
insert into empleados
(documento,nombre,sexo,domicilio,fechaingreso,fechanacimiento,sueldobasico)

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;

5- Se necesita conocer la cantidad de empleados agrupados por fecha de ingreso


a la empresa sólo de las fechas posteriores a "1990-02-01":
select fechaingreso,count(*)
from empleados
group by fechaingreso
having fechaingreso>'1990-02-01';

37 - Registros duplicados (distinct)


Con la cláusula "distinct" se especifica que los registros con ciertos datos
duplicados sean obviadas en el resultado. Por ejemplo, queremos conocer todos
los autores de los cuales tenemos libros, si utilizamos esta sentencia:

select autor from libros;

189
Aparecen repetidos. Para obtener la lista de autores sin repetición usamos:

select distinct autor from libros;

También podemos tipear:

select autor from libros


group by autor;

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:

select distinct autor from libros


where autor is not null;

Para contar los distintos autores, sin considerar el valor "null" usamos:

select count(distinct autor)


from libros;

Note que si contamos los autores sin "distinct", no incluirá los valores "null" pero si
los repetidos:

select count(autor)
from libros;

Esta sentencia cuenta los registros que tienen autor.

Para obtener los nombres de las editoriales usamos:

select editoriales from libros;

Para una consulta en la cual los nombres no se repitan tipeamos:

select distinct editorial from libros;

Podemos saber la cantidad de editoriales distintas usamos:

select count(distinct editoriales) from libros;

Podemos combinarla con "where". Por ejemplo, queremos conocer los distintos
autores de la editorial "Planeta":

select distinct autor from libros


where editorial='Planeta';

190
También puede utilizarse con "group by":

select editorial, count(distinct autor)


from libros
group by editorial;

Para mostrar los títulos de los libros sin repetir títulos, usamos:

select distinct titulo from libros


order by titulo;

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:

select distinct titulo,editorial


from libros
order by titulo;

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.

Eliminamos la tabla, si existe.

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)
);

Ingresamos algunos registros:

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('Martin Fierro','Jose Hernandez','Planeta',42.20);
insert into libros (titulo,autor,editorial,precio)

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 obtener la lista de autores sin repetición usamos "distinct":

select distinct autor


from libros;

Si sólo queremos la lista de autores conocidos, es decir, no queremos incluir "null"


en la lista, utilizamos la sentencia siguiente:

select distinct autor


from libros
where autor is not null;

Para contar los distintos autores, sin considerar el valor "null" usamos:

select count(distinct autor)


from libros;

Note que si contamos los autores sin "distinct", no incluirá los valores "null" pero si
los repetidos:

select count(autor)
from libros;

Esta sentencia cuenta los registros que tienen autor.

Para obtener los nombres de las editoriales usamos:

select editorial
from libros;

Para una consulta en la cual los nombres no se repitan tipeamos:

192
select distinct editorial
from libros;

Podemos saber la cantidad de editoriales distintas usamos:

select count(distinct editorial)


from libros;

Queremos conocer los distintos autores de la editorial "Planeta":

select distinct autor from libros


where editorial='Planeta';

Para contar la cantidad de autores distintos de cada editorial podemos usar


"distinct" y "group by":

select editorial,count(distinct autor)


from libros
group by editorial;

Para mostrar los títulos y editoriales de los libros sin repetir títulos ni editoriales,
usamos:

select distinct titulo,editorial


from libros
order by titulo;

La consulta nos devuelve registros con títulos iguales pero con editorial diferente,
cada registro es distinto.

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,
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('Martin Fierro','Jose Hernandez','Planeta',42.20);
insert into libros (titulo,autor,editorial,precio)
values('Antologia poetica','Borges','Planeta',40);
insert into libros (titulo,autor,editorial,precio)

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:

Una academia de enseñanza dicta distintos cursos de informática. Los cursos se


dictan por la mañana o por la tarde, todos los días de lunes a viernes. La
academia guarda los datos de los cursos enuna tabla llamada "cursos" en la cual
almacena el código del curso, el tema, los días de la semana que se dicta, el
horario, por la mañana (AM) o por la tarde (PM), la cantidad de clases que incluye
cada curso (clases), la fecha de inicio y el costo del curso.

1- Elimine la tabla "cursos", si existe.

2- Cree la tabla "cursos" con la siguiente estructura:


create table cursos(
codigo tinyint unsigned auto_increment,
tema varchar(20) not null,
horario char(2) not null,

194
clases tinyint unsigned default 10,
fechainicio date,
costo decimal(5,2) unsigned,
primary key(codigo)
);

3- Ingrese los siguientes registros:


insert into cursos (tema,horario,clases,fechainicio,costo)
values('PHP básico','AM',10,'2006-08-07',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('PHP básico','PM',default,'2006-08-14',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('PHP básico','AM',default,'2006-08-05',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('PHP avanzado','AM',20,'2006-08-01',350);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('JavaScript básico','PM',15,'2006-09-11',150);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('Paginas web','PM',15,'2006-08-08',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('Paginas web','AM',15,'2006-08-12',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('Paginas web','AM',15,'2006-08-21',200);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('HTML avanzado','AM',20,'2006-09-18',180);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('HTML avanzado','PM',20,'2006-09-25',180);
insert into cursos (tema,horario,clases,fechainicio,costo)
values('JavaScript avanzado','PM',25,'2006-09-18',150);

4- Obtenga la lista de temas de los cursos sin repetición:


select distinct tema
from cursos;

5- Seleccione los cursos donde el tema incluya "PHP", sin repetir horario ni tema:
select distinct horario,tema from cursos
where tema like '%PHP%';

6- Cuente la cantidad de cursos DISTINTOS agrupados por horario:


select horario,count(distinct tema)
from cursos
group by horario;

195
Otros problemas:

A) Una empresa tiene registrados sus clientes en una tabla llamada "clientes".

1- Elimine la tabla "clientes", si existe.


2- Créela con la siguiente estructura:
create table clientes (
codigo int unsigned auto_increment,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11),
primary key(codigo)
);
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');

4- Muestre las distintas provincias y ciudades en las cuales la empresa tiene


clientes:
select distinct provincia,ciudad
from clientes;

5- Obtenga la cantidad de ciudades distintas, por provincia en las cuales hay


clientes:
select provincia, count(distinct ciudad)
from clientes
group by provincia;

196
B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha date,
primary key(numero)
);

3- Ingrese algunos registros:


insert into visitas (nombre,mail,fecha)
values ('Ana Maria Lopez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Gustavo Gonzalez','[email protected]','2006-10-10');
insert into visitas (nombre,mail,fecha)
values ('Juancito','[email protected]','2006-10-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');

4- Obtenga los distintos nombres de quienes visitaron la página:


select distinct nombre
from visitas;

5- Muestre la cantidad de veces que cada persona ingresó a la página:


select nombre, count(fecha)
from visitas
group by nombre;

6- Muestre la cantidad de veces que cada persona ingresó a la página en distintas


fechas:
select nombre, count(distinct fecha)
from visitas
group by nombre;

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.

C) Una concesionaria de autos vende autos usados y almacena la información en


una tabla llamada "autos".

1- Elimine la tabla "autos" si existe.

2- Cree la tabla con la siguiente estructura:


create table autos(
patente char(6),
marca varchar(20),
modelo year,
precio decimal(8,2) unsigned,
primary key(patente)
);

3- Ingrese los siguientes registros:


insert into autos values('ACD123','Fiat 128','1970',15000);
insert into autos values('ACG234','Renault 11','1990',40000);
insert into autos values('BCD333','Peugeot 505','1990',80000);
insert into autos values('GCD123','Renault 11','1990',70000);
insert into autos values('BCC333','Renault Megane','1998',95000);
insert into autos values('BVF543','Fiat 128','1975',20000);
insert into autos values('FCD123','Renault 11','1995',70000);
insert into autos values('HCC333','Renault Megane','1995',95000);
insert into autos values('IVF543','Fiat 128','1970',20000);

4- Muestre las distintas marcas de autos disponibles:


select distinct marca from autos;

5- Muestre la cantidad de autos por marca, de diferentes modelos:


select marca, count(distinct modelo)
from autos
group by marca;

6- Muestre los distintos modelos de autps disponibles:


select distinct modelo from autos;

D) Un consultorio médico en el cual trabajan varios médicos registra las consultas


de los pacientes en una tabla llamada "consultas".

198
1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table consultas(
fechayhora datetime not null,
medico varchar(30) not null,
documento char(8) not null,
paciente varchar(30),
obrasocial varchar(30)
);

4- Ingrese los siguientes registros:


insert into consultas values('2006-08-10 8:00','Perez','22333444','Juana
Garcia','PAMI');
insert into consultas values('2006-08-10 10:00','Lopez','22333444','Juana
Garcia','PAMI');
insert into consultas values('2006-08-10 8:30','Perez','23333444','Adela
Gomez','PAMI');
insert into consultas values('2006-08-10 9:00','Perez','24333444','Juan
Lopez','IPAM');
insert into consultas values('2006-08-10 10:00','Perez','25333444','Hector
Juarez','OSDOP');
insert into consultas values('2006-08-10 8:30','Garcia','25333444','Ana
Molina','PAMI');
insert into consultas values('2006-09-10 8:30','Garcia','25333444','Ana
Molina','PAMI');

5- Muestre las distintas obras sociales:


select distinct obrasocial from consultas;

6- Muestre los nombres de los distintos pacientes:


select distinct paciente from consultas;

7- Muestre la cantidad de distintas obras sociales:


select distinct obrasocial from consultas;

8- Cuente la cantidad de médicos (SIN REPETIR) que tienen consultas agrupado


por mes y día:
select extract(month from fechayhora),extract(day from fechayhora),
count(distinct medico) from consultas
group by extract(month from fechayhora),extract(day from fechayhora);

E) Un club dicta clases de distintos deportes. En una tabla llamada "inscriptos"


almacena la información necesaria.

1- Elimine la tabla "inscriptos" 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'
);

3- Ingrese los siguientes registros:


insert into inscriptos values('35333444','Juan Lopez','tenis','1990','S');
insert into inscriptos values('35333444','Juan Lopez','basquet','1990','S');
insert into inscriptos values('35333444','Juan Lopez','natación','1990','S');
insert into inscriptos values('36333444','Ana Juarez','tenis','1990','S');
insert into inscriptos values('36333444','Ana Juarez','natación','1990','S');
insert into inscriptos values('35333444','Juan Lopez','voley','1991','S');
insert into inscriptos values('35333444','Juan Lopez','voley','1992','S');
insert into inscriptos values('35333444','Juan Lopez','tenis','1992','S');
insert into inscriptos values('36333444','Ana Juarez','tenis','1991','S');
insert into inscriptos values('37333444','Luis Duarte','tenis','1990','S');
insert into inscriptos values('37333444','Luis Duarte','tenis','1991','S');

4- Muestre los nombres de los inscriptos sin repetir:


select distinct nombre
from inscriptos;

5- Muestre los nombres de los deportes sin repetir:


select distinct deporte
from inscriptos;

6- Muestre la cantidad de alumnos DISTINTOS inscriptos en cada deporte:


select deporte,count(distinct nombre)
from inscriptos
group by deporte;

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

Un "alias" se usa como nombre de un campo o de una expresión o para


referenciar una tabla cuando se utilizan más de una tabla (tema que veremos más
adelante).

Cuando usamos una función de agrupamiento, por ejemplo:

select count(*)
from libros
where autor like '%Borges%';

la columna en la salida tiene como encabezado "count(*)", para que el resultado


sea más claro podemos utilizar un alias:

select count(*) as librosdeborges


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';

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;

No está permitido utilizar alias de campos en las cláusulas "where".

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.

Eliminamos la tabla, si existe:

drop table if exists libros;

Creamos la tabla:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(20) not null,
autor varchar(30),
editorial varchar(15),
precio decimal(5,2),
primary key (codigo)
);

Agregamos algunos registros:

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);

Colocamos un alias "Libros de Borges" para la expresión "count(*)" para tener una
salida más clara:

select count(*) as 'Libros de Borges'


from libros
where autor like '%Borges%';

Colocamos el alias "Nombre de editorial" para el campo "editorial":

202
select editorial as 'Nombre de editorial'
from libros
group by 'Nombre de editorial';

Colocamos un alias para la cantidad calculada con "count()" y la empleamos en la


cláusula "order by":

select editorial, count(*) as cantidad


from libros
group by editorial
order by cantidad;

Colocamos un alias para el cálculo de la cantidad y lo utilizamos con "having":

select editorial, count(*) as cantidad


from libros
group by editorial
having cantidad>2;

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),
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 count(*) as 'Libros de Borges'
from libros
where autor like '%Borges%';
select editorial as 'Nombre de editorial'
from libros

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".

1- Elimine la tabla "clientes", si existe.

2- Créela con la siguiente estructura:


create table clientes (
codigo int unsigned auto_increment,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11),
primary key(codigo)
);
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');

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;

5- Muestre la cantidad de clientes que se apellidan "Perez" colocando un alias


para dicha salida:
select count(*) as 'Perez'
from clientes
where nombre like '%Perez%' ;

6- Obtenga la cantidad de ciudades DISTINTAS por provincia en las cuales hay


clientes, coloque un alias:
select provincia, count(distinct ciudad) as 'ciudades'
from clientes
group by provincia;

39 - Clave primaria compuesta.


Las claves primarias pueden ser simples, formadas por un solo campo o
compuestas, más de un campo.

Recordemos que una clave primaria identifica 1 solo registro en una tabla. Para un
valor del campo clave existe solamente 1 registro. Los valores no se repiten ni
pueden ser nulos.

Retomemos el ejemplo de la playa de estacionamiento que almacena cada día los


datos de los vehículos que ingresan en la tabla llamada "vehiculos" con los
siguientes campos:

- patente char(6) not null,


- tipo char (4),
- horallegada time not null,
- horasalida time,

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.

Para establecer más de un campo como clave primaria usamos la siguiente


sintaxis:

create table vehiculos(


patente char(6) not null,
tipo char(4),
horallegada time not null
horasalida time,
primary key(patente,horallegada)
);

Nombramos los campos que formarán parte de la clave separados por comas.

Si vemos la estructura de la tabla con "describe" vemos que en la columna "key",


en ambos campos aparece "PRI", porque ambos son clave primaria.

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":

alter table vehiculos drop 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.

En caso de ejecutarse la sentencia anterior, la clave queda formada sólo por el


campo "patente".

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".

Eliminamos la tabla, si existe:

drop table if exists vehiculos;

Para crear una tabla con clave primaria compuesta usamos la siguiente sintaxis:

create table vehiculos(


patente char(6) not null,
tipo char(4),
horallegada time not null,
horasalida time,
primary key(patente,horallegada)
);
Veamos la estructura de la tabla:

describe vehiculos;

Vemos que en la columna "key", en ambos campos aparece "PRI", porque ambos
son clave primaria.

Ingresemos los siguientes 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','11:10');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('HGF123','auto','9:30','11: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');

4- Intente ingresar un vehículo con clave primaria repetida:

insert into vehiculos (patente,tipo,horallegada,horasalida)


values('ACD123','auto','16:00',null);

Aparece un mensaje de error indicando que la clave está duplicada.

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:

insert into vehiculos (patente,tipo,horallegada,horasalida)


values('ACD123','auto','16:00',null);

6- Si ingresamos un registro con hora de ingreso repetida, no hay problemas,


siempre que la patente sea diferente, sino, repetimos el valor de la clave:

insert into vehiculos (patente,tipo,horallegada,horasalida)


values('ADF123','moto','8:30','10:00');

7- Intente eliminar el campo "horallegada":

alter table vehiculos drop horallegada;

No se puede porque quedarían registros con clave repetida.

8- Elimine los registros con patente "ACD123":

delete from vehiculos


where patente='ACD123';

9- Intente nuevamente eliminar el campo "horallegada":

alter table vehiculos drop horallegada;

Ahora si lo permite.

10- Vea la estructura de la tabla para ver cómo quedó la clave primaria:

describe vehiculos;

drop table if exists vehiculos;


create table vehiculos(
patente char(6) not null,
tipo char(4),
horallegada time not null,
horasalida time,
primary key(patente,horallegada)
);
describe vehiculos;
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','11:10');
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('HGF123','auto','9:30','11:40');
insert into vehiculos (patente,tipo,horallegada,horasalida)

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.

1- Elimine la tabla "prestamos" si existe.

2- Necesitamos una clave que identifique cada registro en la tabla "prestamos". El


mismo libro no puede prestarse en la misma fecha.

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)
);

4- Ingrese los siguientes registros para la tabla "prestamos":


insert into prestamos (titulo,documento,fechaprestamo)
values('Manual de 1 grado','22333444','2006-07-10');
insert into prestamos (titulo,documento,fechaprestamo)
values('Manual de 1 grado','22333444','2006-07-20');
insert into prestamos (titulo,documento,fechaprestamo)
values('Manual de 1 grado','23333444','2006-07-15');

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.

5- Intente ingresar un valor de clave primaria repetida:


insert into prestamos (titulo,documento,fechaprestamo)
values('Manual de 1 grado','25333444','2006-07-10');

Otros problemas:

A) Un consultorio médico en el cual trabajan 3 médicos registra las consultas de


los pacientes en
una tabla llamada "consultas".

1- Elimine la tabla si existe.

2- La tabla contiene los siguientes datos:


- fechayhora: datetime not null, fecha y hora de la consulta,
- medico: varchar(30), not null, nombre del médico (Perez,Lopez,Duarte),
- documento: char(8) not null, documento del paciente,
- paciente: varchar(30), nombre del paciente,
- obrasocial: varchar(30), nombre de la obra social ('IPAM','PAMI').

3- Un médico sólo puede atender a un paciente en una fecha y hora


determianada. En una fecha y hora determinada, varios médicos atienden a
distintos pacientes. Cree la tabla definiendo una clave primaria compuesta:
create table consultas(
fechayhora datetime not null,
medico varchar(30) not null,
documento char(8) not null,
paciente varchar(30),
obrasocial varchar(30),
primary key(fechayhora,medico)
);

4- Ingrese varias consultas para un mismo médico en distintas horas el mismo día.

5- Ingrese varias consultas para diferentes médicos en la misma fecha y hora.

6- Intente ingresar una consulta para un mismo médico en la misma hora el mismo
día.

B) Un club dicta clases de distintos deportes. En una tabla llamada "inscriptos"


almacena la información necesaria.

210
1- Elimine la tabla "inscriptos" si existe.

2- La tabla contiene los siguientes campos:


- documento del socio alumno: char(8) not null
- nombre del socio: varchar(30),
- nombre del deporte (tenis, futbol, natación, basquet): varchar(15) not null,
- año de inscripcion: year,
- matrícula: si la matrícula ha sido o no pagada ('s' o 'n').

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)
);

4- Inscriba a varios alumnos en el mismo deporte en el mismo año.

5- Inscriba a un mismo alumno en varios deportes en el mismo año.

6- Ingrese un registro con el mismo documento de socio en el mismo deporte en


distintos años.

7- Intente inscribir a un socio alumno en un deporte en el cual ya esté inscripto en


un año en el
cual ya se haya inscripto.

8- Intente eliminar un campo parte de la clave.

C) Un comercio guarda la información de sus ventas en una tabla llamada


"facturas".

1- Elimine la tabla si existe.

2- Intente crear la tabla con la siguiente estructura:


create table facturas(
serie char(1) not null,
numero int(10) zerofill auto_increment,
descripcion varchar(30),

211
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (serie,numero)
);

3- Aparece un mensaje de error, la tabla no puede ser creada porque el campo


definido como "auto_increment" es secundario (primero está "serie") y sabemos
que un campo "auto_increment" debe estar primero en orden al ser definido parte
de la clave compuesta.

4- Cree la tabla cambiando el orden de los campos estabecidos como clave


primaria:
create table facturas(
serie char(1) not null,
numero int(10) zerofill auto_increment,
numeroitem smallint unsigned not null,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (numero,serie,numeroitem)
);
Tenga en cuenta al ingresar registros que el campo "numero" se autoincrementará
sin tener en cuenta los demás campos.

5- Ingrese 3 registros con igual "serie", "numero" y distintos números de items:


insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',100,1,'escuadra 20 cm.',2.50,20);
insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',100,2,'escuadra 50 cm.',5,30);
insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',100,3,'goma lapiz-tinta',0.35,100);

6- Ingrese los siguientes registros:


insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',102,1,'lapices coloresx6',4.40,50);
insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',102,2,'lapices coloresx12',8,60);
insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('B',102,1,'lapices coloresx24',12.35,100);
insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)

212
values('B',102,2,'goma lapiz-tinta',0.35,200);

7- Ingrese los siguientes registros y vea qué valor da al "numero" que no se


ingresa:
insert into facturas (serie,numeroitem,descripcion,precioporunidad,cantidad)
values('A',1,'compas plastico',12,50);
insert into facturas (serie,numeroitem,descripcion,precioporunidad,cantidad)
values('A',1,'compas metal',18.90,80);

8- Intente ingresar un registro con valores de clave repetida:


insert into facturas
(serie,numero,numeroitem,descripcion,precioporunidad,cantidad)
values('A',104,1,'compas metal',18.90,80);

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;

40 - Indice de una tabla.


Para facilitar la obtención de información de una tabla se utilizan índices.
El indice de una tabla desempeña la misma función que el índice de un libro:
permite encontrar datos rápidamente; en el caso de las tablas, localiza registros.
Una tabla se indexa por un campo (o varios).

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.

El objetivo de un indice es acelerar la recuperación de información.


La desventaja es que consume espacio en el disco.

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.

Los índices se usan para varias operaciones:

- para buscar registros rápidamente.

- para recuperar registros de otras tablas empleando "join".

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.

Hay distintos tipos de índices:

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.

2) "index": crea un indice común, los valores no necesariamente son unicos y


aceptan valores "null". Podemos darle un nombre, si no se lo damos, se coloca
uno por defecto. "key" es sinónimo de "index". Puede haber varios por tabla.

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.

En las siguientes lecciones aprenderemos sobre cada uno de ellos.

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:

show index from libros;

214
41 - Indice de tipo primary.

El índice llamado primary se crea automáticamente cuando establecemos un


campo como clave primaria, no podemos crearlo directamente. El campo por el
cual se indexa puede ser de tipo numérico o de tipo caracter.

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.

Veamos un ejemplo definiendo la tabla "libros" con una clave primaria:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key(codigo)
);

Podemos ver la estructura de los índices de una tabla con "show index". Por
ejemplo:

show index from libros;

Aparece el índice PRIMARY creado automáticamente al definir el campo "codigo"


como clave primaria.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla definiendo el campo "codigo" como clave primaria:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key(codigo)
);

215
Veamos la estructura de los índices de la tabla:

show index from libros;

Muestra la siguiente información:

Table Non_unique Key_name Column_name Null


_______________________________________________
libros 0 PRIMARY codigo

Aparece el índice PRIMARY creado automáticamente al definir el campo "codigo"


como clave primaria.

La columna "Table" indica a qué tabla pertenece el índice. La columna


"Non_unique" indica si los valores del índice son No únicos, es decir, si hay
valores repetidos para ese campo, aquí indica "0" (false), o sea, los valores son
únicos. La columna "Key_name" muestra el nombre del índice. La columna
"Column_name" muestra el campo indexado y la columna "Null" señala si el
campo indexado permite valores nulos, cuando los permite aparace "YES", aquí
no, así que no los permite.

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key(codigo)
);
show index from libros;

Problema:

Una empresa almacena los datos de sus clientes en una tabla llamada "clientes".

1- Elimine la tabla "clientes" si existe.

2- Créela con los siguientes campos y clave:


create table clientes(
documento char(8),
apellido varchar(20),
nombre varchar(20),
domicilio varchar(30),
primary key(documento)
);

216
3- Vea la estructura de los índices la tabla y analice la información:
show index from clientes;

Otros problemas:

Un instituto de enseñanza almacena los datos de sus estudiantes en una tabla


llamada "alumnos".

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla con la siguiente estructura:


create table alumnos(
legajo varchar(4) not null,
documento char(8) not null,
apellido varchar(30),
nombre varchar(30),
domicilio varchar(30),
primary key (legajo)
);
3- Vea la estructura de los índices la tabla y analice la información:
show index from alumnos;

42 - Indice común (index)


Dijimos que hay 3 tipos de índices. Hasta ahora solamente conocemos la clave
primaria que definimos al momento de crear una tabla.

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.

Vamos a trabajar con nuestra tabla "libros".

Un campo por el cual realizamos consultas frecuentemente es "editorial", indexar


la tabla por ese campo sería útil.

Creamos un índice al momento de crear la tabla:

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)
);

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.

"show index" muestra la estructura de los índices:

show index from libros;

Si no le asignamos un nombre a un índice, por defecto tomará el nombre del


primer campo que forma parte del índice, con un sufijo opcional (_2,_3,...) para
que sea único.

Ciertas tablas (MyISAM, InnoDB y BDB) soportan índices en campos que permiten
valores nulos, otras no, debiendo definirse el campo como "not null".

Se pueden crear índices por varios campos:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
index i_tituloeditorial (titulo,editorial)
);

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.

Recuerde que "index" es sinónimo de "key".

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla, si existe.

Creamos la tabla "libros" con 2 índices:

- una clave primaria (codigo),


- un índice común por el campo "editorial",

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),

218
primary key(codigo),
index i_editorial (editorial)
);
Analicemos la estructura de los índices:

show index from libros;

Analicemos esta información:

Table Non_unique Key_name Column_name Null


________________________________________________
libros 0 PRIMARY codigo
libros 1 i_editorial editorial YES

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 "Table" indica de qué tabla estamos visualizando los índices.

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.

La columna "Key_name" muestra el nombre del índice; para el campo


correspondiente a la clave primaria tomó el nombre "PRIMARY"; el otro nombre es
el que le dimos nosotros al definirlo (i_editorial).

La columna "Column_name" muestra el nombre del campo por el que está


ordenado el índice, "codigo" para el índice "PRIMARY" y "editorial" para nuestro
índice.

La columna "Null" indica si permite valores nulos; el índice "PRIMARY" no los


permite (recuerde lo aprendido sobre clave primaria), el índice "i_editorial" si los
permite (aparece YES).

Las demás columnas no serán explicadas por el momento.

Se pueden crear índices por varios campos:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),

219
primary key(codigo),
index i_tituloeditorial (titulo,editorial)
);

Note que los campos se listan entre paréntesis separados por comas.

Veamos la información de los índices:

show index from libros;

Analicemos esta información:

Table Non_unique Key_name Seq_in_index Column_name Null


_______________________________________________________________
libros 0 PRIMARY 1 codigo
libros 1 i_tituloeditorial 1 titulo
libros 1 i_tituloeditorial 2 editorial YES

Aparecen 3 filas.

La tabla tiene 2 índices (2 filas corresponden al mismo índice): 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_tituloeditorial".

El índice "PRIMARY", no tiene valores repetidos (No es "No único"); el índice


"i_tituloeditorial" es "No único", o sea, hay valores repetidos.

La columna "Seq_in_index" y "Column_name" muestran la secuencia de la


indexación para cada campo. 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.

La columna "Null" indica si el campo permite valores nulos; el índice "PRIMARY"


no los permite; el campo "titulo" del índice "i_tituloeditorial" no los permite
(recuerde que lo definimos "not null"), el campo "editorial" si los permite (YES).

drop table if exists libros;


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)
);
show index from libros;
drop table if exists libros;
create table libros(

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:

Retome la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe.

2- Cree la tabla e indéxela por el campo "laboratorio":


create table medicamentos(
codigo int unsigned auto_increment,
nombre varchar(20) not null,
laboratorio varchar(20),
precio decimal (6,2) unsigned,
cantidad int unsigned,
primary key(codigo),
index i_laboratorio (laboratorio)
);

3- Visualice los índices de la tabla "medicamentos" y analice la información:


show index from medicamentos;

Otros problemas:

A) Retomamos la tabla "clientes" de una empresa.

1- Elimine la tabla "clientes", si existe.

2- Créela y defina un índice por múltiples campos, por ciudad y provincia:


create table clientes (
documento char (8) not null,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11),
primary key (codigo),
index i_ciudadprovincia (ciudad,provincia)
);

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).

B) Trabaje con la tabla "agenda" que registra la información referente a sus


amigos.

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table agenda(
apellido varchar(30),
nombre varchar(20) not null,
domicilio varchar(30),
telefono varchar(11),
mail varchar(30),
index i_apellido (apellido)
);
3- Ingrese los siguientes registros:
insert into agenda values('Perez','Juan','Sarmiento
345','4334455','[email protected]');
insert into agenda values('Garcia','Ana','Urquiza
367','4226677','[email protected]');
insert into agenda values('Lopez','Juan','Avellaneda
900',null,'[email protected]');
insert into agenda values('Juarez','Mariana','Sucre
123','0525657687','[email protected]');
insert into agenda values('Molinari','Lucia','Peru
1254','4590987','[email protected]');
insert into agenda values('Ferreyra','Patricia','Colon 1534','4585858',null);
insert into agenda values('Perez','Susana','San Martin 333',null,null);
insert into agenda values('Perez','Luis','Urquiza
444','0354545256','[email protected]');
insert into agenda values('Lopez','Maria','Salta
314',null,'[email protected]');

4- Vea la información de los índices:


show index from agenda;
5- Analice la información.

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.

Vamos a trabajar con nuestra tabla "libros".

Crearemos dos índices únicos, uno por un solo campo y otro multicolumna:

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)
);

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.

"show index" muestra la estructura de los índices:

show index from libros;

RESUMEN: Hay 3 tipos de índices con las siguientes características:

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.

Eliminamos la tabla, si existe.

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)
);

Veamos la información de los índices:

show index from libros;

Analicemos esta información:

Table Non_unique Key_name Seq_in_index Column_name Null


___________________________________________________________
libros 0 i_codigo 1 codigo
libros 0 i_tituloeditorial 1 titulo
libros 0 i_tituloeditorial 2 editorial YES

Aparecen 3 filas.

La tabla tiene 2 índices (2 filas corresponden al mismo índice).

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.

La columna "Null" indica si el campo permite valores nulos; el índice "i_codigo" no


los permite; el campo "titulo" del índice "i_tituloeditorial" no los permite (recuerde
que lo definimos "not null"), el campo "editorial" si los permite (YES).

drop table if exists libros;


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)
);
show index from libros;

224
Problema:

Un instituto de enseñanza guarda los siguientes datos de sus alumnos:


- año de inscripción,
- número de inscripto, comienza desde 1 cada año,
- nombre del alumno,
- documento del alumno,
- domicilio,
- ciudad,
- provincia,
- clave primaria: número de inscripto y año de inscripción.

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla definiendo una clave primaria compuesta (año de inscripción y


número de inscripto), un índice único por el campo "documento" y un índice común
por ciudad y provincia:
create table alumnos(
año year not null,
numero int unsigned not null,
nombre varchar(30),
documento char(8) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar(20),
primary key(año,numero),
unique i_documento (documento),
index i_ciudadprovincia (ciudad,provincia),
);

3- Vea los índices de la tabla.

4- Ingrese algunos registros. Ingrese 2 ó 4 alumnos para los años 2004, 2005 y
2006.

5- Intente ingresar un alumno con clave primaria repetida.

6- Intente ingresar un alumno con documento repetido.

7- Ingrese varios alumnos de la misma ciudad y provincia.

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,

1- Elimine la tabla si existe.

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.

3- Cree la tabla con la siguiente estructura:


create table consultas(
fecha date,
numero int unsigned,
documento char(8) not null,
obrasocial varchar(30),
medico varchar(30),
primary key(fecha,numero),
unique i_consulta(documento,fecha,medico),
index i_medico (medico),
index i_obrasocial (obrasocial)
);

4- Vea los índices.

5- Los valores de la clave primaria no pueden repetirse. Intente ingresar dos


pacientes el mismo día con el mismo número de consulta.

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.

B) Una empresa de remises tiene registrada la información de sus vehículos en


una tabla
llamada "remis".

1- Elimine la tabla si existe.

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):

create table remis(


patente char(6) not null,
numero tinyint unsigned not null,
marca varchar(15),
modelo year,
primary key (numero),
unique i_patente (patente),
);

3- Vea los índices y analice la información.

4- Los valores de la clave primaria no pueden repetirse. Intente ingresar 2


vehículos con el mismo
número.

5- Los valores para el índice único no pueden repetirse. Intente ingresar 2


vehículos con igual
patente.

44 - Borrar indice (drop index)


Para eliminar un índice usamos "drop index". Ejemplo:

drop index i_editorial on libros;


drop index i_tituloeditorial on libros;

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.

Eliminamos la tabla, si existe.

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)
);

Veamos la información de los índices:

show index from libros;

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":

drop index i_editorial on libros;

Eliminamos el índice "i_tituloeditorial":

drop index i_tituloeditorial on libros;

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".

drop table if exists libros;


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)
);
show index from libros;
drop index i_editorial on libros;
drop index i_tituloeditorial on libros;
show index from libros;

228
Problema:

Un instituto de enseñanza guarda los datos de sus alumnos en una tabla llamada
"alumnos".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table alumnos(
año year not null,
numero int unsigned not null,
nombre varchar(30),
documento char(8) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar(20),
primary key(año,numero),
unique i_documento (documento),
index i_ciudadprovincia (ciudad,provincia),
);

3- Vea los índices de la tabla.

4- Elimine el índice "i_ciudadprovincia".

5- Verifique la eliminación usando "show index".

6- Intente eliminar el índice PRIMARY.

7- Elimine el índice único.

8- Verifique la eliminación usando "show index".

Otros problemas:

Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".

1- Elimine la tabla si existe.

2- Cree la tabla con la estructura siguiente:


create table consultas(
fecha date,
numero int unsigned,
documento char(8) not null,
obrasocial varchar(30),

229
medico varchar(30),
primary key(fecha,numero),
unique i_consulta(documento,fecha,medico),
index i_medico (medico),
index i_obrasocial (obrasocial)
);

4- Vea los índices.

5- Elimine el índice único.

6- Elimine el índice "i_medico".

7- Verifique las eliminaciones anteriores visualizando los índices.

8- Elimine el índice "i_obrasocial".

45 - Creación de índices a tablas existentes (create index)


Podemos agregar un índice a una tabla existente.
Para agregar un índice común a la tabla "libros" tipeamos:

create index i_editorial on libros (editorial);

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 la tabla "libros" tipeamos:

create unique index i_tituloeditorial on libros (titulo,editorial);

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á.

Un índice PRIMARY no puede agregarse, se crea automáticamente al definir una


clave primaria.

Ejemplo:
Trabajamos con nuestra tabla "libros" de una librería.

Eliminamos la tabla, si existe.

230
Creamos la tabla con clave primaria:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);

Veamos la información de los índices:

show index from libros;

Vemos que tenemos el índice creado al definir la clave primaria (PRIMARY).


Para agregar un índice común a la tabla "libros" tipeamos:

create index i_editorial on libros (editorial);

Veamos la información de los índices:

show index from libros;

Aparecen 2, "PRIMARY" y "i_editorial".

Para agregar un índice único a la tabla "libros" tipeamos:

create unique index i_tituloeditorial on libros (titulo,editorial);

Veamos la información de los índices:

show index from libros;

Aparecen 3, "PRIMARY", "i_editorial" y "i_tituloeditorial".

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
primary key (codigo)
);
show index from libros;
create index i_editorial on libros (editorial);
show index from libros;
create unique index i_tituloeditorial on libros (titulo,editorial);
show index from libros;

231
Problema:

Retome la tabla "clientes" que almacena información sobre los clientes de una
empresa.

1- Elimine la tabla "clientes", si existe.

2- Créela con esta estructura:


create table clientes (
documento char (8) not null,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar (20),
telefono varchar(11)
);

3- Agregue un índice común por ciudad y provincia:


create index i_ciudadprovincia on clientes (ciudad,provincia);

4- Vea la información de los índices:


show index from clientes;

5- Agregue un índice único por el campo "documento":


create unique index i_documento on clientes (documento);

Otros problemas:

Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table consultas(
fecha date,
numero int unsigned,
documento char(8) not null,
obrasocial varchar(30),
medico varchar(30),
);

3- Agregue un índice único multicampo (fecha,documento,medico):


create unique index i_consulta on consultas (fecha,documento,medico);

4- Agregue un índice común por el campo "medico":


create index i_medico on consultas (medico);

232
5- Agregue un índice común por el campo "obrasocial":
create index i_obrasocial on consultas (obrasocial);

6- Vea los índices.

46 - Cláusula limit del comando select.

La cláusula "limit" se usa para restringir los registros que se retornan en una
consulta "select".

Recibe 1 ó 2 argumentos numéricos enteros positivos; el primero indica el número


del primer registro a retornar, el segundo, el número máximo de registros a
retornar. El número de registro inicial es 0 (no 1).

Si el segundo argumento supera la cantidad de registros de la tabla, se limita


hasta el último registro.

Ejemplo:
select * from libros limit 0,4;

Muestra los primeros 4 registros, 0,1,2 y 3.

Si tipeamos:
select * from libros limit 5,4;

recuperamos 4 registros, desde el 5 al 8.

Si se coloca un solo argumento, indica el máximo número de registros a retornar,


comenzando desde 0. Ejemplo:
select * from libros limit 8;

Muestra los primeros 8 registros.

Para recuperar los registros desde cierto número hasta el final, se puede colocar
un número grande para el segundo argumento:

select * from libros limit 6,10000;

recupera los registros 7 al último.

"limit" puede combinarse con el comando "delete". Si queremos eliminar 2


registros de la tabla "libros" Usamos:

delete from libros


limit 2;

233
Podemos ordenar los regitros por precio (por ejemplo) y borrar 2:

delete from libros


order by precio
limit 2;

esta sentencia borrará los 2 primeros registros, es decir, los de precio más bajo.

Podemos emplear la cláusula "limit" para eliminar registros duplicados. Por


ejemplo, continuamos con la tabla "libros" de una librería, ya hemos almacenado
el libro "El aleph" de "Borges" de la editorial "Planeta", 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:

select * from libros


where titulo='El aleph' and
autor='Borges' and
editorial='Planeta';

Luego eliminamos con "limit" la cantidad sobrante (tenemos 3 y queremos solo 1):

delete from libros


where titulo='El aleph" and
autor='Borges' and
editorial='Planeta'
limit 2;

Un mensaje nos muestra la cantidad de registros eliminados.

Es decir, con "limit" indicamos la cantidad a eliminar.

Veamos cuántos hay ahora:

select * from libros


where titulo='El aleph" and
autor='Borges' and
editorial='Planeta';

Sólo queda 1.

234
Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla:

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)
);

Agregamos algunos registros:

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);

Para recuperar 4 libros desde el registro cero tipeamos:

select * from libros limit 0,4;

Para recuperar 4 libros a partir del registro 5:

select * from libros limit 5,4;

Si colocamos un solo argumento, éste indica el máximo número de registros a


retornar, comenzando desde 0:

235
select * from libros limit 8;

Muestra los primeros 8 registros.

Para recuperar los registros desde cierto número hasta el último, colocamos un
número grande para el segundo argumento:

select * from libros limit 6,10000;

Ordenamos por precio y combinamos "limit" con el comando "delete" para eliminar
los 2 registros con precio más bajo:

delete from libros


order by precio
limit 2;

se eliminaron los 2 registros con precio más bajo.

También podemos emplear la cláusula "limit" para eliminar registros duplicados.


Por ejemplo: almacenamos el libro "El aleph" de "Borges" de la editorial "Planeta":

insert into libros (titulo,autor,editorial,precio)


values('El aleph','Borges','Planeta',15);

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):

insert into libros (titulo,autor,editorial,precio)


values('El aleph','Borges','Planeta',15);
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',15);

Para eliminar el libro duplicado y que sólo quede un registro de él, vemos cuántos
tenemos:

select * from libros


where titulo='El aleph" and
autor='Borges' and
editorial='Planeta';

Nos devuelve 3 registros.

Luego eliminamos con "limit" la cantidad sobrante (tenemos 3 y queremos sólo 1):

delete from libros


where titulo='El aleph" and

236
autor='Borges' and
editorial='Planeta'
limit 2;

Un mensaje nos muestra la cantidad de registros eliminados.

Veamos cuántos hay ahora:

select * from libros


where titulo='El aleph" and
autor='Borges' and
editorial='Planeta';

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;

delete from libros


order by precio
limit 2;
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Planeta',15);
insert into libros (titulo,autor,editorial,precio)

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.

1- Elimine la tabla, si existe.


- Créela con la siguiente estructura:
-codigo (entero sin signo, autoincrementable),
-titulo (cadena de 30), not null,
-actor (cadena de 20),
-duracion (entero sin signo no mayor a 200 aprox.),
-clave primaria (codigo).

3- Ingrese 10 registros.

4- Realice una consulta limitando la salida a sólo 5 registros.

5- Muestre los registros desde el cero al 8 usando un solo argumento.

6- Muestre 3 registros a partir del 4.

7- Muestre los registros a partir del 2 hasta el final.

Otros problemas:

Trabaje con la tabla "agenda" que registra la información referente a sus amigos.

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table agenda(
apellido varchar(30),

238
nombre varchar(20) not null,
domicilio varchar(30),
telefono varchar(11),
mail varchar(30),
index i_apellido (apellido)
);

3- Ingrese 10 registros.

4- Realice una consulta limitando la salida a sólo 3 registros.

5- Muestre los registros desde el cero al 9 usando un solo argumento.

6- Muestre 5 registros a partir del 5.

7- Muestre los registros a partir del 7 hasta el final.

47 - Recuperación de registros en forma aleatoria(rand)


Una librería que tiene almacenados los datos de sus libros en una tabla llamada
"libros" quiere donar a una institución 5 libros tomados al azar.

Para recuperar de una tabla registros aleatorios se puede utilizar la función


"rand()" combinada con "order by" y "limit":

select * from libros


order by rand()
limit 5;

Nos devuelve 5 registros 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.

Ejemplo:
Trabajamos con la tabla "libros" en el cual una librería guarda los datos de sus
libros.

Eliminamos la tabla "libros" si existe:


drop table if exists libros;
Creamos la tabla:
create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),

239
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
Agregamos varios registros:

insert into libros values(1,'El aleph','Borges','Planeta',23.5);


insert into libros values(2,'Cervantes y el quijote','Borges','Paidos',33.5);
insert into libros
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);

la librería quiere tomar 5 libros al azar para donarlos a una institución.

Para recuperar de la tabla "libros" registros aleatorios utilizamos la función "rand()"


combinada con "order by" y "limit":

select * from libros


order by rand()
limit 5;

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:

select * from libros order by rand() limit 5;


select * from libros order by rand() limit 5;
select * from libros order by rand() limit 5;

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
insert into libros values(1,'El aleph','Borges','Planeta',23.5);
insert into libros values(2,'Cervantes y el quijote','Borges','Paidos',33.5);
insert into libros

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:

Trabajamos con la tabla "alumnos" en el cual un instituto de enseñanza guarda los


datos de sus alumnos.
Eliminamos la tabla "alumnos" si existe:
drop table if exists alumnos;
Creamos la tabla:
create table alumnos(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
ciudad varchar(20),
provincia varchar(20),
primary key(documento)
);
Agregamos varios registros:
insert into alumnos values('22333444','Juan Perez','Colon
123','Cordoba','Cordoba');
insert into alumnos values('23456789','Ana Acosta','Caseros
456','Cordoba','Cordoba');
insert into alumnos values('24123123','Patricia Morales','Sucre 234','Villa del
Rosario','Cordoba');
insert into alumnos values('25000333','Jose Torres','Sarmiento 980','Carlos
Paz','Cordoba');
insert into alumnos values('26333444','Susana Molina','Avellaneda
234','Rosario','Santa Fe');
insert into alumnos values('27987654','Marta Herrero','San Martin 356','Villa del
Rosario','Cordoba');
insert into alumnos values('28321321','Marcos Ferreyra','Urquiza
357','Cordoba','Cordoba');
insert into alumnos values('30987464','Marta Perez','Rivadavia
234','Cordoba','Cordoba');

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;

Nos devuelve los nombres y documentos de 3 alumnos tomados al azar de la


tabla "alumnos". Podemos
ejecutar la sentencia anterior varias veces seguidas y veremos que los registros
recuperados son diferentes en cada ocasión:
select documento,nombre from alumnos order by rand() limit 3;
select documento,nombre from alumnos order by rand() limit 3;
select documento,nombre from alumnos order by rand() limit 3;

Otros problemas:

Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con
ese nombre.

1- Elimine "articulos", si existe:


drop table if exists articulos;

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo int unsigned auto_increment,
nombre varchar(25) not null,
descripcion varchar(30),
precio decimal(6,2) unsigned,
cantidad tinyint unsigned,
primary key(codigo)
);

3- Ingrese algunos registros:


insert into articulos (nombre, descripcion, precio,cantidad)
values ('impresora','Epson Stylus C45',400.80,20);
insert into articulos (nombre, descripcion, precio,cantidad)
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)

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.

48 - Remplazar registros (replace)


"replace" reemplaza un registro por otro.

Cuando intentamos ingresar con "insert" un registro que repite el valor de un


campo clave o indexado con índice único, aparece un mensaje de error indicando
que el valor está duplicado. Si empleamos "replace" en lugar de "insert", el registro
existente se borra y se ingresa el nuevo, de esta manera no se duplica el valor
único.

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.

Veamos un ejemplo. Tenemos los siguientes registros almacenados en "libros":

codigo titulo autor editorial precio


-------------------------------------------------------------------------------------
10 Alicia en .. Lewis Carroll Emece 15.4
15 Aprenda PHP Mario Molina Planeta 45.8
23 El aleph Borges Planeta 23.0

Intentamos insertar un registro con valor de clave repetida (código 23):

insert into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);

Aparece un mensaje de error indicando que hay registros duplicados.

Si empleamos "replace":

replace into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);

la sentencia se ejecuta y aparece un mensaje indicando que se afectaron 2 filas,


esto es porque un registro se eliminó y otro se insertó.

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:

replace into libros(titulo,autor,editorial,precio)


values('Cervantes y el quijote','Borges','Paidos',28);

aparece un mensaje indicando que se afectó un solo registro, el ingresado, que se


guarda con valor de código 0.

- si el dato para el campo indexado que se ingresa no existe:

replace into libros values(30,'Matematica estas ahi','Paenza','Paidos',12.8);

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.

- si la tabla no tiene indexación. Si la tabla "libros" no tuviera establecida ninguna


clave primaria (ni índice único), podríamos ingresar varios registros con igual
código:

replace into libros values(1,'Harry Potter ya la piedra


filosofal','Hawking','Emece',48);

aparecería un mensaje indicando que se afectó 1 registro (el ingresado), no se


reemplazó ninguno y ahora habría 2 libros con código 1.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe:

drop table if exists libros;

Creamos la tabla:

create table libros(


codigo int unsigned,
titulo varchar(40),
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);

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);

Intentemos ingresar un registro con valor de clave repetida (código 23):

insert into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);

aparece un mensaje de error indicando que hay registros duplicados.


Para reemplazar el registro con clave 23 por el nuevo empleamos "replace":

replace into libros values(23,'Java en 10 minutos','Mario Molina','Emece',25.5);

aparece un mensaje indicando que se afectaron 2 filas, esto es porque un registro


se eliminó y otro se insertó.

Veamos los casos en los cuales "replace" funciona como "insert":

- ingresamos un registro sin valor de código:

replace into libros(titulo,autor,editorial,precio)


values('Cervantes y el quijote','Borges','Paidos',28);

aparece un mensaje indicando que se afectó un solo registro, el ingresado, que se


guarda con valor de código 0.

- ingresamos un registro con un valor de código que no existe:

replace into libros values(30,'Matematica estas ahi','Paenza','Paidos',12.8);

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.

Quitemos la clave primaria:

alter table libros drop primary key;

Ingresamos un registro con valor de código repetido usando "replace":

replace into libros values(10,'Harry Potter ya la piedra


filosofal','Hawking','Emece',48);

aparece un mensaje indicando que se afectó 1 registro (el ingresado), no se


reemplazó ninguno y ahora hay 2 libros con código 10.

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:

Un instituto de enseñanza guarda los datos de sus alumnos en la tabla "alumnos".

1- Elimine la tabla si existe:


drop table if exists alumnos;

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)
);

3- Ingrese algunos registros:


insert into alumnos values('1353','Juan Lopez','22333444','Colon 123');
insert into alumnos values('2345','Ana Acosta','24000555','Caseros 456');
insert into alumnos values('2356','Jose Torres','26888777','Sucre 312');
insert into alumnos values('3567','Luis Perez','28020020','Rivadavia 234');

4- Intente ingresar un registro con clave primaria repetida (legajo "3567"):


insert into alumnos values('3567','Marcos Pereyra','30000333','Guemes 134');
aparece un mensaje de error.

246
5- Ingrese el registro anterior reemplazando el existente:
replace into alumnos values('3567','Marcos Pereyra','30000333','Guemes 134');

6- Intente ingresar un alumno con documento repetido:


insert into alumnos values('4567','Susana Juarez','30000333','Avellaneda 33');
aparece un mensaje de error.

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.

8- Elimine el índice único:


drop index i_documento on alumnos;

9- Ingrese con "replace" el siguiente registro con documento existente:


replace into alumnos values('4888','Gustavo Garcia','30000333','San Martin 846');
un registro afectado, no hubo eliminación solamente inserción.

10- Muestre todos los registros:


select * from alumnos;
note que hay dos alumnos con el mismo número de documento.

49 - Agregar campos a una tabla (alter table - add)


Para modificar la estructura de una tabla existente, usamos "alter table".

"alter table" se usa para:

- agregar nuevos campos,


- eliminar campos existentes,
- modificar el tipo de dato de un campo,
- agregar o quitar modificadores como "null", "unsigned", "auto_increment",
- cambiar el nombre de un campo,
- agregar o eliminar la clave primaria,
- agregar y eliminar índices,
- renombrar una tabla.

"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.

Aprenderemos a agregar campos a una tabla.

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.

Necesitamos agregar el campo "cantidad", de tipo smallint unsigned not null,


tipeamos:

alter table libros


add cantidad smallint unsigned not null;

Usamos "alter table" seguido del nombre de la tabla y "add" seguido del nombre
del nuevo campo con su tipo y los modificadores.

Agreguemos otro campo a la tabla:

alter table libros


add edicion date;

Si intentamos agregar un campo con un nombre existente, aparece un mensaje de


error indicando que el campo ya existe y la sentencia no se ejecuta.

Cuando se agrega un campo, si no especificamos, lo coloca al final, después de


todos los campos existentes; podemos indicar su posición (luego de qué campo
debe aparecer) con "after":

alter table libros


add cantidad tinyint unsigned after autor;

Ejemplo:
Trabajamos con la tabla "libros".

Eliminamos la tabla "libros" si existe.

Creamos la tabla "libros" con la siguiente estructura:

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)
);

248
Para agregar el campo "cantidad" de tipo smallint unsigned not null, tipeamos:

alter table libros


add cantidad smallint unsigned not null;

Vemos su nueva estructura:

describe libros;

Ahora la tabla tiene un nuevo campo, el ingresado con "alter table".

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".

Agreguemos otro campo a la tabla:


alter table libros
add edicion date;

Vemos la nueva estructura:


describe libros;

Si mostramos todos los registros, vemos que los valores para el nuevo campo se
cargaron con su valor por defecto, "null" en este caso.

Si intentamos agregar un campo existente aparece un mensaje de error indicando


que la columna existe y la acción no se realiza:

alter table libros


add precio int;

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)
);
alter table libros
add cantidad smallint unsigned not null;
describe libros;
alter table libros
add edicion date;
describe libros;
alter table libros
add precio int;

249
Problema:

Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table peliculas(
codigo int unsigned auto_increment,
nombre varchar(30) not null,
actor varchar(20),
primary key(codigo)
);

3- Ingrese algunos registros.

4- Agregue un campo para almacenar la duración de la película, de tipo tinyint


unsigned:
alter table peliculas
add duracion tinyint unsigned;

5- Visualice la estructura de la tabla con "describe".

6- Agregue el campo "director" para almacenar el nombre del director, de tipo


varchar(20):
alter table peliculas
add director varchar(20);

7- Visualice la estructura de la tabla con su nuevo campo:


describe peliculas;

8- Intente agregar un campo existente. Aparece un mensaje de error:


alter table peliculas
add actor varchar(20);

Otros problemas:

Un comercio que vende por mayor artículos de librería y papelería tiene una tabla
llamada "articulos".

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table articulos(
codigo int unsigned auto_increment,
nombre varchar(20) not null,
descripcion varchar(30),

250
precio decimal(4,2) unsigned,
primary key(codigo)
);

3- Ingrese los siguientes registros:


insert into articulos (nombre,descripcion,precio)
values('escuadra','plastico 20 cm.',3.50);
insert into articulos (nombre,descripcion,precio)
values('lápices colores','Join x12',4.50);
insert into articulos (nombre,descripcion,precio)
values('lápices colores','Join x24',7.50);
insert into articulos (nombre,descripcion,precio)
values('regla','30 cm.',2.50);
insert into articulos (nombre,descripcion,precio)
values('fibras','Join x12',10.30);
insert into articulos (nombre,descripcion,precio)
values('fibras','Join x6',5.10);

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;

5- Muestre todos los registros:


select * from articulos;
Note que para el nuevo campo los valores se setearon en "null".

6- Actualice el campo "preciopormenor" de todos los registros, dándole el valor del


campo "precio" incrementado en un 10%:
update articulos set preciopormenor=precio+(precio*0.10);

7- Muestre todos los registros:


select * from articulos;

50 - Eliminar campos de una tabla (alter table - drop)


"alter table" nos permite alterar la estructura de la tabla, podemos usarla para
eliminar un campo.

Continuamos con nuestra tabla "libros".

251
Para eliminar el campo "edicion" tipeamos:

alter table libros


drop edicion;

Entonces, para borrar un campo de una tabla usamos "alter table" junto con "drop"
y el nombre del campo a eliminar.

Si intentamos borrar un campo inexistente aparece un mensaje de error y la


acción no se realiza.

Podemos eliminar 2 campos en una misma sentencia:

alter table libros


drop editorial, drop cantidad;

Si se borra un campo de una tabla que es parte de un índice, también se borra el


índice.

Si una tabla tiene sólo un campo, éste no puede ser borrado.

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:

alter table libros


drop codigo;

Si eliminamos un campo clave, la clave también se elimina.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla "libros" si existe.

Creamos la tabla "libros" con la siguiente estructura:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar (20),
edicion date,
precio decimal(5,2) unsigned,
cantidad int unsigned,
primary key(codigo)
);

252
Para eliminar el campo "edicion" tipeamos:

alter table libros


drop edicion;

Si visualizamos la estructura de la tabla con "describe", vemos que la columna


"edicion" se ha eliminado:

describe libros;

Si intentamos borrar un campo inexistente aparece un mensaje de error y la


acción no se realiza:

alter table libros


drop edicion;

Para eliminar 2 campos en una misma sentencia tipeamos:

alter table libros


drop editorial, drop cantidad;

Elimine el campo clave:

alter table libros


drop codigo;

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar (20),
edicion date,
precio decimal(5,2) unsigned,
cantidad int unsigned,
primary key(codigo)
);
alter table libros
drop edicion;
describe libros;
alter table libros
drop edicion;
alter table libros
drop editorial, drop cantidad;
alter table libros
drop codigo;

253
Problema:

Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table peliculas(
codigo int unsigned auto_increment,
nombre varchar(30) not null,
protagonista varchar(20),
actorsecundario varchar(20),
director varchar(25),
duracion tinyint unsigned,
primary key(codigo),
index i_director (director)
);

3- Ingrese algunos registros.

4- Vea los índices:


show index from peliculas;

5- Elimine el campo "director":


alter table peliculas
drop director;

6- Visualice la estructura modificada:


describe peliculas;

7- Vea los índices:


show index from peliculas;
Note que el índice por "editorial" ya no existe, esto es porque si borra un campo
que es parte de un índice, también se borra el índice.

8- Intente eliminar un campo inexistente. Aparece un mensaje de error:


alter table peliculas
drop director;

9- Elimine los campos "actorsecundario" y "duracion" en una misma sentencia:


alter table peliculas
drop actorsecundario, drop cantidad;

254
Otros problemas:

Trabajamos con nuestra tabla "usuarios" que almacena los nombres de los
usuarios y sus claves.

1- Elimine la tabla si existe.

2- Cree la tabla:
create table usuarios (
nombre varchar(30),
clave varchar(10)
);

3- Elimine el campo "clave":


alter table usuarios
drop clave;

4- Visualice la estructura de la tabla:


describe usuarios;

5- Intente eliminar el único campo de la tabla:


alter table usuarios
drop nombre;
Aparece un mensaje de error y la sentencia no se ejecuta, esto es porque no se
puede dejar una tabla vacía de campos.

51 - Modificar campos de una tabla (alter table - modify)


Con "alter table" podemos modificar el tipo de algún campo incluidos sus atributos.

Continuamos con nuestra tabla "libros", definida con la siguiente estructura:

- código, int unsigned,


- titulo, varchar(30) not null,
- autor, varchar(30),
- editorial, varchar (20),
- precio, decimal(5,2) unsigned,
- cantidad int unsigned.

Queremos modificar el tipo del campo "cantidad", como guardaremos valores que
no superarán los 50000 usaremos smallint unsigned, tipeamos:

alter table libros

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:

alter table libros


modify titulo varchar(40) not null;

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.

Igualmente, si un campo fue definido permitiendo valores nulos, se cargaron


registros con valores nulos y luego se lo define "not null", todos los registros con
valor nulo para ese campo cambiarán al valor por defecto según el tipo (cadena
vacía para tipo texto y 0 para numéricos), ya que "null" se convierte en un valor
inválido.

Si definimos un campo de tipo decimal(5,2) y tenemos un registro con el valor


"900.00" y luego modificamos el campo a "decimal(4,2)", el valor "900.00" se
convierte en un valor inválido para el tipo, entonces guarda en su lugar, el valor
límite más cercano, "99.99".

Si intentamos definir "auto_increment" un campo que no es clave primaria,


aparece un mensaje de error indicando que el campo debe ser clave primaria. Por
ejemplo:

alter table libros


modify codigo int unsigned auto_increment;

"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:

alter table libros


alter autor set default 'Varios';

Para eliminar el valor por defecto podemos emplear:

alter table libros


alter autor drop default;

256
Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla "libros" si existe.

Creamos la tabla "libros" con la siguiente estructura:


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
);
Para modificar el tipo del campo "cantidad" por "smallint unsigned", tipeamos:
alter table libros
modify cantidad smallint unsigned;

Si visualizamos la estructura de la tabla:


describe libros;

vemos la nueva definición del campo "cantidad".

Para modificar el tipo del campo "titulo" para poder almacenar una longitud de 40
caracteres y que no permita valores nulos, tipeamos:

alter table libros


modify titulo varchar(40) not null;

Visualicemos la estructura de la tabla:

describe libros;

Ahora el campo "titulo" permite 40 caracteres de longitud.

Ingresemos algunos registros:

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);

Modificamos el tipo de dato de "autor" a 10 caracteres de longitud:

257
alter table libros
modify autor varchar(10);

Mostramos todos los registros:

select * from libros;

Note que los nombres de los autores que tenían más de 10 caracteres se cortaron.

Modificamos el tipo de dato de "autor" para que no permita valores nulos:

alter table libros


modify autor varchar(10) not null;

Mostramos todos los registros:

select * from libros;

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.

El libro "Martín Fierro" tiene un precio de $150; si modificamos el tipo de dato de


"precio" a "decimal(4,2), el precio anterior quedará fuera del rango:

alter table libros


modify precio decimal(4,2);

Mostramos todos los registros:

select * from libros,

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".

Si intentamos definir "auto_increment" un campo que no es clave primaria,


aparece un mensaje de error indicando que el campo debe ser clave primaria:

alter table libros


modify codigo int unsigned auto_increment;

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:

Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table peliculas(
codigo int unsigned,
nombre varchar(20) not null,
actor varchar(20),
director varchar(25),
duracion tinyint
);
3- Modifique el campo "duracion" por tinyint unsigned.
alter table peliculas
modify duracion tinyint unsigned;

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;

5- Modifique el campo "actor" para que no permita valores nulos:


alter table peliculas
modify actor varchar(20) not null;

6- Intente definir "auto_increment" el campo "codigo" (mensaje de error):


alter table peliculas
modify codigo int unsigned auto_increment;

Otros problemas:

Un comercio que vende artículos de computación registra los datos de sus


artículos en una tabla con
ese nombre.

1- Elimine "articulos", si existe.

2- Cree la tabla, con la siguiente estructura:


create table articulos(
codigo int unsigned,
nombre varchar(25) not null,
descripcion varchar(30),
precio decimal(4,2) unsigned,
cantidad tinyint,
primary key(codigo)
);
3- Modifique el campo "precio" para que pueda guardar valores hasta "9999.99".

4- Modifique el campo "codigo" para que se autoincremente.

5- Modifique el campo "cantidad" para que no permita valores negativos.

52 - Cambiar el nombre de un campo de una tabla (alter table - change)


Con "alter table" podemos cambiar el nombre de los campos de una tabla.

Continuamos con nuestra tabla "libros", definida con la siguiente estructura:

- código, int unsigned auto_increment,

260
- nombre, varchar(40),

- autor, varchar(30),

- editorial, varchar (20),

- costo, decimal(5,2) unsigned,

- cantidad int unsigned,

- clave primaria: código.

Queremos cambiar el nombre del campo "costo" por "precio", tipeamos:

alter table libros


change costo precio decimal (5,2);

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.

Con "change" cambiamos el nombre de un campo y también podemos cambiar el


tipo y sus modificadores. Por ejemplo, queremos cambiar el nombre del campo
"nombre" por "titulo" y redefinirlo como "not null", tipeamos:

alter table libros


change nombre titulo varchar(40) not null;

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:

create table libros(


codigo int unsigned auto_increment,
nombre varchar(30),
autor varchar(30),
editorial varchar (20),
costo decimal(5,2) unsigned,
cantidad int unsigned,
primary key(codigo)
);

261
Para cambiar el nombre del campo "costo" por "precio", tipeamos:

alter table libros


change costo precio decimal (5,2);

Si visualizamos la estructura de la tabla con "describe" vemos que el nombre del


campo se ha modificado.

Con "change" cambiamos el nombre de un campo y también podemos cambiar el


tipo y sus modificadores.

Para cambiar el nombre del campo "nombre" por "titulo" y redefinirlo como "not
null", tipeamos:

alter table libros


change nombre titulo varchar(40) not null;

Si visualizamos la estructura nueva:

describe libros;

vemos que el campo ahora tiene un nuevo nombre y no permite valores nulos.

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,
nombre varchar(30),
autor varchar(30),
editorial varchar (20),
costo decimal(5,2) unsigned,
cantidad int unsigned,
primary key(codigo)
);
describe libros;
alter table libros
change costo precio decimal (5,2);
alter table libros
change nombre titulo varchar(40) not null;
describe libros;

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.

2- Cree la tabla con la siguiente estructura:


create table articulos(
codigo int unsigned auto_increment,
nombre varchar(20) not null,
descripcion varchar(30),
precio decimal(4,2) unsigned,
primary key(codigo)
);

3- Ingrese los siguientes registros:


insert into articulos (nombre,descripcion,precio)
values('escuadra','plastico 20 cm.',3.50);
insert into articulos (nombre,descripcion,precio)
values('lápices colores','Faber x12',4.50);
insert into articulos (nombre,descripcion,precio)
values('lápices colores','Faber x24',7.50);
insert into articulos (nombre,descripcion,precio)
values('regla','30 cm.',2.50);
insert into articulos (nombre,descripcion,precio)
values('fibras','Faber x12',10.30);
insert into articulos (nombre,descripcion,precio)
values('fibras','Faber x6',5.10);

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:

alter table articulos


change precio preciopormayor decimal(4,2) unsigned not null;

5- También necesita alterar la tabla agregando un campo para almacenar el precio


por menor para cada artículo. Agrege un campo llamado "preciopormenor" que no
permita valores nulos:
alter table articulos
add preciopormenor decimal(4,2) unsigned not null;

6- Muestre todos los registros:


select * from articulos;
Note que para el nuevo campo los valores se setearon en "null".

7- Actualice el campo "preciopormenor" de todos los registros, dándole el valor del


campo "precio" incrementado en un 10%:
update articulos set preciopormenor=precio+(precio*0.10);

263
8- Muestre todos los registros:
select * from articulos;

Otros problemas:

Trabaje con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Cree la tabla con la siguiente estructura:


create table peliculas(
codigo int unsigned,
nombre varchar(40) not null,
actor varchar(20),
director varchar(25),
duracion tinyint unsigned
);

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;

5- Cambie el nombre del campo "duracion" por "minutos":


alter table peliculas
change duracion minutos tinyint unsigned;

53 - Agregar y eliminar la clave primaria (alter table)


Hasta ahora hemos aprendido a definir una clave primaria al momento de crear
una tabla. Con "alter table" podemos agregar una clave primaria a una tabla
existente.
Continuamos con nuestra tabla "libros", definida con la siguiente estructura:

- código, int unsigned auto_increment,


- titulo, varchar(40),
- autor, varchar(30),
- editorial, varchar (20),
- precio, decimal(5,2) unsigned,
- cantidad smallint unsigned.

264
Para agregar una clave primaria a una tabla existente usamos:

alter table libros


add primary key (codigo);

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.

Para que un campo agregado como clave primaria sea autoincrementable, es


necesario agregarlo como clave y luego redefinirlo con "modify" como
"auto_increment". No se puede agregar una clave y al mismo tiempo definir el
campo autoincrementable. Tampoco es posible definir un campo como
autoincrementable y luego agregarlo como clave porque para definir un campo
"auto_increment" éste debe ser clave primaria.

También usamos "alter table" para eliminar una clave primaria.

Para eliminar una clave primaria usamos:

alter table libros


drop primary key;

Con "alter table" y "drop primary key" eliminamos una clave primaria definida al
crear la tabla o agregada luego.

Si queremos eliminar la clave primaria establecida en un campo "auto_increment"


aparece un mensaje de error y la sentencia no se ejecuta porque si existe un
campo con este atributo DEBE ser clave primaria. Primero se debe modificar el
campo quitándole el atributo "auto_increment" y luego se podrá eliminar la clave.

Si intentamos establecer como clave primaria un campo que tiene valores


repetidos, aparece un mensaje de error y la operación no se realiza.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:

create table libros(


codigo int unsigned,
titulo varchar(40) not null,

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);

Visualicemos la estructura de la tabla:

describe libros;

Ahora el campo "codigo" es clave primaria.

Si intentamos agregar otra clave primaria, aparecerá un mensaje de error porque


(recuerde) una tabla solamente puede tener una clave primaria:

alter table libros


add primary key (titulo);

Si queremos que el campo clave sea "auto_increment" debemos modificarlo con:

alter table libros


modify codigo int unsigned auto_increment;

Si intentamos eliminar la clave primaria:

alter table libros


drop primary key;

la sentencia no se ejecuta porque si existe un campo con este atributo DEBE ser
clave primaria.

Primero debemos modificar el campo quitándole dicho atributo:

alter table libros


modify codigo int unsigned;

Ahora si podemos eliminar la clave primaria:

alter table libros


drop primary key;

Si visualizamos la estructura de la tabla:


describe libros;
vemos que la tabla ya no tiene 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:

Trabaje con la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe:


drop table if exists medicamentos;

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo int unsigned not null,
nombre varchar(20) not null,
laboratorio varchar(20),
precio decimal(6,2) unsigned
);

3- Visualice la estructura de la tabla "medicamentos".

4- Agregue una clave primaria por "codigo":


alter table medicamentos
add primary key (codigo);
La clave agregada, no es auto_increment, por ello, al agregar registros debemos
ingresar el código, si no lo hacemos, se almacenará el valor "0" en el primer
registro agregado:
insert into medicamentos (nombre, laboratorio,precio)
values('Sertal compuesto','Bayer',5.10);

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);

5- Para solucionar esto podemos modificar el campo convirtiéndolo en


autoincrementable:
alter table medicamentos
modify codigo int unsigned auto_increment;

6- Veamos los registros:


select * from medicamentos;
El código se alteró, ahora tiene el valor "1".

7- Ingrese más registros:


insert into medicamentos (nombre, laboratorio,precio)
values('Paracetamol 500','Bago',1.90);
insert into medicamentos (nombre, laboratorio,precio)
values('Bayaspirina','Bayer',2.10);

8- Intente eliminar la clave primaria:


alter table medicamentos
drop primary key;
Aparece un mensaje de error. La clave no se puede eliminar porque el campo
"codigo" es "auto_increment" y si existe un campo con este atributo DEBE ser
clave primaria.

9- Modifique el campo "codigo" quitándole el atributo "auto_increment":


alter table medicamentos
modify codigo int unsigned not null;

10- Elimine la clave primaria:


alter table medicamentos
drop primary key;

Otros problemas:

Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos".

1- Elimine la tabla "prestamos" si existe.

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'*/
);

3- Agregue una clave primaria compuesta por "codigo" y "fechaprestamo":


alter table prestamos
add primary key (codigo,fechaprestamo);

4- Intente agregar un registro con clave repetida.

5- Elimine la clave primaria:


alter table prestamos
drop primary key;

53 - Agregar y eliminar la clave primaria (alter table)


Hasta ahora hemos aprendido a definir una clave primaria al momento de crear
una tabla. Con "alter table" podemos agregar una clave primaria a una tabla
existente.

Continuamos con nuestra tabla "libros", definida con la siguiente estructura:

- código, int unsigned auto_increment,


- titulo, varchar(40),
- autor, varchar(30),
- editorial, varchar (20),
- precio, decimal(5,2) unsigned,
- cantidad smallint unsigned.

Para agregar una clave primaria a una tabla existente usamos:

alter table libros


add primary key (codigo);

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.

Para que un campo agregado como clave primaria sea autoincrementable, es


necesario agregarlo como clave y luego redefinirlo con "modify" como
"auto_increment". No se puede agregar una clave y al mismo tiempo definir el
campo autoincrementable. Tampoco es posible definir un campo como

269
autoincrementable y luego agregarlo como clave porque para definir un campo
"auto_increment" éste debe ser clave primaria.

También usamos "alter table" para eliminar una clave primaria.

Para eliminar una clave primaria usamos:

alter table libros


drop primary key;

Con "alter table" y "drop primary key" eliminamos una clave primaria definida al
crear la tabla o agregada luego.

Si queremos eliminar la clave primaria establecida en un campo "auto_increment"


aparece un mensaje de error y la sentencia no se ejecuta porque si existe un
campo con este atributo DEBE ser clave primaria. Primero se debe modificar el
campo quitándole el atributo "auto_increment" y luego se podrá eliminar la clave.

Si intentamos establecer como clave primaria un campo que tiene valores


repetidos, aparece un mensaje de error y la operación no se realiza.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:


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
);
Para establecer el campo "codigo" como clave primaria usamos:

alter table libros


add primary key (codigo);

Visualicemos la estructura de la tabla:


describe libros;

Ahora el campo "codigo" es clave primaria.

270
Si intentamos agregar otra clave primaria, aparecerá un mensaje de error porque
(recuerde) una tabla solamente puede tener una clave primaria:

alter table libros


add primary key (titulo);

Si queremos que el campo clave sea "auto_increment" debemos modificarlo con:

alter table libros


modify codigo int unsigned auto_increment;

Si intentamos eliminar la clave primaria:

alter table libros


drop primary key;

la sentencia no se ejecuta porque si existe un campo con este atributo DEBE ser
clave primaria.

Primero debemos modificar el campo quitándole dicho atributo:

alter table libros


modify codigo int unsigned;

Ahora si podemos eliminar la clave primaria:

alter table libros


drop primary key;

Si visualizamos la estructura de la tabla:

describe libros;

vemos que la tabla ya no tiene clave primaria.

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

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:

Trabaje con la tabla llamada "medicamentos" de una farmacia.

1- Elimine la tabla, si existe:


drop table if exists medicamentos;

2- Cree la tabla con la siguiente estructura:


create table medicamentos(
codigo int unsigned not null,
nombre varchar(20) not null,
laboratorio varchar(20),
precio decimal(6,2) unsigned
);

3- Visualice la estructura de la tabla "medicamentos".

4- Agregue una clave primaria por "codigo":


alter table medicamentos
add primary key (codigo);
La clave agregada, no es auto_increment, por ello, al agregar registros debemos
ingresar el código,
si no lo hacemos, se almacenará el valor "0" en el primer registro agregado:
insert into medicamentos (nombre, laboratorio,precio)
values('Sertal compuesto','Bayer',5.10);
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);

5- Para solucionar esto podemos modificar el campo convirtiéndolo en


autoincrementable:
alter table medicamentos
modify codigo int unsigned auto_increment;

6- Veamos los registros:


select * from medicamentos;

272
El código se alteró, ahora tiene el valor "1".

7- Ingrese más registros:


insert into medicamentos (nombre, laboratorio,precio)
values('Paracetamol 500','Bago',1.90);
insert into medicamentos (nombre, laboratorio,precio)
values('Bayaspirina','Bayer',2.10);

8- Intente eliminar la clave primaria:


alter table medicamentos
drop primary key;
Aparece un mensaje de error. La clave no se puede eliminar porque el campo
"codigo" es "auto_increment" y si existe un campo con este atributo DEBE ser
clave primaria.

9- Modifique el campo "codigo" quitándole el atributo "auto_increment":


alter table medicamentos
modify codigo int unsigned not null;

10- Elimine la clave primaria:


alter table medicamentos
drop primary key;

Otros problemas:
Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla
llamada "prestamos".

1- Elimine la tabla "prestamos" si existe.

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);

4- Intente agregar un registro con clave repetida.

5- Elimine la clave primaria:


alter table prestamos
drop primary key;

273
54 - Agregar índices(alter table - add index)

Aprendimos a crear índices al momento de crear una tabla. También a crearlos


luego de haber creado la tabla, con "create index". También podemos agregarlos a
una tabla usando "alter table".

Creamos la tabla "libros":


create table libros(
codigo int unsigned,
titulo varchar(40),
autor varchar(30),
editorial varchar (20),
precio decimal(5,2) unsigned,
cantidad smallint unsigned
);
Para agregar un índice común por el campo "editorial" usamos la siguiente
sentencia:
alter table libros
add index i_editorial (editorial);

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á.

En ambos casos, para índices comunes o únicos, si no colocamos nombre de


índice, se coloca uno por defecto, como cuando los creamos junto con la tabla.

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla si existe.

Creamos la tabla "libros" con la siguiente estructura:

create table libros(


codigo int unsigned,
titulo varchar(40),
autor varchar(30),

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);

Visualicemos los índices con:


show index from libros;

Aparecen nuestros 2 índices agregados.

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,
cantidad smallint unsigned
);
alter table libros
add index i_editorial (editorial);
alter table libros
add unique index i_tituloeditorial (titulo,editorial);
show index from libros;

Problema:

Trabaje con la tabla "alumnos" en el cual un instituto de enseñanza guarda los


datos de sus alumnos.

1- Elimine la tabla "alumnos" si existe.

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);

6- Visualice los índices:


show index from alumnos;

Otros problemas:

Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".

1- Elimine la tabla si existe.

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);

4- Hay 2 campos por los cuales podemos realizar consultas frecuentemente:


"medico" y "obrasocial", cree índices comunes para esos campos:
alter table consultas
add index i_medico (medico);
alter table consultas
add index i_obrasocial (obrasocial);

5- Vea los índices.

276
55 - Borrado de índices (alter table - drop index)

Los índices común y únicos se eliminan con "alter table".

Trabajamos con la tabla "libros" de una librería, que tiene los siguientes campos e
índices:

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)
);

Para eliminar un índice usamos la siguiente sintaxis:

alter table libros


drop index i_editorial;

Usamos "alter table" y "drop index" seguido del nombre del índice a borrar.

Para eliminar un índice único usamos la misma sintaxis:

alter table libros


drop index i_tituloeditorial;

Ejemplo:
Trabajamos con la tabla "libros" de una librería.

Eliminamos la tabla "libros" si existe.

Creamos la tabla "libros", con los siguientes campos e índices:

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)
);

277
Para eliminar el índice común llamado "i_editorial" usamos la siguiente sintaxis:
alter table libros
drop index i_editorial;

Para eliminar el índice único llamado "i_tituloeditodrop table if exists libros;

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)
);

alter table libros


drop index i_editorial;

alter table libros


drop index i_tituloeditorial;

show index from libros;rial" usamos la misma sintaxis:


alter table libros
drop index i_tituloeditorial;

Visualicemos los índices de la tabla:


show index from libros;

vemos que solamente queda el índice "PRIMARY", este índice no se puede


eliminar; se elimina automáticamente al eliminar la clave primaria.

drop table if exists libros;


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)
);
alter table libros
drop index i_editorial;
alter table libros
drop index i_tituloeditorial;
show index from libros;

278
Problema:

Trabajamos con la tabla "alumnos" en la cual un instituto de enseñanza guarda los


datos de sus alumnos.

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla con los siguientes índices:


create table alumnos(
año year not null,
numero int unsigned not null,
nombre varchar(30),
documento char(8) not null,
domicilio varchar(30),
ciudad varchar(20),
provincia varchar(20),
primary key(año,numero),
unique i_documento (documento),
index i_ciudadprovincia (ciudad,provincia),
);
3- Vea los índices de la tabla.

4- Elimine el índice único:


alter table alumnos
drop index i_documento;

5- Elimine el índice común:


alter table alumnos
drop index i_ciudadprovincia;

6- Vea los índices:


show index from alumnos;

Otros problemas:

Una clínica registra las consultas de los pacientes en una tabla llamada
"consultas".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table consultas(
fecha date,
numero int unsigned,
documento char(8) not null,
obrasocial varchar(30),
medico varchar(30),

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.

4- Elimine el índice único:


alter table consultas
drop index i_consulta;

5- Elimine los índices comumes:


alter table consultas
drop index i_medico;
alter table consultas
drop index i_obrasocial;

6- Vea los índices:


show index from consultas;

56 - renombrar tablas (alter table - rename - rename table)


Podemos cambiar el nombre de una tabla con "alter table".

Para cambiar el nombre de una tabla llamada "amigos" por "contactos" usamos
esta sintaxis:

alter table amigos rename contactos;

Entonces usamos "alter table" seguido del nombre actual, "rename" y el nuevo
nombre.

También podemos cambiar el nombre a una tabla usando la siguiente sintaxis:

rename table amigos to contactos;

La renombración se hace de izquierda a derecha, con lo cual, si queremos


intercambiar los nombres de dos tablas, debemos tipear lo siguiente:

rename table amigos to auxiliar,


contactos to amigos,
auxiliar to contactos;

280
Ejemplo:
Eliminamos las tablas "amigos" y "contactos" si existen.

Creamos la tabla "amigos" con la siguiente estructura:


create table amigos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
Para cambiar el nombre de nuestra tabla "amigos" por "contactos" usamos esta
sintaxis:
alter table amigos rename contactos;

Veamos si existen las tablas "amigos" y "contactos":


show tables;

La tabla "amigos" ya no existe, si "contactos".

También podemos cambiar el nombre a una tabla usando la siguiente sintaxis:


rename table contactos to amigos;

Así cambiamos el nombre de la tabla "contactos" por "amigos".

Veamos si existen las tablas "amigos" y "contactos":


show tables;

La tabla "contactos" ya no existe, si "amigos".

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.

Elimine las tablas "amigos" y "contactos" si existen.

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:

insert into contactos (nombre,telefono)


values('Juancito','4565657');
insert into contactos (nombre,telefono)
values('patricia','4223344');

insert into amigos (nombre,telefono)


values('Perez Luis','4565657');
insert into amigos (nombre,telefono)
values('Lopez','4223344');

Para intercambiar los nombres de estas dos tablas, debemos tipear lo siguiente:
rename table amigos to auxiliar,
contactos to amigos,
auxiliar to contactos;

Verifiquemos el cambio de nombre:


select * from amigos;
select * from contactos;

drop table if exists amigos;


drop table if exists contactos;
create table amigos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
alter table amigos rename contactos;
show tables;
rename table contactos to amigos;
show tables;
drop table if exists amigos;
drop table if exists contactos;
create table amigos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
create table contactos(
nombre varchar(30),
domicilio varchar(30),
telefono varchar (11)
);
insert into contactos (nombre,telefono)
values('Juancito','4565657');
insert into contactos (nombre,telefono)
values('patricia','4223344');
insert into amigos (nombre,telefono)
values('Perez Luis','4565657');
insert into amigos (nombre,telefono)

282
values('Lopez','4223344');
rename table amigos to auxiliar,
contactos to amigos,
auxiliar to contactos;
select * from amigos;
select * from contactos;

Problema:

Trabajamos con la tabla "peliculas" de un video club.

1- Elimine la tabla, si existe.

2- Cree la tabla "peliculas":


create table peliculas(
codigo int unsigned auto_increment,
titulo varchar(40),
duracion tinyint unsigned
);

3- Cambie el nombre de la tabla por "films" con "alter table":


alter table peliculas rename films;

4- Vea si existen las tablas "peliculas" y "films":


show tables;

5- Cambie nuevamente el nombre, de la tabla "films" por "peliculas" usando


"rename":
rename table films to peliculas;

6- vea si existen las tablas:


show tables;

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".

1- Elimine ambas tablas si existen.

2- Cree las tablas dándoles el nombre equivocado, es decir, de el nombre


"clientes" a la tabla que contiene los datos de los empleados y el nombre
"empleados" a la tabla con la informaciómn de los clientes:
create table clientes(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),

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;

4- Intercambie los nombres de las dos tablas:


rename table clientes to auxiliar,
empleados to clientes,
auxiliar to empleados;

5- Verifique el cambio de nombre:


describe clientes;
describe empleados;

6- Vea si existe la tabla "auxiliar":


show tables;

57 - Tipo de dato enum.


Además de los tipos de datos ya conocidos, existen otros que analizaremos ahora,
los tipos "enum" y "set".

El tipo de dato "enum" representa una enumeración. Puede tener un máximo de


65535 valores distintos. Es una cadena cuyo valor se elige de una lista enumerada
de valores permitidos que se especifica al definir el campo. Puede ser una cadena
vacía, incluso "null".

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)
);

Los valores presentados deben ser cadenas de caracteres.

Si un "enum" permite valores nulos, el valor por defecto el "null"; si no permite


valores nulos, el valor por defecto es el primer valor de la lista de permitidos.

Si se ingresa un valor numérico, lo interpreta como índice de la enumeración y


almacena el valor de la lista con dicho número de índice. Por ejemplo:

insert into postulantes (documento,nombre,estudios)


values('22255265','Juana Pereyra',5);

En el campo "estudios" almacenará "universitario" que es valor de índice 5.

Si se ingresa un valor inválido, puede ser un valor no presente en la lista o un


valor de índice fuera de rango, coloca una cadena vacía. Por ejemplo:

insert into postulantes (documento,nombre,estudios)


values('22255265','Juana Pereyra',0);
insert into postulantes (documento,nombre,estudios)
values('22255265','Juana Pereyra',6);
insert into postulantes (documento,nombre,estudios)
values('22255265','Juana Pereyra','PostGrado');

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í:

select * from postulantes


where estudios=0;

El índice de un valor "null" es "null".

285
Para seleccionar registros con un valor específico de un campo enumerado
usamos "where", por ejemplo, queremos todos los postulantes con estudios
universitarios:

select * from postulantes


where estudios='universitario';

Los tipos "enum" aceptan cláusula "default".

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.

Eliminamos la tabla "postulantes", si existe.

Creamos la siguiente tabla definiendo un campo de tipo "enum":


create table postulantes(
numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
sexo char(1),
estudios enum('ninguno','primario','secundario', 'terciario','universitario') not null,
primary key(numero)
);
Ingresamos algunos registros:
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');

Ingresamos un registro sin especificar valor para "estudios", guardará el valor por
defecto:

insert into postulantes (documento,nombre,sexo)


values('24333444','Luis Lopez','m');

286
Vemos el registro ingresado:
select * from postulantes;

En el campo "estudios" se guardó el valor por defecto, el primer valor de la lista


enumerada.

Si ingresamos un valor numérico, lo interpreta como índice de la enumeración y


almacena el valor de la lista con dicho número de índice. Por ejemplo:
insert into postulantes (documento,nombre,sexo,estudios)
values('2455566','Juana Pereyra','f',5);

En el campo "estudios" almacenará "universitario" que es valor de índice 5.

Si ingresamos un valor no presente en la lista, coloca una cadena vacía. Por


ejemplo:
insert into postulantes (documento,nombre,sexo,estudios)
values('24678907','Pedro Perez','m','Post Grado');

Si ingresamos un valor de índice fuera de rango, almacena una cadena vacía:


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);

La cadena vacía ingresada como resultado de ingresar un valor incorrecto tiene el


valor de índice 0; entonces, podemos seleccionar los registros con valores
inválidos en el campo de tipo "enum" así:
select * from postulantes
where estudios=0;

Queremos seleccionar los postulantes con estudios universitarios:


select * from postulantes
where estudios='universitario';

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);

drop table if exists postulantes;


create table postulantes(
numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
sexo char(1),
estudios enum('ninguno','primario','secundario', 'terciario','universitario') not null,
primary key(numero)
);

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:

Trabajamos con la tabla "empleados" de una empresa.

1- Elimine la tabla empleados, si existe.

2- Cree la tabla con la siguiente estructura:


create table empleados(
documento char(8),
nombre varchar(30),
sexo char(1),
estadocivil enum('soltero','casado','divorciado','viudo') not null,
sueldobasico decimal(6,2),
primary key(documento)
);
3- Ingrese algunos registros:
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('22333444','Juan Lopez','m','soltero',300);
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('23333444','Ana Acosta','f','viudo',400);

4- Intente ingresar un valor "null" para el campo enumerado:


insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('25333444','Ana Acosta','f',null,400);

5- Ingrese resgistros con valores de índice para el campo "estadocivil":


insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)

288
values ('26333444','Luis Perez','m',1,400);
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('26336444','Marcelo Torres','m',3,460);

6- Ingrese un valor inválido, uno no presente en la lista y un valor de índice fuera


de rango (guarda una cadena vacía):
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('29333444','Lucas Perez','m',0,400);
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('30336444','Federico Garcia','m',5,450);
insert into empleados (documento,nombre,sexo,estadocivil,sueldobasico)
values ('31333444','Karina Sosa','f','Concubino',500);

7- Seleccione todos los empleados solteros:


select * from empleados
where estadocivil='soltero';

8- Seleccione todos los empleados viudos usando el número de índice de la


enumeración:
select * from empleados
where estadocivil=4;

Otros problemas:

A) Una empresa de turismo vende paquetes de viajes y almacena la información


referente a los mismos en una tabla llamada "viajes":

1- Elimine la tabla si existe.

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');

6- Ingrese valor nulo para el campo "hotel"


insert into viajes (nombre,pension,hotel,dias,salida)
values ('Mexico especial','media',3,18,'2005-11-01');

7- Ingrese un valor inválido, no presente en la lista de "pension" (guarda una


cadena vacía):
insert into viajes (nombre,pension,hotel,dias,salida)
values ('Caribe especial','ninguna','4',18,'2005-11-01');

8- Ingrese un valor de índice fuera de rango para el campo "hotel":


insert into viajes (nombre,pension,hotel,dias,salida)
values ('Venezuela única','no',6,18,'2005-11-01');

9- Seleccione todos los viajes que incluyen media pensión:


select * from viajes
where pension=2;

10- Seleccione todos los viajes que incluyen un hotel de 4 estrellas:


select * from viajes
where hotel='4';

B) Una inmobiliaria vende inmuebles; los inmuebles pueden ser: casa,


departamento, local o terreno.

1- Elimine la tabla "inmuebles" si existe.

2- Cree la tabla "inmuebles" para registrar la siguiente información:


- tipo de inmueble: tipo enum (casa,dpto,local,terreno), not null,
- domicilio: varchar(30),
- propietario: nombre del dueño,
- precio: decimal hasta $999999.99 positivo.

3- Ingrese algunos registros.

4- Seleccione el domicilio y precio de todos los departamentos en alquiler.

5- Seleccione el domicilio, propietario y precio de todos los locales en venta.

6- Seleccione el domicilio y precio de todas las casas disponibles.

290
58 - Tipo de dato set.

El tipo de dato "set" representa un conjunto de cadenas.

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.

Es similar al tipo "enum" excepto que puede almacenar más de un valor en el


campo.

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 definir un campo de tipo "set" usamos la siguiente sintaxis:

create table postulantes(


numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
idioma set('ingles','italiano','portuges'),
primary key(numero)
);
Ingresamos un registro:

insert into postulantes (documento,nombre,idioma)


values('22555444','Ana Acosta','ingles');

Para ingresar un valor que contenga más de un elemento del conjunto, se separan
por comas, por ejemplo:

insert into postulantes (documento,nombre,idioma)


values('23555444','Juana Pereyra','ingles,italiano');

No importa el orden en el que se inserten, se almacenan en el orden que han sido


definidos, por ejemplo, si ingresamos:

insert into postulantes (documento,nombre,idioma)


values('23555444','Juana Pereyra','italiano,ingles');

en el campo "idioma" guardará 'ingles,italiano'.

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:

insert into postulantes (documento,nombre,idioma)


values('23555444','Juana Pereyra','italiano,ingles,italiano');
en el campo "idioma" guardará 'ingles,italiano'.

Si ingresamos un valor que no está en la lista "set", se ignora y se almacena una


cadena vacía, por ejemplo:

insert into postulantes (documento,nombre,idioma)


values('22255265','Juana Pereyra','frances');

Si un "set" permite valores nulos, el valor por defecto es "null"; si no permite


valores nulos, el valor por defecto es una cadena vacía.

Si se ingresa un valor de índice fuera de rango, coloca una cadena vacía. Por
ejemplo:

insert into postulantes (documento,nombre,idioma)


values('22255265','Juana Pereyra',0);
insert into postulantes (documento,nombre,idioma)
values('22255265','Juana Pereyra',8);

Si se ingresa un valor numérico, lo interpreta como índice de la enumeración y


almacena el valor de la lista con dicho número de índice. Los valores de índice se
definen en el siguiente orden, en este ejemplo:

1='ingles',
2='italiano',
3='ingles,italiano',
4='portugues',
5='ingles,portugues',
6='italiano,portugues',
7='ingles,italiano,portugues'.

Ingresamos algunos registros con valores de índice:

insert into postulantes (documento,nombre,idioma)


values('22255265','Juana Pereyra',2);
insert into postulantes (documento,nombre,idioma)
values('22555888','Juana Pereyra',3);

En el campo "idioma", con la primera inserción se almacenará "italiano" que es


valor de índice 2 y con la segunda inserción, "ingles,italiano" que es el valor con
índice 3.

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:

select * from postulantes


where idioma like '%ingles%';
select * from postulantes
where find_in_set('ingles',idioma)>0;

La función "find_in_set()" retorna 0 si el primer argumento (cadena) no se


encuentra en el campo set colocado como segundo argumento. Esta función no
funciona correctamente si el primer argumento contiene una coma.

Para recuperar todos los valores que incluyan "ingles,italiano" tipeamos:

select * from postulantes


where idioma like '%ingles,italiano%';

Para realizar búsquedas, es importante respetar el orden en que se presentaron


los valores en la definición del campo; por ejemplo, si se busca el valor
"italiano,ingles" en lugar de "ingles,italiano", no retornará registros.

Para buscar registros que contengan sólo el primer miembro del conjunto "set"
usamos:

select * from postulantes


where idioma='ingles';

También podemos buscar por el número de índice:

select * from postulantes


where idioma=1;

Para buscar los registros que contengan el valor "ingles,italiano" podemos utilizar
cualquiera de las siguientes sentencias:

select * from postulantes


where idioma='ingles,italiano';
select * from postulantes
where idioma=3;

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 tipos "set" admiten cláusula "default".

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.

Eliminamos la tabla, si existe.

Creamos la tabla definiendo un campo de tipo "set" usando la siguiente sintaxis:


create table postulantes(
numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
idioma set('ingles','italiano','portuges'),
primary key(numero)
);
Ingresamos un registro:
insert into postulantes (documento,nombre,idioma)
values('22555444','Ana Acosta','ingles');

Ingresamos un valor que contiene 2 elementos del conjunto:


insert into postulantes (documento,nombre,idioma)
values('23555444','Juana Pereyra','ingles,italiano');

Recuerde que no importa el orden en el que se inserten, se almacenan en el orden


que han sido definidos:
insert into postulantes (documento,nombre,idioma)
values('25555444','Andrea Garcia','italiano,ingles');

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:
insert into postulantes (documento,nombre,idioma)
values('27555444','Diego Morales','italiano,ingles,italiano');

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);

Si un "set" permite valores nulos, el valor por defecto el "null":


insert into postulantes (documento,nombre)
values('28555464','Ines Figueroa');

Ingresemos un registro con el valor "ingles,italiano,portugues" para el campo


"idioma" con su núméro de índice):
insert into postulantes (documento,nombre,idioma)
values('29255265','Esteban Juarez',7);

Busquemos valores de campos "set" utilizando el operador "like". Recuperemos


todos los valores que contengan la cadena "ingles":
select * from postulantes
where idioma like '%ingles%';

Para recuperar todos los valores que incluyen "ingles,italiano", tipeamos:


select * from postulantes
where idioma like '%ingles,italiano%';

Recuerde que para las búsquedas, es importante respetar el orden en que se


presentaron los valores en la definición del campo; intentemos buscar el valor
"italiano,ingles" en lugar de "ingles,italiano", no retornará registros:
select * from postulantes
where idioma like '%italiano,ingles%';

Busquemos valores de campos "set" utilizando la función "find_in_set()".


Recuperemos todos los postulantes que sepan inglés:
select * from postulantes
where find_in_set('ingles',idioma)>0;

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 buscar los registros que contengan el valor "ingles,italiano,portugues"


podemos utilizar:
select * from postulantes
where idioma=7;

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;

drop table if exists postulantes;


create table postulantes(
numero int unsigned auto_increment,
documento char(8),
nombre varchar(30),
idioma set('ingles','italiano','portuges'),
primary key(numero)
);
insert into postulantes (documento,nombre,idioma)
values('22555444','Ana Acosta','ingles');
insert into postulantes (documento,nombre,idioma)
values('23555444','Juana Pereyra','ingles,italiano');
insert into postulantes (documento,nombre,idioma)
values('25555444','Andrea Garcia','italiano,ingles');
insert into postulantes (documento,nombre,idioma)
values('27555444','Diego Morales','italiano,ingles,italiano');
insert into postulantes (documento,nombre,idioma)
values('27555464','Diana Herrero','frances');
insert into postulantes (documento,nombre,idioma)
values('28255265','Pedro Perez',0);
insert into postulantes (documento,nombre,idioma)
values('22255260','Nicolas Duarte',8);
insert into postulantes (documento,nombre)
values('28555464','Ines Figueroa');
insert into postulantes (documento,nombre,idioma)
values('29255265','Esteban Juarez',7);
select * from postulantes
where idioma like '%ingles%';
select * from postulantes
where idioma like '%ingles,italiano%';

select * from postulantes


where idioma like '%italiano,ingles%';
select * from postulantes
where find_in_set('ingles',idioma)>0;
select * from postulantes
where idioma='ingles';

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:

Una academia de enseñanza dicta distintos cursos de informática. Los cursos se


dictan por la mañana (de 8 a 12 hs.) o por la tarde (de 16 a 20 hs.), distintos días a
la semana. La academia guarda los datos de los cursos en una tabla llamada
"cursos" en la cual almacena el código del curso, el tema, los días de la semana
que se dicta, el horario, por la mañana (AM) o por la tarde (PM), la cantidad
de clases que incluye cada curso (clases), la fecha de inicio y el costo del curso.

1- Elimine la tabla "cursos", si existe.

2- Cree la tabla "cursos" con la siguiente estructura:


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 default 1,
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);

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);

4- Una persona quiere inscribirse en un curso de "PHP" y sólo tiene disponibles


los sábados. Localice los cursos de "PHP" que se dictan solamente los sábados:
select * from cursos
where tema like '%PHP%' and
dias='sabado';

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:

A) Trabaje con la tabla "inmuebles" en la cual una inmobiliaria almacena la


información referente a sus departamentos en venta.

1- Elimine la tabla "inmuebles" si existe.

2- Cree la tabla "inmuebles":


create table inmuebles(
detalles set ('estacionamiento','terraza','pileta','patio','ascensor'),
domicilio varchar(30),
propietario varchar(30),
precio decimal (9,2) unsigned
);

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);

4- Seleccione todos los datos de los departamentos con terraza:


select * from inmuebles
where find_in_set('terraza',detalles)>0;

5- Seleccione los departamentos que no tiene ascensor:


select * from inmuebles
where detalles not like '%ascensor%';

6- Muestre los inmuebles que tengan terraza y pileta solamente:


select *from inmuebles
where detalles='terraza,pileta';

7- Muestre los inmuebles que no tengan ascensor y si estacionamiento, además


de otros detalles:
select * from inmuebles
where detalles not like '%ascensor%' and
detalles like '%estacionamiento%';

8- Ingrese un registro con valor inexistente en "detalles":


insert into inmuebles (detalles,precio)
values('gimnasio',90000);

9 Ingrese un registro sin valor para "detalles":


insert into inmuebles (domicilio,precio)
values('Colon 354',90000);

B) Una empresa de turismo vende paquetes de viajes a México y almacena la


información referente a los mismos en una tabla llamada "viajes":

1- Elimine la tabla si existe.

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');

4- Ingrese un registro sin valor para el campo "ciudades":


insert into viajes (nombre,pension,dias,salida)
values ('Mexico maravilloso','completa',5,'2005-10-25');

5- Seleccione todos los viajes que incluyan "Acapulco":


select * from viajes
where find_in_set('acapulco',ciudades)>0;

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';

7- Muestre los viajes que incluyan "Puerto Vallarta" o "Cuernavaca":


select * from viajes
where find_in_set('Cuernavaca',ciudades)>0 or
find_in_set('Puerto Vallarta',ciudades)>0;

300
59 - Tipos de datos blob y text.

Los tipos "blob" o "text" son bloques de datos. Tienen una longitud de 65535
caracteres.

Un "blob" (Binary Large Object) puede almacenar un volumen variable de datos.


La diferencia entre "blob" y "text" es que "text" diferencia mayúsculas y minúsculas
y "blob" no; esto es porque "text" almacena cadenas de caracteres no binarias
(caracteres), en cambio "blob" contiene cadenas de caracteres binarias (de bytes).

No permiten valores "default".

Existen subtipos:

- tinyblob o tinytext: longitud máxima de 255 caracteres.

- mediumblob o mediumtext: longitud de 16777215 caracteres.

- longblob o longtext: longitud para 4294967295 caracteres.

Se utiliza este tipo de datos cuando se necesita almacenar imágenes, sonidos o


textos muy largos.

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.

La tabla contiene un campo de tipo "text" llamado "sinopsis":

- codigo: int unsigned auto_increment, clave primaria,


- nombre: varchar(40),
- actor: varchar(30),
- duracion: tinyint unsigned,
- sinopsis: text,

Se ingresan los datos en un campo "text" o "blob" como si fuera de tipo cadena de
caracteres, es decir, entre comillas:

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');

Para buscar un texto en un campo de este tipo usamos "like":


select * from peliculas
where sinopsis like '%Drama%';

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.

Eliminamos la tabla si existe:


drop table if exists peliculas;

Creamos la tabla con un campo de tipo "text" llamado "sinopsis":


create table peliculas(
codigo int unsigned auto_increment,
nombre varchar(40),
actor varchar(30),
duracion tinyint unsigned,
sinopsis text,
primary key (codigo)
);
Ingresamos algunos registros:
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(2,'Charlie y la fábrica de chocolate','J. Deep',120,


'Un niño llamado Charlie tiene la ilusión de encontrar uno de los 5 tickets del
concurso para entrar a la fabulosa fábrica de chocolates del excéntrico Willy
Wonka y descubrir el misterio de sus golosinas. Aventuras');

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');

Para buscar todas las películas que en su campo "sinopsis" contengan el texto
"Drama" usamos "like":

select * from peliculas


where sinopsis like '%Drama%';

Podemos buscar la película que incluya en su sinopsis el texto "chocolates":

select * from peliculas


where sinopsis like '%chocolates%';

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(2,'Charlie y la fábrica de chocolate','J. Deep',120, 'Un niño


llamadoCharlie tiene la ilusión de encontrar uno de los 5 tickets del concurso para entrar a la
fabulosa fábrica de chocolates del excéntrico Willy Wonka y descubrir el misterio de sus golosinas.
Aventuras');

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');

select * from peliculas


where sinopsis like '%Drama%';

select * from peliculas


where sinopsis like '%chocolates%';

Problema:

Una inmobiliaria guarda los datos de sus inmuebles en venta en una tabla llamada
"inmuebles".

1- Elimine la tabla si existe:


drop table if exists 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');

4- Busque todos los inmuebles que tengan "patio":


select * from inmuebles
where detalles like '%patio%';

Otros problemas:

Una librería guarda la información de sus libros en una tabla llamada "libros".

1- Elimine la tabla si existe:


drop table if exists 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)
);

3- Ingrese algunos registros.:


insert into libros values(1,'Aprenda PHP','Mario Molina','Emece',
'Instalacion de PHP.
Palabras reservadas.
Sentencias basicas.
Definicion de variables.',
45.6);

insert into libros values(2,'Java en 10 minutos','Mario Molina','Planeta',


'Instalacion de Java en Windows.
Instalacion de Java en Linux.
Palabras reservadas.
Sentencias basicas.
Definir variables.', 55);

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%';

5- Busque los libros de "Java" que incluyan el tema "Instalacion" o "Instalar":


select * from libros
where titulo like '%Java%' and
temas like '%Instalacion%' or '%Instalar%';

60 - Funciones de control de flujo (if)


Trabajamos con las tablas "libros" de una librería.

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;

select titulo from libros


where precio >=50;

En la primera sentencia mostramos los libros con precio menor a 50 y en la


segunda los demás.

También podemos usar la función "if".

"if" es una función a la cual se le envían 3 argumentos: el segundo y tercer


argumento corresponden a los valores que retornará en caso que el primer
argumento (una expresión de comparación) sea "verdadero" o "falso"; es decir, si
el primer argumento es verdadero, retorna el segundo argumento, sino retorna el
tercero.

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").

Veamos otros ejemplos.

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;

Si la cantidad de libros de cada autor es mayor a 1 (primer argumento del "if"),


coloca "Más de 1" (segundo argumento del "if"), en caso contrario coloca "1"
(tercer argumento del "if").

Queremos saber si la cantidad de libros por editorial supera los 4 o no:

select editorial,
if (count(*)>4,'5 o más','menos de 5') as cantidad
from libros
group by editorial
order by cantidad;

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").

306
Ejemplo:
Trabajamos con las tablas "libros" de una librería.

Eliminamos la tabla, si existe.

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;

select titulo from libros


where precio >=50;

En la primera sentencia mostramos los libros con precio menor a 50 y en la


segunda los demás.

Usamos la función "if":


select titulo,
if (precio>50,'caro','economico')
from libros;

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;

Si la cantidad de libros de cada autor es mayor a 1 (primer argumento del "if"),


coloca "Más de 1" (segundo argumento del "if"), en caso contrario coloca "1"
(tercer argumento del "if").

Podemos ordenar por la columna del "if":

select autor,
if (count(*)>1,'Más de 1','1') as cantidad
from libros
group by autor
order by cantidad;

Para saber si la cantidad de libros por editorial supera los 4 o es menor:


select editorial,
if (count(*)>4,'5 o más','menos de 5') as cantidad
from libros
group by editorial
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".

1- Elimine la tabla "empleados" si existe:


drop table if exists 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;

5- Además, si el empleado cumple 10,20,30,40... años de servicio, se le regala


una placa recordatoria. La secretaria de Gerencia necesita saber la cantidad de
años de servicio que cumplen los empleados que ingresaron en el mes de abril
para encargar dichas placas:
select nombre,fechaingreso,
year(current_date)-year(fechaingreso) as 'Años de servicio',
if ( (year(current_date)-year(fechaingreso)) %10=0,'Si','No') as 'Placa'
from empleados
where month(fechaingreso)=4;

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:

A) La empresa que provee de luz a los usuarios de un municipio, almacena en una


tabla algunos datos
de los usuarios y el monto a cobrar:
- documento,
- domicilio,
- monto a pagar,
- fecha de vencimiento.
Si la boleta no se paga hasta el día del vencimiento, inclusive, se incrementa al
monto, un 1% del
monto cada día de atraso.

1- Elimine la tabla "luz", si existe.

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).

4- Ingrese para el mismo usuario (igual documento) 2 boletas vencidas.

5- Muestre el documento del usuario, la fecha de vencimiento, la fecha actual (en


que efectúa el pago) y si debe pagar recargo o no.:
select documento,vencimiento,
current_date as 'Fecha actual',
monto,
if (datediff(current_date,vencimiento)>0,'Si','No') as vencida
from luz;

La función "datediff()" retorna la cantidad de días de diferencia entre las fecha


enviadas como argumento, si el primer argumento es anterior al segundo, el valor
retornado es negativo, por ello, colocamos como condición que el valor retornado
por esta función sea mayor a cero, es decir, que la fecha actual sea posterior a la
del vencimiento, así las vencidas mostrarán "Si" y las que no hayan
vencido "No".

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;

B) Un profesor guarda los promedios de sus alumnos de un curso en una tabla


llamada "alumnos".

1- Elimine la tabla si existe.

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);

4- Si el alumno tiene un promedio superior o igual a 4, muestre un mensaje


"aprobado" en caso contrario "reprobado":
select legajo,promedio,
if (promedio>=4,'aprobado','reprobado')
from alumnos;

5- Es política del profesor entregar una medalla a quienes tengan un promedio


igual o superior a 9.
Muestre los nombres y promedios de los alumnos y un mensaje "medalla" a
quienes cumplan con ese
requisito:
select nombre,promedio,
if (promedio>=9,'medalla','')
from alumnos;

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');

4- Muestre la patente, la hora de llegada y de salida de todos los vehículos, más


una columna que calcule la cantidad de horas que estuvo cada vehículo en la
playa, sin considerar los que aún no se retiraron de la playa:
select patente,horallegada,horasalida,
left(timediff(horasalida,horallegada),5) as horasminutos
from vehiculos
where horasalida is not null;

5- Se cobra 1 peso por hora. Pero si un vehículo permanece en la playa 4 horas,


se le cobran 3
pesos, es decir, no se le cobra la cuarta hora; si está 8 horas, se cobran 6 pesos, y
así sucesivamente. Muestre la patente, la hora de llegada y de salida de todos los
vehículos, más la columna que calcule la cantidad de horas que estuvo cada
vehículo en la playa (sin considerar los que aún no se retiraron de la playa) y otra
columna utilizando "if" que muestre la cantidad de horas gratis:
select patente,horallegada,horasalida,
left(timediff(horasalida,horallegada),5) as horasminutos,
if (hour(timediff(horasalida,horallegada))>4,
hour(timediff(horasalida,horallegada)) div 4,0) as horagratis
from vehiculos
where horasalida is not null;

314
D) Un teatro con varias salas guarda la información de las entradas vendidas en
una tabla llamada "entradas".

1- Elimine la tabla, si existe.

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.

Trabajemos con la tabla "libros" de una librería.

Queremos saber si la cantidad de libros de cada editorial es menor o mayor a 1,


tipeamos:

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;

Por cada valor hay un "when" y un "then"; si encuentra un valor coincidente en


algún "where" ejecuta el "then" correspondiente a ese "where", si no encuentra
ninguna coincidencia, se ejecuta el "else", si no hay parte "else" retorna "null".
Finalmente se coloca "end" para indicar que el "case" ha finalizado.

Entonces, la sintaxis es:

case
when then
...
else end

Se puede obviar la parte "else":

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;

La diferencia con "if" es que el "case" toma valores puntuales, no expresiones. La


siguiente sentencia provocará un error:

select editorial,
case count(*)
when 1 then 1
when >1 then 'mas de 1'
end as 'cantidad'
from libros
group by editorial;

Pero existe otra sintaxis de "case" que permite condiciones:

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.

Eliminamos la tabla si existe:


drop table if exists libros;

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);

Queremos saber si la cantidad de libros de cada editorial es menor o mayor a 1


empleando "case":
select editorial,
case count(*)
when 1 then 1

318
else 'mas de 1' end as 'cantidad'
from libros
group by editorial;

Por cada valor hay un "when" y un "then"; si encuentra un valor coincidente en


algún "where" ejecuta el "then" correspondiente a ese "where", si no encuentra
ninguna coincidencia, se ejecuta el "else", si no hay parte "else" retorna "null".
Finalmente se coloca "end" para indicar que el "case" ha finalizado. Veamos un
ejemplo sin parte "else":
select editorial,
case count(*)
when 1 then 1
end as 'cantidad'
from libros
group by editorial;

Extendamos el "case" para mostrar distintos mensajes comparando más de 2


valores:
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;

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;

"case" toma valores puntuales, no expresiones. Intentemos lo siguiente:


select editorial,
case count(*)
when 1 then 1
when >1 then 'mas de 1'
end as 'cantidad'
from libros
group by editorial;

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;

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,
cantidad smallint unsigned,
primary key(codigo)
);
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);
select editorial,
case count(*)
when 1 then 1
else 'mas de 1' end as 'cantidad'
from libros
group by editorial;
select editorial,
case count(*)
when 1 then 1
end as 'cantidad'
from libros
group by editorial;
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;

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:

Un profesor guarda los promedios de sus alumnos de un curso en una tabla


llamada "alumnos".

1- Elimine la tabla si existe.

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);

4- Si el alumno tiene un promedio menor a 4, muestre un mensaje "reprobado", si


el promedio es mayor o igual a 4 y menor a 7, muestre "regular", si el promedio es
mayor o igual a 7, muestre "promocionado", usando la primer sintaxis de "case":
select legajo,promedio,
case truncate(promedio,0)
when 0 then 'reprobado'

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;

5- Obtenga la misma salida anterior pero empleando la otra sintaxis de "case":


select legajo,promedio,
case when promedio<4 then 'reprobado'
when promedio>4 and promedio<7 then 'regular'
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".

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)

322
values('FRT545','moto','19:45',null);
insert into vehiculos (patente,tipo,horallegada,horasalida)
values('GTY154','auto','20:30','21:00');

4- Se cobra 1 peso por hora. Pero si un vehículo permanece en la playa 4 horas,


se le cobran 3 pesos, es decir, no se le cobra la cuarta hora; si está 8 horas, se
cobran 6 pesos, y así sucesivamente. Muestre la patente, la hora de llegada y de
salida de todos los vehículos, más la columna que calcule la cantidad de horas
que estuvo cada vehículo en la playa (sin considerar los que aún no se retiraron
de la playa) y otra columna utilizando "case" que muestre la cantidad de horas
gratis:
select patente,horallegada,horasalida,
left(timediff(horasalida,horallegada),5) as horasminutos,
case when hour(timediff(horasalida,horallegada))>4 then
hour(timediff(horasalida,horallegada)) div 4
else 0
end as horagratis
from vehiculos
where horasalida is not null;

5- Muestre la patente, la hora de llegada y de salida de todos los vehículos, más


una columna que calcule la cantidad de horas que estuvo cada vehículo en la
playa (sin considerar los que aún no se retiraron de la playa) y otra columna (con
"case") que calcule la cantidad de horas cobradas:
select patente,horallegada,horasalida,
left(timediff(horasalida,horallegada),5) as horasminutos,
case when extract(hour_minute from timediff(horasalida,horallegada))<200 then 1
else hour(timediff(horasalida,horallegada))-
hour(timediff(horasalida,horallegada)) div 4
end as horascobradas
from vehiculos
where horasalida is not null;

B) En una página web se solicitan los siguientes datos para guardar información
de sus visitas.

1- Elimine la tabla "visitas", si existe.

2- Créela con la siguiente estructura:


create table visitas (
numero int unsigned auto_increment,
nombre varchar(30) not null,
mail varchar(50),
pais varchar (20),
fecha date,
primary key(numero)
);

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');

4- Muestre el nombre, la fecha de ingreso y los nombres de los días de la semana


empleando un "case":
select nombre,fecha,
case dayname(fecha)
when 'Monday' then 'lunes'
when 'Tuesday' then 'martes'
when 'Wednesday' then 'miercoles'
when 'Thursday' then 'jueves'
when 'Friday' then 'viernes'
when 'Saturday' then 'sabado'
else 'domingo'
end as 'dia'
from visitas;

5- Muestre el nombre y fecha de ingreso a la página y con un "case" muestre si el


nombre del mes corresponde al 1º, 2º o 3º cuatrimestre del año.
select nombre,fecha,
case when (monthname(fecha) in ('January','February','March','April'))
then '1º cuatrimestre'
when (monthname(fecha) in ('May','June','July','August'))
then '2º cuatrimestre'
else '3º cuatrimestre'
end as 'mes'
from visitas;

324
62 - Varias tablas (join)

Hasta ahora hemos trabajado con una sola tabla, pero en general, se trabaja con
varias tablas.

Para evitar la repetición de datos y ocupar menos espacio, se separa la


información en varias tablas. Cada tabla tendrá parte de la información total que
queremos registrar.

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:

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)
);

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".

Al recuperar los datos de los libros:

select * from libros;

vemos que en el campo "editorial" aparece el código, pero no sabemos el nombre


de la editorial. Para obtener los datos de cada libro, incluyendo el nombre de la
editorial, necesitamos consultar ambas tablas, traer información de las dos.

Cuando obtenemos información de más de una tabla decimos que hacemos un


"join" (unión). Veamos un ejemplo:

325
select * from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo;

Analicemos la consulta anterior.

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.

Cuando se combina (join, unión) información de varias tablas, es necesario indicar


qué registro de una tabla se combinará con qué registro de la otra tabla.

Si no especificamos por qué campo relacionamos ambas tablas, por ejemplo:

select * from libros


join editoriales;

el resultado es el producto cartesiano de ambas tablas (cada registro de la primera


tabla se combina con cada registro de la segunda tabla), un "join" sin condición
"on" genera un resultado en el que aparecen todas las combinaciones de los
registros de ambas tablas. La información no sirve.

Note que en la consulta

select * from libros


join editoriales
on libros.codigoeditorial=editoriales.codigo;

al nombrar el campo usamos el nombre de la tabla también. Cuando las tablas


referenciadas tienen campos con igual nombre, esto es necesario para evitar
confusiones y ambiguedades al momento de referenciar un campo. En este
ejemplo, si no especificamos "editoriales.codigo" y solamente tipeamos "codigo",
MySQL no sabrá si nos referimos al campo "codigo" de "libros" o de "editoriales".

Si omitimos la referencia a las tablas al nombrar el campo "codigo" (nombre de


campo que contienen ambas tablas):

select * from libros


join editoriales
on codigoeditorial=codigo;

aparece un mensaje de error indicando que "codigo" es ambiguo.

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 (.).

Entonces, se nombra la primer tabla, se coloca "join" junto al nombre de la


segunda tabla de la cual obtendremos información y se asocian los registros de
ambas tablas usando un "on" que haga coincidir los valores de un campo en
común en ambas tablas, que será el enlace.

Para simplificar la sentencia podemos usar un alias para cada tabla:

select * from libros as l


join editoriales as e
on l.codigoeditorial=e.codigo;

Cada tabla tiene un alias y se referencian los campos usando el alias


correspondiente. En este ejemplo, el uso de alias es para fines de simplificación,
pero en algunas consultas es absolutamente necesario.

En la consulta anterior vemos que el código de la editorial aparece 2 veces, desde


la tabla "libros" y "editoriales". Podemos solicitar que nos muestre algunos
campos:

select titulo,autor,nombre from libros as l


join editoriales as e
on l.codigoeditorial=e.codigo;

Al presentar los campos, en este caso, no es necesario aclarar a qué tabla


pertenecen porque los campos solicitados no se repiten en ambas tablas, pero si
solicitáramos el código del libro, debemos especificar de qué tabla porque el
campo "codigo" se repite en ambas tablas ("libros" y "editoriales"):

select l.codigo,titulo,autor,nombre from libros as l


join editoriales as e
on l.codigoeditorial=e.codigo;

Si obviamos la referencia a la tabla, la sentencia no se ejecuta y aparece un


mensaje indicando que el campo "codigo" es ambiguo.

Ejemplo:
Trabajamos con las tablas "libros" y editoriales" de una librería.

Elimine las tablas, si existen:

drop table if exists libros, editoriales;

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');

Cargamos algunos registros en la tabla "libros":


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);

Mostramos todos los datos de la tabla "libros":


select * from libros;

Queremos también el nombre de la editorial, necesitamos ambas tablas:


select * from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo;

Analicemos la consulta: 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

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.

Si no especificamos por qué campo relacionamos ambas tablas, es decir,


omitimos la condición "on":
select * from libros
join editoriales;

el resultado es el producto cartesiano de ambas tablas. Un "join" sin condición "on"


para la unión genera un resultado en el que aparecen todas las combinaciones de
los registros de ambas tablas.

Veamos lo que sucede si omitimos la referencia a las tablas al nombrar el campo


"codigo" (nombre de campo que contienen ambas tablas):
select * from libros
join editoriales
on codigoeditorial=codigo;

aparece un mensaje de error indicando que "codigo" es ambiguo.

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.

Para simplificar la sentencia podemos usar un alias para cada tabla:


select * from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;

En la consulta anterior, el código de la editorial aparece 2 veces, desde la tabla


"libros" y "editoriales". Podemos solicitar que nos muestre algunos campos:
select titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;

Si queremos ver el código del libro, al presentar el campo "codigo", debemos


especificar de qué tabla, porque el campo "codigo" se repite en ambas tablas
("libros" y "editoriales"):
select l.codigo,titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;

Si obviamos la referencia a la tabla, la sentencia no se ejecuta y aparece un


mensaje indicando que el campo "codigo" es ambiguo:
select codigo,titulo,autor,nombre from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo;

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.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
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');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
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');

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');

4- Obtenga los datos de ambas tablas, use alias:


select c.nombre,c.domicilio,c.ciudad,p.nombre,c.telefono
from clientes as c
join provincias as p
on c.codigoProvincia=p.codigo;

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;

6- Omita la referencia a las tablas en la condición "on" para verificar que la


sentencia no se ejecuta porque el nombre del campo "codigo" es ambiguo (ambas
tablas lo tienen):
select c.nombre,c.domicilio,c.ciudad,p.nombre,c.telefono
from clientes as c
join provincias as p
on codigoProvincia=codigo

Otros problemas:

A) 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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);

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)
);

3- Ingrese algunos registros para ambas tablas:


insert into socios values('22333444','Juan Perez','Colon 234');
insert into socios values('23333444','Maria Lopez','Sarmiento 465');
insert into socios values('24333444','Antonio Juarez','Caseros 980');

insert into inscriptos values ('22333444','natacion','2005','s');


insert into inscriptos values ('22333444','natacion','2006','n');
insert into inscriptos values ('23333444','natacion','2005','s');
insert into inscriptos values ('23333444','tenis','2006','s');
insert into inscriptos values ('23333444','natacion','2006','s');
insert into inscriptos values ('24333444','tenis','2006','n');
insert into inscriptos values ('24333444','basquet','2006','n');

4- Muestre el nombre del socio y todos los campos de la tabla "inscriptos":


select s.nombre,i.*
from socios as s
join inscriptos as i
on s.documento=i.documento;

5- Omita la referencia a las tablas en la condición "on" para verificar que la


sentencia no se ejecuta porque el nombre del campo "documento" es ambiguo
(ambas tablas lo tienen):
select s.nombre,i.*
from socios as s
join inscriptos as i
on documento=documento;

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;

7- Muestre el nombre y todas las inscripciones del socio con número de


documento='23333444':
select s.nombre,i.*
from socios as s

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".

1- Elimine las tablas, si existen.

2- Cree las tablas:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar (30),
editorial varchar (15),
primary key (codigo)
);
create table prestamos(
codigolibro int unsigned not null,
documento char(8) not null,
fechaprestamo date not null,
fechadevolucion date,
primary key(codigolibro,fechaprestamo)
);

3- Ingrese algunos registros para ambas tablas:


insert into libros values (15,'Manual de 1º grado','Moreno Luis','Emece');
insert into libros values (28,'Manual de 2º grado','Moreno Luis','Emece');
insert into libros values (30,'Alicia en el pais de las maravillas','Lewis
Carroll','Planeta');
insert into libros values (35,'El aleph','Borges','Emece');

insert into prestamos


values(15,'22333444','2006-07-10','2006-07-12');
insert into prestamos
values(15,'22333444','2006-07-20','2006-07-21');
insert into prestamos (codigolibro,documento,fechaprestamo)
values(15,'23333444','2006-07-25');
insert into prestamos (codigolibro,documento,fechaprestamo)
values(30,'23333444','2006-07-28');
insert into prestamos (codigolibro,documento,fechaprestamo)
values(28,'25333444','2006-08-10');

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;

5- Muestre la información de los préstamos del libro "Manual de 1º grado":


select p.documento,fechaprestamo,fechadevolucion
from prestamos as p
join libros as l
on l.codigo=p.codigolibro
where l.titulo='Manual de 1º grado';

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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table consultas(
fecha date,
hora time,
documento char(8) not null,
codigoobrasocial tinyint unsigned,
medico varchar(30),
primary key(fecha,hora,medico)
);
create table obrassociales(
codigo tinyint unsigned auto_increment,
nombre varchar(15),
monto decimal(5,2) unsigned,
primary key(codigo)
);
3- Ingrese algunos registros:
insert into obrassociales (nombre,monto)
values('PAMI',2);
insert into obrassociales (nombre,monto)
values('IPAM',5);
insert into obrassociales (nombre,monto)
values('OSDOP',3);

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');

4- Muestre la fecha,hora,documento del paciente, médico, nombre y monto de la


obra social de todas las consultas (join con "obrassociales"):
select c.fecha,c.hora,c.documento,c.medico,os.nombre,os.monto
from consultas as c
join obrassociales as os
on os.codigo=c.codigoobrasocial;

5- Muestre fecha,hora,documento del paciente y nombre de la obra social para las


consultas del doctor "Perez":
select c.fecha,c.hora,c.documento,os.nombre,os.monto
from consultas as c
join obrassociales as os
on os.codigo=c.codigoobrasocial
where c.medico='Perez';

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".

En el ejemplo de la librería en que utilizamos las tablas "libros" y "editoriales" con


los campos:

libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio, cantidad y


editoriales: codigo (clave primaria), nombre.

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.

Eliminamos las tablas, si existen:


drop table libros, editoriales;

Creamos las 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)
);

En este ejemplo, el campo "codigoeditorial" de "libros" es una clave foránea, se


emplea para enlazar la tabla "libros" con "editoriales".

Ingresamos algunos registros:


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);

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);

Veamos cómo afectó el cambio a la tabla "libros":


select * from libros;

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").

Si buscamos coincidencia de códigos en la tabla "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.

Intentemos modificar la clave en "editoriales":

alter table editoriales


modify codigo char(1);

No lo permite porque si la modifica los valores para el campo clave quedan


repetidos.

drop table 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,

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.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
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)
);
En este ejemplo, el campo "codigoprovincia" de "clientes" es una clave foránea, se
emplea para enlazar la tabla "clientes" con "provincias".

3- Ingrese algunos registros para ambas tablas:


insert into provincias(codigo,nombre) values(1,'Cordoba');
insert into provincias(codigo,nombre) values(2,'Santa Fe');
insert into provincias(codigo,nombre) values(30,'Misiones');

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');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Ramos Betina', 'San Martin 999', 'Bahia Blanca',15,'4223366');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Lopez Lucas', 'San Martin 1010', 'Posadas',30,'0457858745');

4- Enlace las tablas:


select c.nombre,c.ciudad,p.nombre
from clientes as c
left join provincias as p
on c.codigoprovincia=p.codigo;

5- Modifique el campo "codigoprovincia" a "char(1)":


alter table clientes
modify codigoprovincia char(1);

6- Vea cómo afectó el cambio a la tabla "clientes":


select * from clientes;
El cliente de "Bahia Blanca" con código de provincia "15" ("Buenos Aires") ahora
tiene "1"
("Cordoba") y el cliente con código de provincia "30" ("Misiones") ahora almacena
"3" (valor
inexistente en "provincias").

7- Realice un "left join" buscando coincidencia de códigos en la tabla "provincias":


select c.nombre,c.ciudad,p.nombre
from clientes as c
left join provincias as p
on c.codigoprovincia=p.codigo;
El resultado es erróneo.

8- Intente modificar la clave primaria en "provincias" para que se corresponda


con "codigoprovincia" de "clientes":
alter table provincias
modify codigo char(1);

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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table deportes(
codigo tinyint unsigned,
nombre varchar(20),
profesor varchar(30),
primary key(codigo)
);
create table inscriptos(
documento char(8) not null,
codigodeporte tinyint unsigned not null,
año year,
matriculapaga char(1),/* 's' si está paga, 'n' si no está paga*/
primary key(documento,codigodeporte,año)
);
3- Ingrese algunos registros para ambas tablas:
insert into deportes values(1,'Tenis','Juan Lopez');
insert into deportes values(2,'Natacion','Maria Lopez');
insert into deportes values(3,'Basquet','Antonio Juarez');

insert into inscriptos values ('22333444',2,'2005','s');


insert into inscriptos values ('22333444',2,'2006','n');
insert into inscriptos values ('23333444',2,'2005','s');
insert into inscriptos values ('23333444',1,'2005','s');
insert into inscriptos values ('23333444',1,'2006','s');
insert into inscriptos values ('24333444',2,'2006','n');
insert into inscriptos values ('24333444',3,'2006','n');

4- Muestre el nombre del deporte y todos los campos de la tabla "inscriptos":


select d.nombre,i.*
from deportes as d
join inscriptos as i
on d.codigo=i.codigodeporte;

5- Modifique el campo "codigo" de "deportes" para que almacene 1 caracter:


alter table deportes modify codigo char(1);

341
6- Actualice la tabla "deportes" almacenando en "codigo" el primer caracter del
nombre del deporte:
update deportes set codigo=left(nombre,1);

7- Vea cómo cambió la tabla:


select * from deportes;

8- Realice un "join":
select d.nombre,i.*
from deportes as d
join inscriptos as i
on d.codigo=i.codigodeporte;
No encuentra coincidencia.

64 - Varias tablas (left join)


Hemos visto cómo usar registros de una tabla para encontrar registros de otra
tabla, uniendo ambas tablas con "join" y enlazándolas con una condición "on" en la
cual colocamos el campo en común. O sea, hacemos un "join" y asociamos
registros de 2 tablas usando el "on", buscando coincidencia en los valores del
campo que tienen en comun ambas tablas.

Trabajamos con las tablas de una librería:

-libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio, cantidad y


-editoriales: codigo (clave primaria), nombre.

Queremos saber de qué editoriales no tenemos libros.

Para averiguar qué registros de una tabla no se encuentran en otra tabla


necesitamos usar un "join" diferente.

Necesitamos determinar qué registros no tienen correspondencia en otra tabla,


cuáles valores de la primera tabla (de la izquierda) no están en la segunda (de la
derecha).

Para obtener la lista de editoriales y sus libros, incluso de aquellas editoriales 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

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".

Entonces, la sintaxis es la siguiente: se nombran ambas tablas, una a la izquierda


del "join" y la otra a la derecha, y la condición para enlazarlas, es decir, el campo
por el cual se combinarán, se establece luego de "on". Es importante la posición
en que se colocan las tablas en un "left join", la tabla de la izquierda es la que se
usa para localizar registros en la tabla de la derecha. Por lo tanto, estos "join" no
son iguales:

select * from editoriales


left join libros
on editoriales.codigo=libros.codigoeditorial;

select * from libros


left join editoriales
on editoriales.codigo=libros.codigoeditorial;

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".

La segunda sentencia opera de modo inverso: por cada valor de "codigoeditorial"


de "libros" busca coincidencia en la tabla "editoriales", si no encuentra
coincidencia, setea la fila a "null".

Usando registros de la tabla de la izquierda se encuentran registros en la tabla de


la derecha.

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").

También podemos mostrar las editoriales que no están presentes en "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.

Eliminamos dichas tablas, si existen:


drop table if exists libros, editoriales;

Creamos 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 tinyint 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');

Cargamos algunos registros en la tabla "libros":


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);

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".

Recuerde que es importante la posición en que se colocan las tablas en un "left


join", la tabla de la izquierda es la que localiza registros en la tabla de la derecha.
Por lo tanto, estos "join" no son iguales:
select * from editoriales
left join libros
on editoriales.codigo=libros.codigoeditorial;

select * from libros


left join editoriales
on editoriales.codigo=libros.codigoeditorial;

La primera sentencia busca coincidencia en la tabla "libros" por cada valor de


codigo de "editoriales", si no encuentra coincidencia para algún valor, genera una
fila seteada a "null". No hay libros de la editorial "Sudamericana", entonces esa fila
contiene "null" en todos los campos correspondientes a "libros".

La segunda sentencia busca coincidencia en la tabla "editoriales" por cada valor


de "codigoeditorial" de "libros", si no encuentra coincidencia para algún valor,
genera una fila seteada a "null". El libro "Aprenda java en 10 minutos" tiene código
de editorial "5", valor inexistente en la tabla "editoriales", por ello, esa fila contiene
"null" en todos los campos correspondientes a "editoriales".

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;

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 tinyint 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);
insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('Aprenda Java en 10 minutos','Lopez Juan',5,28,100);
select * from editoriales
left join libros
on editoriales.codigo=libros.codigoeditorial;
select * from libros
left join editoriales
on editoriales.codigo=libros.codigoeditorial;
select nombre,titulo
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
where l.codigoeditorial is not null;
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.

1- Elimine las tablas "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
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');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
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)

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');

4- Queremos saber de qué provincias no tenemos clientes:


select p.codigo,p.nombre from provincias as p
left join clientes as c
on c.codigoProvincia=p.codigo
where c.codigoprovincia is null;

5- Queremos saber de qué provincias si tenemos clientes, sin repetir el nombre de


la provincia:
select distinct p.codigo,p.nombre from provincias as p
left join clientes as c
on c.codigoProvincia=p.codigo
where c.codigoprovincia is not null;

6- Omita la referencia a las tablas en la condición "on" para verificar que la


sentencia no se ejecuta porque el nombre del campo "codigo" es ambiguo (ambas
tablas lo tienen):
select distinct codigo,p.nombre from provincias as p
left join clientes as c
on c.codigoProvincia=p.codigo
where c.codigoprovincia is not null;

Otros problemas:

A) 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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
create table inscriptos(
documento char(8) not null,
deporte varchar(15) not null,
año year,

348
matricula char(1), /*si esta paga ='s' sino 'n'*/
primary key(documento,deporte,año)
);

3- Ingrese algunos registros para ambas tablas:


insert into socios values('22333444','Juan Perez','Colon 234');
insert into socios values('23333444','Maria Lopez','Sarmiento 465');
insert into socios values('24333444','Antonio Juarez','Caseros 980');
insert into socios values('25333444','Ana Juarez','Sucre 134');
insert into socios values('26333444','Sofia Herrero','Avellaneda 1234');

insert into inscriptos values ('22333444','natacion','2005','s');


insert into inscriptos values ('22333444','natacion','2006','n');
insert into inscriptos values ('23333444','natacion','2005','s');
insert into inscriptos values ('23333444','tenis','2006','s');
insert into inscriptos values ('23333444','natacion','2006','s');
insert into inscriptos values ('25333444','tenis','2006','n');
insert into inscriptos values ('25333444','basquet','2006','n');

4- Muestre el nombre del socio, deporte y año realizando un join:


select s.nombre,i.deporte,i.año
from socios as s
left join inscriptos as i
on s.documento=i.documento;

5- Muestre los nombres de los socios que no se han inscripto nunca en un


deporte:
select s.nombre
from socios as s
left join inscriptos as i
on s.documento=i.documento
where i.documento is null;

6- Omita la referencia a las tablas en la condición "on" para verificar que la


sentencia no se ejecuta porque el nombre del campo "documento" es ambiguo
(ambas tablas lo tienen):
select s.nombre
from socios as s
left join inscriptos as i
on documento=documento;

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".

1- Elimine las tablas si existen.

2- Cree las tablas:

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);

insert into numerosrifa values(205,'22333444');


insert into numerosrifa values(200,'23333444');
insert into numerosrifa values(5,'23333444');
insert into numerosrifa values(8,'23333444');
insert into numerosrifa values(1,'24333444');
insert into numerosrifa values(109,'28333444');
insert into numerosrifa values(15,'30333444');
insert into numerosrifa values(29,'29333444');
insert into numerosrifa values(28,'32333444');

4- Muestre todos los números de rifas vendidos ("numerosrifas") y realice un "left


join" mostrando la posición y el premio:
select nr.numero,p.posicion,p.premio
from numerosrifa as nr
left join premios as p
on p.numeroganador=nr.numero;

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;

Note que el premio de la posición "5" no encuentra coincidencia en la tabla


"numerosrifa" (porque no fue vendido) y el campo está seteado a "null".

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;

65 - Varias tablas (right join)


"right join" opera del mismo modo que "left join" sólo que la búsqueda de
coincidencias la realiza de modo inverso, es decir, los roles de las tablas se
invierten, busca coincidencia de valores desde la tabla de la derecha en la tabla de
la izquierda y si un valor de la tabla de la derecha no encuentra coincidencia en la
tabla de la izquierda, se genera una fila extra (una por cada valor no encontrado)
con todos los campos seteados a "null".

Trabajamos con las tablas de una librería:

-libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio, cantidad y


-editoriales: codigo (clave primaria), nombre.

Estas sentencias devuelven el mismo resultado:


select nombre,titulo
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial;

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.

Eliminamos dichas tablas, si existen:


drop table if exists libros, editoriales;

Creamos 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 tinyint 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');

Cargamos algunos registros en la tabla "libros":


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);

Necesitamos los títulos y nombres de las editoriales de los libros, incluso de


aquellos editoriales que no tienen libros:

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).

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 tinyint 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 nombre,titulo
from editoriales as e
left join libros as l

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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
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)
);
3- Ingrese algunos registros para ambas tablas:
insert into socios values('22333444','Juan Perez','Colon 234');
insert into socios values('23333444','Maria Lopez','Sarmiento 465');
insert into socios values('24333444','Antonio Juarez','Caseros 980');
insert into socios values('25333444','Marcelo Pereyra','Sucre 349');

insert into inscriptos values ('22333444','natacion','2005','s');


insert into inscriptos values ('22333444','natacion','2006','n');
insert into inscriptos values ('23333444','natacion','2005','s');
insert into inscriptos values ('23333444','tenis','2006','s');
insert into inscriptos values ('23333444','natacion','2006','s');
insert into inscriptos values ('24333444','tenis','2006','n');
insert into inscriptos values ('24333444','basquet','2006','n');

4- Realice un "left join" de la tabla "socios" a "inscriptos" buscando coincidencia de


"documento":
select s.documento,nombre,i.deporte,i.año,i.matricula
from socios as s
left join inscriptos as i

354
on s.documento=i.documento;
Note que el socio que no está inscripto en ningún deporte tiene la fila seteada a
"null".

5- Realice un "right join" para obtener la misma salida anterior:


select s.documento,nombre,i.deporte,i.año,i.matricula
from inscriptos as i
right join socios as s
on s.documento=i.documento;

6- Ingrese una inscripción de alguien que no sea socio (documento que no se


encuentre en la tabla "socios"):
insert into inscriptos values ('26333444','basquet','2006','n');

7- Realice un "right join" desde la tabla "socios" a "inscriptos" buscando


coincidencia de documento:
select nombre,i.documento,deporte,i.año,i.matricula
from socios as s
right join inscriptos as i
on s.documento=i.documento;
Note que la persona con documento "26333444" no se encuentra en "socios", la
columna "nombre" (correspondiente a la tabla "socios") contiene "null".

66 - Varias tablas (cross join)


"cross join" retorna todos los registros de todas las tablas implicadas en la unión,
devuelve el producto cartesiano. No es muy utilizado.

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.

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;

es igual a un simple "join" sin parte "on":

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;

Para realizar un "join" no es necesario utilizar 2 tablas, podemos combinar los


registros de una misma tabla. Para ello debemos utilizar 2 alias para la tabla.

Si los datos de las tablas anteriores ("comidas" y "postres") estuvieran en una sola
tabla con la siguiente estructura:

create table comidas(


codigo tinyint unsigned auto_increment,
nombre varchar(30),
rubro varchar(20),/*plato principal y postre*/
precio decimal (5,2) unsigned,
primary key(codigo)
);

Podemos obtener la combinación de platos principales con postres empleando un


"cross join" con una sola tabla:

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';

Se empleó un "where" para combinar "plato principal" con "postre".

Si queremos el monto total de cada combinación:

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;

Creamos las siguientes tablas:


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)
);
Ingresamos algunos registros:
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);

insert into postres values(1,'flan',1);


insert into postres values(2,'porcion de torta',2.1);
insert into postres values(3,'gelatina',0.9);

Empleamos "cross join" para obtener el producto cartesiano de ambas tablas:


select c.*,p.*
from comidas as c
cross join postres as p;

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.

Eliminamos las tablas anteriormente creadas:


drop table comidas, postres;

Creamos la tabla "comidas" con la siguiente estructura:


create table comidas(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
rubro varchar(20),/*plato principal y postre*/
precio decimal (5,2) unsigned,
primary key(codigo)
);
Ingresamos algunos registros:
insert into comidas values(1,'milanesa y fritas','plato principal',3.4);
insert into comidas values(2,'arroz primavera','plato principal',2.5);
insert into comidas values(3,'pollo','plato principal',2.8);
insert into comidas values(4,'flan','postre',1);
insert into comidas values(5,'porcion de torta','postre',2.1);
insert into comidas values(6,'gelatina','postre',0.9);

Podemos obtener la combinación de platos principales con postres empleando un


"cross join" con una sola tabla:
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';

Note que utilizamos 2 alias para la misma tabla y empleamos un "where" para
combinar el "plato principal" con el "postre".

Si queremos el monto total de cada combinación:


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';

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);

insert into postres values(1,'flan',1);


insert into postres values(2,'porcion de torta',2.1);
insert into postres values(3,'gelatina',0.9);
select c.*,p.*
from comidas as c
cross join postres as p;
select c.*,p.*
from comidas as c
join postres as p;
select c.nombre,p.nombre,
c.precio+p.precio as total
from comidas as c
cross join postres as p;
drop table comidas, postres;
create table comidas(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
rubro varchar(20),/*plato principal y postre*/
precio decimal (5,2) unsigned,
primary key(codigo)
);
insert into comidas values(1,'milanesa y fritas','plato principal',3.4);
insert into comidas values(2,'arroz primavera','plato principal',2.5);
insert into comidas values(3,'pollo','plato principal',2.8);
insert into comidas values(4,'flan','postre',1);
insert into comidas values(5,'porcion de torta','postre',2.1);
insert into comidas values(6,'gelatina','postre',0.9);
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';

359
Problema:

Una empresa de seguridad almacena los datos de sus guardias de seguridad en


una tabla llamada "guardias". también almacena los distintos sitios que solicitaron
sus servicios en una tabla llamada "tareas".

1- Elimine las tablas "guardias" y "tareas" si existen.

2- Cree las siguientes tablas:


create table guardias(
documento char(8),
nombre varchar(30),
sexo char(1), /* 'f' o 'm' */
domicilio varchar(30),
primary key (documento)
);
create table tareas(
codigo tinyint unsigned auto_increment,
domicilio varchar(30),
descripcion varchar(30),
horario char(2), /* 'AM' o 'PM'*/
primary key (codigo)
);
3- Ingrese los siguientes registros:
insert into guardias values('22333444','Juan Perez','m','Colon 123');
insert into guardias values('23333444','Lorena Viale','f','Sarmiento 988');
insert into guardias values('24333444','Alberto Torres','m','San Martin 567');
insert into guardias values('25333444','Luis Ferreyra','m','Chacabuco 235');
insert into guardias values('26333444','Irma Gonzalez','f','Mariano Moreno 111');

insert into tareas (domicilio,descripcion,horario)


values('Colon 1111','vigilancia exterior','AM');
insert into tareas (domicilio,descripcion,horario)
values('Urquiza 234','vigilancia exterior','PM');
insert into tareas (domicilio,descripcion,horario)
values('Peru 345','vigilancia interior','AM');
insert into tareas (domicilio,descripcion,horario)
values('Avellaneda 890','vigilancia interior','PM');

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:

A) Varios clubes de barrio se organizaron para realizar campeonatos entre ellos.


La tabla llamada "equipos" guarda la información de los distintos equipos que
jugarán.

1- Elimine la tabla, si existe.

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;

5- Obtenga el mismo resultado empleando un "join" sin parte "on":


select e1.nombre,e2.nombre,e1.barrio as 'sede'
from equipos as e1
join equipos as e2
where e1.nombre<>e2.nombre;

B) Una agencia matrimonial almacena la información de sus clientes en una tabla


llamada "clientes".

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);

4- La agencia necesita la combinación de todas las personas de sexo femenino


con las de sexo masculino. Use un "join" sin parte "on" y establezca como
condición que las personas de la primera tabla sean de sexo femenino y las de la
segunda tabla de sexo masculino:
select c1.nombre,c1.edad,c1.sexo, c2.nombre,c2.edad,c2.sexo
from clientes as c1
join clientes as c2
where c1.sexo='f' and c2.sexo='m';

5- Obtenga la misma salida usando "cross join":


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';

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.

Tenemos las tablas "libros" y "editoriales" de una librería.

Las tablas tienen las siguientes estructuras:

- libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio.


- editoriales: codigoeditorial(clave primaria), nombre.

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;

La siguiente sentencia tiene la misma salida anterior:

select titulo,nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigoeditorial;

También se puede usar "natural" con "left join" y "right join":

select nombre,titulo
from editoriales as e
natural left join libros as l;

que tiene la misma salida que:

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.

Eliminamos dichas tablas, si existen:


drop table if exists libros, editoriales;

Creamos 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 tinyint unsigned default 0,
primary key (codigo)
);
create table editoriales(
codigoeditorial tinyint unsigned auto_increment,
nombre varchar(20) not null,
primary key(codigoeditorial)
);
Cargamos algunos registros en la tabla "editoriales":
insert into editoriales (nombre) values('Planeta');
insert into editoriales (nombre) values('Emece');
insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Sudamericana');

Cargamos algunos registros en la tabla "libros":


insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
values('El Aleph','Borges',1,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('Martin Fierro','Jose Hernandez',1,55.8,50);

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;

La siguiente sentencia tiene la misma salida anterior:


select titulo,nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigoeditorial;

También se puede usar "natural" con "left join" y "right join":


select nombre,titulo
from editoriales as e
natural left join libros as l;

que tiene la misma salida que:


select nombre,titulo
from editoriales as e
left join libros as l
on e.codigoeditorial=l.codigoeditorial;

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.

Alteremos la tabla "libros" para que el campo "titulo" se denomine "nombre":


alter table libros change titulo nombre varchar(40);

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.

Alteramos nuevamente la tabla "libros" para que el campo "nombre" en adelante


sea "titulo":
alter table libros change nombre titulo varchar(40);

Alteramos la tabla "editoriales" para que el campo "codigoeditorial" se llame en


adelante "codigo":

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.

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 tinyint unsigned default 0,
primary key (codigo)
);
create table editoriales(
codigoeditorial tinyint unsigned auto_increment,
nombre varchar(20) not null,
primary key(codigoeditorial)
);
insert into editoriales (nombre) values('Planeta');
insert into editoriales (nombre) values('Emece');
insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Sudamericana');

insert into libros (titulo, autor,codigoeditorial,precio,cantidad)


values('El Aleph','Borges',1,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('Martin Fierro','Jose Hernandez',1,55.8,50);
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

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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
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)
);
3- Ingrese algunos registros para ambas tablas:
insert into socios values('22333444','Juan Perez','Colon 234');
insert into socios values('23333444','Maria Lopez','Sarmiento 465');
insert into socios values('24333444','Antonio Juarez','Caseros 980');
insert into socios values('25333444','Marcelo Pereyra','Sucre 349');

insert into inscriptos values ('22333444','natacion','2005','s');


insert into inscriptos values ('22333444','natacion','2006','n');
insert into inscriptos values ('23333444','natacion','2005','s');
insert into inscriptos values ('23333444','tenis','2006','s');
insert into inscriptos values ('23333444','natacion','2006','s');
insert into inscriptos values ('24333444','tenis','2006','n');
insert into inscriptos values ('24333444','basquet','2006','n');

367
4- Realice un "natural join" de ambas tablas:
select nombre,i.*
from socios as s
natural join inscriptos as i;

5- Obtenga el mismo resultado con un "join":


select nombre,i.*
from socios as s
join inscriptos as i
on s.documento=i.documento;

6- Realice un "left join" de la tabla "socios" a "inscriptos" buscando coincidencia de


"documento":
select nombre,i.*
from socios as s
left join inscriptos as i
on s.documento=i.documento;
Note que el socio que no está inscripto en ningún deporte tiene la fila seteada a
"null".

7- Realice un "natural left join" para obtener la misma salida anterior:


select nombre,i.*
from socios as s
natural left join inscriptos as i;

8- Realice un "natural right join" para obtener la misma salida anterior:


select nombre,i.*
from inscriptos as i
natural right join socios as s;

68 - Varias tablas (inner join - straight join)


Existen otros tipos de "join" además del simple "join", "left join", "right join", "cross
join" y "natural join". Veámoslos.

"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;

Tiene la misma salida que un simple "join":

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.

69 - join, group by y funciones de agrupamiento.


Podemos usar "group by" y las funciones de agrupamiento con "join".

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;

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":

select e.nombre,count(l.codigoeditorial) as 'Cantidad de libros'


from editoriales as e
join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;

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.

Eliminamos ambas tablas, si existen.

Creamos las tablas.


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)
);
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');

Ingresamos algunos registros en la tabla "libros":


insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll',1,23.5);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia a traves del espejo','Lewis Carroll',2,25);
insert into libros (titulo, autor,codigoeditorial,precio)
values('El aleph','Borges',2,15);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Matemática estas ahi','Paenza',1,10);

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":

select e.nombre,count(l.codigoeditorial) as 'cantidad de libros'


from editoriales as e
join libros as l
on l.codigoeditorial=e.codigo
group by e.nombre;

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;

Igualmente, en la sentencia anterior, muestra, para la editorial de la cual no hay


libros, el valor "null" en la columna calculada; si realizamos un "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


"libros".

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');

insert into libros (titulo, autor,codigoeditorial,precio)


values('Alicia en el pais de las maravillas','Lewis Carroll',1,23.5);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia a traves del espejo','Lewis Carroll',2,25);
insert into libros (titulo, autor,codigoeditorial,precio)
values('El aleph','Borges',2,15);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Matemática estas ahi','Paenza',1,10);
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;
select e.nombre,count(l.codigoeditorial) as 'cantidad de libros'
from editoriales as e
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
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;

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.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
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');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)

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');

4- Agrupe por nombre de provincia y cuente la cantidad de clientes por provincia


usando un "join":
select p.nombre,
count(c.codigoprovincia) as 'cant. clientes'
from provincias as p
join clientes as c
on p.codigo=c.codigoprovincia
group by p.nombre;
sólo aparecen las provincias en las cuales tenemos clientes.

5- Agrupe por nombre de provincia y cuente la cantidad de clientes por provincia


usando un "left join":
select p.nombre,
count(c.codigoprovincia) as 'cant. clientes'
from provincias as p
left join clientes as c
on p.codigo=c.codigoprovincia
group by p.nombre;
Muestra todas las provincias.

6- Agrupe por nombre de provincia y muestre la cantidad de clientes por provincia


usando un "join" de las provincias en las cuales tenemos 2 o más clientes:
select p.nombre,
count(c.codigoprovincia) as 'cant. clientes'
from provincias as p
join clientes as c
on p.codigo=c.codigoprovincia
group by p.nombre
having count(c.codigoprovincia)>=2;

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.

1- Elimine las tablas "visitantes" y "ciudades", si existen.

2- Créelas con las siguientes estructuras:


create table visitantes(
nombre varchar(30),
edad tinyint unsigned,
sexo char(1),
domicilio varchar(30),
codigociudad tinyint unsigned not null,
telefono varchar(11),
montocompra decimal(6,2) unsigned
);
create table ciudades(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key (codigo)
);
3- Ingrese algunos registros:
insert into ciudades (nombre)
values('Cordoba');
insert into ciudades (nombre)
values('Alta Gracia');
insert into ciudades (nombre)
values('Villa Dolores');
insert into ciudades (nombre)
values('Carlos Paz');

insert into visitantes (nombre,edad,


sexo,domicilio,codigociudad,telefono,montocompra)
values ('Susana Molina', 28,'f','Colon 123',1,null,45.50);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Marcela Mercado',36,'f','Avellaneda 345',1,'4545454',0);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Alberto Garcia',35,'m','Gral. Paz 123',2,'03547123456',25);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)
values ('Teresa Garcia',33,'f','Gral. Paz 123',2,'03547123456',0);
insert into visitantes (nombre,edad,
sexo,domicilio,codigociudad,telefono,montocompra)

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);

4- Muestre la cantidad de visitantes agrupados por nombre de la ciudad:


select c.nombre,count(v.codigociudad)
from ciudades as c
left join visitantes as v
on c.codigo=v.codigociudad
group by c.nombre;

5- Muestre la cantidad de visitantes que hicieron alguna compra, agrupados por


nombre de la ciudad:
select c.nombre,count(v.codigociudad)
from ciudades as c
join visitantes as v
on c.codigo=v.codigociudad
where v.montocompra>0
group by c.nombre;

6- Muestre la suma de las compras y el promedio de las mismas, agrupados por


ciudad y sexo:
select c.nombre,sexo,sum(montocompra) as 'total',
avg(montocompra) as 'promedio'
from ciudades as c
join visitantes as v
on c.codigo=v.codigociudad
group by c.nombre,sexo;

B) Una inmobiliaria que alquila departamentos guarda la información de los


mismos en una tabla llamada "departamentos" y "barrios".

376
1- Elimine las tablas si existen.

2- Cree las tablas con las siguientes estructuras:


create table inmuebles(
edificio varchar(30),
domicilio varchar(30) not null,
piso char(1) not null,
numerodpto char(2) not null,
detalles varchar(200),
codigobarrio tinyint unsigned,
precio decimal(6,2) unsigned,
primary key (edificio,piso,numerodpto)
);
create table barrios(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
primary key(codigo)
);
3- Ingrese los siguientes registros:
insert into barrios (nombre) values ('Centro');
insert into barrios (nombre) values ('Alberdi');
insert into barrios (nombre) values ('Gral. Paz');
insert into barrios (nombre) values ('Pueyrredon');

insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)


values('Avellaneda','Avellaneda 86','1','1',1,400.50);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Avellaneda','Avellaneda 86','1','2',1,400.50);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Avellaneda','Avellaneda 86','2','1',1,400.50);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Bolivar','Sarmiento 1203','1','1',3,500);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Centauro I','Peru 456','1','A',4,300);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Centauro I','Peru 456','2','C',4,350);
insert into departamentos (edificio,domicilio,piso,numerodpto,codigobarrio,precio)
values('Paris','Urquiza 364','1','12',1,600);

4- Muestre todos los departamentos incluido el nombre del barrio:


select edificio,domicilio,piso,numerodpto,nombre,precio
from departamentos as d
join barrios as b
on d.codigobarrio=b.codigo;

5- Muestre la cantidad de departamentos por edificio con el nombre del barrio:


select edificio,nombre,count(*)

377
from departamentos as d
join barrios as b
on d.codigobarrio=b.codigo
group by edificio;

6- Muestre el promedio de los precios de los departamentos agrupados por barrio:


select nombre,avg(precio)
from departamentos as d
join barrios as b
on d.codigobarrio=b.codigo
group by nombre;

7- Muestre el promedio de los precios de los departamentos agrupados por barrio


teniendo en cuenta todos los barrios, incluso aquellos en los cuales no hay
departamentos disponibles:
select nombre,avg(precio)
from barrios as b
left join departamentos as d
on d.codigobarrio=b.codigo
group by nombre;

C) Un video club que alquila películas en video guarda información de sus


películas en alquiler y los alquileres en las tabla "peliculas" y "alquileres"
respectivamente.

1- Elimine las tablas si existen.

2- Créelas con las siguientes estructuras:


create table peliculas (
codigo smallint unsigned auto_increment,
titulo varchar(30) not null,
actores varchar(40),
duracion tinyint unsigned,
primary key (codigo)
);
create table alquileres(
codigopelicula smallint unsigned not null,
socio varchar(30) not null,
fechaprestamo date not null,
fechadevolucion date,
primary key (codigopelicula,fechaprestamo)
);

3- Ingrese los siguientes registros para las 2 tablas.


insert into peliculas (titulo,actores,duracion)
values('Elsa y Fred','China Zorrilla',90);

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);

insert into alquileres (codigopelicula,socio,fechaprestamo)


values(1,'Juan Lopez','2006-07-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(2,'Juan Lopez','2006-07-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(3,'Juan Lopez','2006-07-12');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(1,'Luis Molina','2006-08-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(3,'Luis Molina','2006-08-12');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(4,'Luis Molina','2006-08-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(1,'Andrea Torres','2006-09-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(2,'Andrea Torres','2006-08-02');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(3,'Andrea Torres','2006-08-15');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(4,'Andrea Torres','2006-08-22');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(4,'Juan Lopez','2006-08-25');
insert into alquileres (codigopelicula,socio,fechaprestamo)
values(1,'Andrea Torres','2006-08-25');

4- Muestre toda la información de los "alquileres" (nombre de la película, nombre


del socio, fecha de préstamo y de devolución):
select titulo,socio,fechaprestamo,fechadevolucion from alquileres as a
join peliculas as p
on a.codigopelicula=p.codigo

5- Muestre la cantidad de veces que se alquiló cada película:


select p.titulo,count(*) from peliculas as p
join alquileres as a
on p.codigo=a.codigopelicula
group by p.titulo;

379
6- Muestre la cantidad de películas que alquiló cada socio:
select socio,count(a.codigopelicula) from alquileres
group by socio;

7- Muestre la cantidad de películas DISTINTAS que alquiló cada socio:


select socio,count(distinct 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;

70 - join con más de dos tablas.


Podemos hacer un "join" con más de dos tablas.

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".

En la tabla "prestamos" haremos referencia al libro y al socio que lo solicita


colocando un código que los identifique. Veamos:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(20) default 'Desconocido',
primary key (codigo)
);
create socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key (numero)
);
create table prestamos(
documento char(8) not null,
codigolibro int unsigned,
fechaprestamo date not null,
fechadevolucion date,
primary key (codigolibro,fechaprestamo)
);

380
Al recuperar los datos de los prestamos:

select * from 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.

Hacemos un "join" (unión):

select nombre,titulo,fechaprestamo
from prestamos as p
join socios as s
on s.documento=p.documento
join libros as l
on codigolibro=codigo;

Analicemos la consulta anterior. Indicamos el nombre de la tabla luego del "from"


("prestamos"), unimos esa tabla con la tabla "socios" especificando con "on" el
campo por el cual se combinarán: el campo "documento" de ambas tablas; luego
debemos hacer coincidir los valores para la unión con la tabla "libros"
enlazándolas por los campos "codigolibro" y "codigo" de "libros". Utilizamos alias
para una sentencia más sencilla y comprensible.

Note que especificamos a qué tabla pertenece el campos "documento" porque a


ese nombre de campo lo tienen las tablas "prestamos" y "socios", esto es
necesario para evitar confusiones y ambiguedades al momento de referenciar un
campo. En este ejemplo, si omitimos la referencia a las tablas al nombrar el campo
"documento" aparece un mensaje de error indicando que "documento" es
ambiguo.

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".

En la tabla "prestamos" se hace referencia al libro y al socio que lo solicita


colocando un código que los identifique.

Eliminamos las tablas, si existen.

Creamos las tablas:


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)
);
Ingresamos algunos registros:
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');

insert into libros values(1,'Manual de 2º grado','Molina Manuel');


insert into libros values(25,'Aprenda PHP','Oscar Mendez');
insert into libros values(42,'Martin Fierro','Jose Hernandez');

insert into prestamos values('22333444',1,'2006-08-10','2006-08-12');


insert into prestamos values('22333444',1,'2006-08-15',null);
insert into prestamos values('25333444',25,'2006-08-10','2006-08-13');
insert into prestamos values('25333444',42,'2006-08-10',null);

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');

Al recuperar los datos de los prestamos:


select * from 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.

Hacemos un "join" (unión):


select nombre,titulo,fechaprestamo
from prestamos as p
join socios as s
on s.documento=p.documento
join libros as l
on codigolibro=codigo;

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');

insert into libros values(1,'Manual de 2º grado','Molina Manuel');


insert into libros values(25,'Aprenda PHP','Oscar Mendez');
insert into libros values(42,'Martin Fierro','Jose Hernandez');

insert into prestamos values('22333444',1,'2006-08-10','2006-08-12');


insert into prestamos values('22333444',1,'2006-08-15',null);
insert into prestamos values('25333444',25,'2006-08-10','2006-08-13');
insert into prestamos values('25333444',42,'2006-08-10',null);
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');
select * from prestamos;
select nombre,titulo,fechaprestamo
from prestamos as p
join socios as s
on s.documento=p.documento
join libros as l
on codigolibro=codigo;
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;
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;

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.

1- Elimine las tablas si existen.

2- Créelas con las siguientes estructuras:


create table peliculas (
codigo smallint unsigned auto_increment,
titulo varchar(30) not null,
actores varchar(40),
duracion tinyint unsigned,
primary key (codigo)
);
create table socios(
codigo smallint unsigned auto_increment,
documento char(8),
nombre varchar(30),
domicilio varchar(30),
primary key (codigo)
);
create table alquileres(
codigopelicula smallint unsigned not null,
codigosocio smallint unsigned not null,
fechaprestamo date not null,
fechadevolucion date,
primary key (codigopelicula,fechaprestamo)
);
3- Ingrese los siguientes registros para las 3 tablas.
insert into peliculas (titulo,actores,duracion)
values('Elsa y Fred','China Zorrilla',90);
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);

insert into socios (documento,nombre)


values('22333444','Juan Lopez');
insert into socios (documento,nombre)
values('23333444','Diana Perez');

385
insert into socios (documento,nombre)
values('24333444','Luis Fuentes');

insert into alquileres (codigopelicula,codigosocio,fechaprestamo)


values(1,1,'2006-07-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(2,1,'2006-07-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(3,1,'2006-07-12');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(1,2,'2006-08-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(3,2,'2006-08-12');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(4,2,'2006-08-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(1,3,'2006-09-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(2,3,'2006-08-02');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(3,3,'2006-08-15');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(4,3,'2006-08-22');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(4,1,'2006-08-25');
insert into alquileres (codigopelicula,codigosocio,fechaprestamo)
values(1,3,'2006-08-25');

4- Muestre toda la información de los "alquileres" (nombre de la película, nombre


del socio, fecha de préstamo y de devolución):
select titulo,nombre,fechaprestamo,fechadevolucion from alquileres as a
join peliculas as p
on a.codigopelicula=p.codigo
join socios as s
on s.codigo=a.codigosocio;

5- Muestre la cantidad de veces que se alquiló cada película:


select p.titulo,count(*) from peliculas as p
join alquileres as a
on p.codigo=a.codigopelicula
group by p.titulo;

6- Muestre la cantidad de películas que alquiló cada socio:


select s.nombre,count(a.codigopelicula) from socios as s
join alquileres as a
on s.codigo=a.codigosocio
group by s.nombre;

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:

Un club de dicta clases de distintos deportes a sus socios. Guarda la información


de sus socios en una tabla llamada "socios", los datos de los deportes en
"deportes" y las inscipciones en "incriptos".

1- Elimine las 3 tablas, si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30) not null,
primary key(documento)
);
create table deportes(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
primary key(codigo)
);
create table inscriptos(
documento char(8) not null,
codigodeporte tinyint unsigned,
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:
insert into socios values('22333444','Juan Perez');
insert into socios values('23333444','Ana Garcia');

387
insert into socios values('24333444','Hector Fuentes');
insert into socios values('25333444','Marta Molina');

insert into deportes (nombre) values('tenis');


insert into deportes (nombre) values('natacion');
insert into deportes (nombre) values('basquet');
insert into deportes (nombre) values('voley');

insert into inscriptos values('22333444',1,'2005','s');


insert into inscriptos values('22333444',1,'2006','s');
insert into inscriptos values('22333444',2,'2005','s');
insert into inscriptos values('24333444',1,'2005','s');
insert into inscriptos values('24333444',2,'2006','s');
insert into inscriptos values('25333444',1,'2005','s');
insert into inscriptos values('25333444',1,'2006','s');
insert into inscriptos values('25333444',3,'2006','s');

4- Muestre el nombre del socio, el deporte en el cual se ha inscripto y el año de


inscripción usando "join":
select s.nombre,d.nombre,i.año
from inscriptos as i
join socios as s
on s.documento=i.documento
join deportes as d
on d.codigo=i.codigodeporte;

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;

7- Muestre la cantidad de socios inscriptos en cada deporte:


select d.nombre,count(i.codigodeporte)
from deportes as d

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;

8- Muestre los distintos socios que se inscribieron en el año "2006":


select distinct s.nombre
from inscriptos as i
join socios as s
on s.documento=i.documento
where año='2006';

B) 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.

1- Elimine las 3 tablas, si existen:


drop table carreras, materias, inscriptos;

2- Cree las tablas con las siguientes estructuras:


create table carreras(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
primary key(codigo)
);
create table materias(
codigo tinyint unsigned auto_increment,
codigocarrera tinyint unsigned,
nombre varchar(30),
profesor varchar(30),
primary key(codigo,codigocarrera)
);
create table inscriptos(
documento char(8) not null,
codigocarrera tinyint unsigned,
codigomateria tinyint unsigned,
año year,
cuota char(1),/* si esta paga o no*/
primary key (documento,codigocarrera,codigomateria,año)
);
3- Ingrese algunos registros:
insert into carreras values(1,'Analista de sistemas');
insert into carreras values(2,'Diseñador web');

insert into materias values(1,1,'Programacion I','Alfredo Lopez');

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');

insert into inscriptos values('22333444',1,1,'2005','s');


insert into inscriptos values('22333444',1,2,'2005','s');
insert into inscriptos values('22333444',1,3,'2006','n');
insert into inscriptos values('23222222',1,1,'2005','s');
insert into inscriptos values('23222222',1,2,'2006','s');
insert into inscriptos values('24555666',1,1,'2005','s');
insert into inscriptos values('24555666',2,1,'2005','s');
insert into inscriptos values('25000999',1,1,'2005','s');
insert into inscriptos values('25000999',1,2,'2005','s');
insert into inscriptos values('25000999',2,1,'2006','n');
insert into inscriptos values('25000999',2,2,'2006','s');

4- Muestre el nombre de las materias, a qué carrera pertenecen y el nombre del


profesor que las dicta ordenadas por carrera:
select c.nombre, m.nombre,m.profesor
from materias as m
join carreras as c
on c.codigo=m.codigocarrera
order by c.nombre;

5- Muestre el nombre de los profesores y la cantidad de materias que dicta cada


uno:
select m.profesor,count(*) as cantidad
from materias as m
group by m.profesor;

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;

10- Muestre la cantidad de alumnos distintos inscriptos en la institución:


select count(distinct documento) from inscriptos;

11- Muestre la cantidad de alumnos que no pagaron la cuota, por carrera y


materia:
select c.nombre,m.nombre,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
where i.cuota='n'
group by c.nombre,m.nombre;

391
71 - Función de control if con varias tablas.

Podemos emplear "if" y "case" en la misma sentencia que usamos un "join".

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;

Podemos obtener una salida similar usando "case" en lugar de "if":

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.

Eliminamos las tablas, si existen:


drop table if exists libros, editoriales;

Creamos las tablas:


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)
);

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');

Ingresamos algunos registros en la tabla "libros":


insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia en el pais de las maravillas','Lewis Carroll',1,23.5);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia a traves del espejo','Lewis Carroll',2,25);
insert into libros (titulo, autor,codigoeditorial,precio)
values('El aleph','Borges',2,15);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Matemática estas ahi','Paenza',1,10);

Queremos saber si hay libros de cada una de las editoriales, necesitamos


consultar ambas tablas:
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;

Podemos obtener una salida similar usando "case" en lugar de "if":


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;

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)
);

393
insert into editoriales (nombre) values ('Planeta');
insert into editoriales (nombre) values ('Emece');
insert into editoriales (nombre) values ('Paidos');

insert into libros (titulo, autor,codigoeditorial,precio)


values('Alicia en el pais de las maravillas','Lewis Carroll',1,23.5);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Alicia a traves del espejo','Lewis Carroll',2,25);
insert into libros (titulo, autor,codigoeditorial,precio)
values('El aleph','Borges',2,15);
insert into libros (titulo, autor,codigoeditorial,precio)
values('Matemática estas ahi','Paenza',1,10);

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:

Un profesor guarda los promedios de sus alumnos de un curso en una tabla


llamada "alumnos" y las
notas de los mismos en la tabla "notas".

1- Elimine las tablas si existen.

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');

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);

No todos los alumnos tienen la misma cantidad de notas porque algunos


presentaron trabajos extras o no asistieron a los examenes.

4- Muestre el documento del alumno, su nombre y el promedio; si el alumno tiene


un promedio menor a 4, muestre un mensaje "reprobado", si el promedio es mayor
o igual a 4 y menor a 7, muestre "regular", si el promedio es mayor a 7, muestre
"promocionado", usando "case":
select a.documento,a.nombre,avg(nota),
case when avg(nota)<4 then 'reprobado'
when avg(nota)>=4 and avg(nota)<7 then 'regular'
else 'promocionado' end as condicion
from alumnos as a
join notas as n
on a.documento=n.documento
group by n.documento;

5- Muestre el documento y nombre del alumno y con un "if" si el alumno está


aprobado o no:
select a.documento,a.nombre,
if (avg(nota)>=4,'si','no') as aprobado
from alumnos as a
join notas as n
on a.documento=n.documento
group by n.documento;

6- Muestre el documento, nombre del alumno y con un "case", si tiene 1 nota, 2


notas o más de 2 notas:
select a.documento,a.nombre,
case count(*)
when 1 then '1 nota'
when 2 then '2 notas'
else 'mas de 2' end as 'cantidad de notas'
from alumnos as a

395
join notas as n
on a.documento=n.documento
group by n.documento
order by 'cantidad de notas';

72 - Variables de usuario.

Cuando buscamos un valor con las funciones de agrupamiento, por ejemplo


"max()", la consulta nos devuelve el máximo valor de un campo de una tabla, pero
no nos muestra los valores de otros campos del mismo registro. Por ejemplo,
queremos saber todos los datos del libro con mayor precio de la tabla "libros" de
una librería, tipeamos:

select max(precio) from libros;

Para obtener todos los datos del libro podemos emplear una variable para
almacenar el precio más alto:

select @mayorprecio:=max(precio) from libros;

y luego mostrar todos los datos de dicho libro empleando la variable anterior:

select * from libros


where precio=@mayorprecio;

Es decir, guardamos en la variable el precio más alto y luego, en otra sentencia,


mostramos los datos de todos los libros cuyo precio es igual al valor de la variable.

Las variables nos permiten almacenar un valor y recuperarlo más adelante, de


este modo se pueden usar valores en otras sentencias.

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.

Para almacenar un valor en una variable se coloca ":=" (operador de asignación)


entre la variable y el valor a asignar.

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;

La utilidad de las variables consiste en que almacenan valores para utilizarlos en


otras consultas.

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 @mayorprecio:=max(precio) from libros;

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.

Eliminamos las tablas si existen:


drop table if exists libros, editoriales;

Creamos las tablas:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(20),
codigoeditorial tinyint unsigned,
precio decimal(5,2) unsigned,
primary key(codigo)
);
create table editoriales(
codigo tinyint unsigned auto_increment,
nombre varchar(20),
primary key(codigo)
);

397
Ingresamos algunos registros:
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');

insert into libros values (1,'El aleph','Borges',2,23);


insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,12);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,34);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,55);
insert into libros values (6,'Aprenda PHP','Molina Mario',1,45);
insert into libros values (7,'Java en 10 minutos','Molina Mario',3,42);

Guardamos en una variable el valor de precio más alto:


select @mayorprecio:=max(precio) from libros;

Mostramos todos los datos de dicho libro empleando la variable anterior:


select * from libros
where precio=@mayorprecio;

Empleamos ahora un "join" para ver, además, el nombre de la editorial:


select l.titulo,l.autor,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
where l.precio = @mayorprecio;

Queremos ver todos los libros de la editorial que tenga el libro más caro.

Almacenamos el precio más alto en una variable llamada "@mayorprecio":


select @mayorprecio:=max(precio) from libros;

Luego almacenamos el nombre de la editorial del libro en la variable denominada


"@editorial":
select @editorial:=e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
where precio=@mayorprecio;

Finalmente buscamos todos los libros de la editorial igual a la variable "@editorial":


select l.titulo,l.autor,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo

398
where e.nombre=@editorial;

drop table if exists libros, editoriales;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(20),
codigoeditorial tinyint unsigned,
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 values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');

insert into libros values (1,'El aleph','Borges',2,23);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,12);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,34);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,55);
insert into libros values (6,'Aprenda PHP','Molina Mario',1,45);
insert into libros values (7,'Java en 10 minutos','Molina Mario',3,42);

select @mayorprecio:=max(precio) from libros;


select * from libros
where precio=@mayorprecio;
select l.titulo,l.autor,e.nombre
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
where l.precio = @mayorprecio;
select @mayorprecio:=max(precio) from libros;
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;

399
Problema:

Un video club que alquila películas en video guarda información de sus películas
en la
tabla "peliculas".

1- Elimine la tabla si existe.

2- Créela con la siguiente estructura:


create table peliculas (
codigo smallint unsigned auto_increment,
titulo varchar(30) not null,
actor varchar(30),
duracion tinyint unsigned,
primary key (codigo)
);
3- Ingrese los siguientes registros para las 3 tablas.
insert into peliculas (titulo,actor,duracion)
values('Elsa y Fred','China Zorrilla',90);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible','Tom Cruise',120);
insert into peliculas (titulo,actor,duracion)
values('Mision imposible 2','Tom Cruise',180);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la piedra filosofal','Daniel H.',120);
insert into peliculas (titulo,actor,duracion)
values('Harry Potter y la camara secreta','Daniel H.',150);

4- Guarde en dos variables el valor de duración de la película más larga y el de la


más corta:
select @mayorduracion:=max(duracion), @menorduracion:= min(duracion) from
peliculas;

5- Muestre todos los datos de ambas peliculas;


select * from peliculas
where duracion=@mayorduracion or
duracion=@menorduracion;

6- Guarde en una variable el nombre del actor de la película de mayor duración:


select @actor:=actor
from peliculas
where duracion=@mayorduracion;

7- Muestre todas las películas en las cuales trabaja el autor almacenado en la


variable "@actor":
select * from peliculas
where actores=@actor;

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.

La tabla "libros" tiene esta estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(40) not null,
-autor: varchar(30),
-editorial: varchar(20) not null,
-precio: decimal(5,2) unsigned,
-clave primaria: codigo.

La tabla "editoriales", que no existe, debe tener la siguiente estructura:

-nombre: nombre de la editorial.

La tabla libros contiene varios registros.

Para guardar en "editoriales" los nombres de las editoriales, podemos hacerlo en 3


pasos:

1º paso: crear la tabla "editoriales":

create table editoriales(


nombre varchar(20)
);

2º paso: realizar la consulta en la tabla "libros" para obtener los nombres de las
distintas editoriales:

select distinct editorial as nombre


from libros;

obteniendo una salida como la siguiente:

editorial
_________
Emece
Paidos
Planeta

401
3º paso: insertar los registros necesarios en la tabla "editoriales":

insert into editoriales (nombre) values('Emece');


insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Planeta');

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:

create table editoriales


select distinct editorial as nombre
from libros;

La tabla "editoriales" se ha creado con el campo llamado "nombre" seleccionado


del campo "editorial" de "libros".

Entonces, se realiza una consulta de la tabla "libros" y anteponiendo "create table


..." se ingresa el resultado de dicha consulta en la tabla "editoriales" al momento
de crearla.

Si seleccionamos todos los registros de la tabla "editoriales" aparece lo siguiente:

nombre
______
Emece
Paidos
Planeta

Si visualizamos la estructura de "editoriales" con "describe editoriales" 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. Veamos un ejemplo.

Tenemos la misma tabla "libros" y queremos crear una tabla llamada


"librosporeditorial" que contenga la cantidad de libros de cada editorial.

La tabla "cantidadporeditorial", que no está creada, debe tener la siguiente


estructura:

-nombre: nombre de la editorial,


-cantidad: cantidad de libros.

402
Podemos lograrlo en 3 pasos:

1º paso: crear la tabla "cantidadporeditorial":

create table editoriales(


nombre varchar(20),
cantidad smallint
);

2º paso: realizar la consulta en la tabla "libros" para obtener la cantidad de libros


de cada editorial agrupando por "editorial" y calculando la cantidad con "count()":

select editorial,count(*)
from libros
group by editorial;

obteniendo una salida como la siguiente:

nombre cantidad
________________
Emece 3
Paidos 4
Planeta 2

3º paso: insertar los registros necesarios en la tabla "editoriales":

insert into cantidadporeditorial values('Emece',3);


insert into cantidadporeditorial values('Paidos',4);
insert into cantidadporeditorial values('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:

create table cantidadporeditorial


select editorial as nombre,count(*) as cantidad
from libros
group by editorial;

La tabla "cantidadporeditorial" se ha creado con el campo llamado "nombre"


seleccionado del campo "editorial" de "libros" y con el campo "cantidad" con el
valor calculado con count() de la tabla "libros".

Entonces, se realiza una consulta de la tabla "libros" y anteponiendo "create table


..." se ingresa el resultado de dicha consulta en la tabla "cantidadporeditorial" al
momento de crearla.

403
Si seleccionamos todos los registros de la tabla "cantidadporeditorial" aparece lo
siguiente:

nombre cantidad
_______________________
Emece 3
Paidos 4
Planeta 2

Si visualizamos la estructura de "cantidadporeditorial" con "describe


cantidadporeditorial", vemos que el campo "nombre" se creó con el mismo tipo y
longitud del campo "editorial" de "libros" y el campo "cantidad" se creó como
"bigint".

Ejemplo:
Tenemos la tabla "libros" de una librería y queremos crear una tabla llamada
"editoriales" que contenga los nombres de las editoriales.

Eliminamos las tablas "libros" y "editoriales", si existen:


drop table if exists libros, editoriales;

Creamos la tabla "libros" con la siguiente estructura:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) not null default 'Desconocido',
editorial varchar(20) not null,
precio decimal(5,2) unsigned,
primary key (codigo)
);
La tabla "editoriales" debe tener la siguiente estructura:

-nombre: nombre de la editorial.

No la creamos aún.

Ingresamos algunos registros para "libros":

insert into libros values (1,'El aleph','Borges','Emece',23.5);


insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);
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);

404
insert into libros values (9,'Antologia poetica','Borges','Paidos',47.9);

Podemos lograrlo en 3 pasos: 1º) crear la tabla "editoriales", 2º) realizar la


consulta en la tabla "libros" para obtener los nombres de las distintas editoriales y
3º) insertar los registros necesarios en la tabla "editoriales".

Pero lo haremos de la manera simplificada. Crearemos la tabla "editoriales" con el


campo necesario consultando la tabla "libros" y en el mismo momento
insertaremos la información:
create table editoriales
select distinct editorial as nombre
from libros;

La tabla "editoriales" se ha creado con el campo llamado "nombre" seleccionado


del campo "editorial" de "libros".

Seleccionamos todos los registros de la tabla "editoriales":


select * from editoriales;

Visualicemos la estructura de "editoriales":


describe editoriales;

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.

Queremos crear una tabla llamada "cantidadporeditorial" que contenga la cantidad


de libros de cada editorial.

Eliminamos la tabla "cantidadporeditorial" si existe:


drop table if exists cantidadporeditorial;

La tabla "cantidadporeditorial" debe tener la siguiente estructura:

-nombre: nombre de la editorial,


-cantidad: cantidad de libros.

No la creamos aún.

Podemos lograrlo en 3 pasos: 1º) crear la tabla "cantidadporeditorial", 2º) realizar


la consulta en la tabla "libros" para obtener la cantidad de libros de cada editorial
agrupando por "editorial" y calculando la cantidad con "count()", 3º) insertar los
registros necesarios en la tabla "cantidadporeditorial" con "insert into".

Pero lo haremos de la manera simplificada.

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;

La tabla "cantidadporeditorial" se ha creado con el campo llamado "nombre"


seleccionado del campo "editorial" de "libros" y con el campo "cantidad" con el
valor calculado con count() de la tabla "libros".

Seleccionamos los registros de la tabla "cantidadporeditorial":


select * from cantidadporeditorial;

Visualizamos la estructura de "cantidadporeditorial":


describe cantidadporeditorial;

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',
editorial varchar(20) not null,
precio decimal(5,2) unsigned,
primary key (codigo)
);
insert into libros values (1,'El aleph','Borges','Emece',23.5);
insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);
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);
create table editoriales
select distinct editorial as nombre
from libros;
select * from editoriales;
describe editoriales;
drop table if exists cantidadporeditorial;
create table cantidadporeditorial
select editorial as nombre,count(*) as cantidad
from libros
group by editorial;
select * from cantidadporeditorial;
describe cantidadporeditorial;

406
Problema:

Un comercio guarda la información de sus ventas en una tabla llamada "facturas".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table facturas(
numero int(10) zerofill auto_increment,
numeroitem smallint unsigned not null,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (numero,numeroitem)
);
3- Ingrese algunos registros:
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,1,'escuadra 20 cm.',2.50,20);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,2,'escuadra 50 cm.',5,30);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,3,'goma lapiz-tinta',0.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,1,'lapices coloresx6',4.40,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,2,'lapices coloresx12',8,60);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(255,1,'lapices coloresx24',12.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,1,'compas plastico',12,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,2,'compas metal',18.90,80);

4- Se quiere guardar la siguiente información en una tabla denominada


"montofacturas":
-numero: número de factura,
-total: total en dinero de todos los items de cada factura (precioporunidad x
cantidad).

5- Elimine la tabla "montofacturas" si existe.

6- Realice una consulta de la tabla "facturas", agrupando por "numero", en la cual


aparezca el número de factura y el monto total de todos sus items:
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;

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;

8- Muestre todos los registros de la tabla "montofacturas".

9- Visualice la estructura de la nueva tabla creada.

74 - Crear tabla a partir de otras (create - insert - join)


Tenemos las tablas "libros" y "editoriales" y queremos crear una tabla llamada
"cantidadporeditorial" que contenga la cantidad de libros de cada editorial.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(40) not null,
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-precio: decimal(5,2) unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene esta estructura:

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
clave primaria: codigo.

Las tablas "libros" y "editoriales" contienen varios registros.

La tabla "cantidadporeditorial", que no existe, debe tener la siguiente estructura:

-nombre: nombre de la editorial,


-cantidad: cantidad de libros.

Podemos guardar en la tabla "cantidadporeditorial" la cantidad de libros de cada


editorial en 3 pasos:

408
1º paso: crear la tabla "cantidadporeditorial":

create table cantidadporeditorial(


nombre varchar(20),
cantidad smallint
);

2º paso: realizar la consulta en la tabla "libros" y "editoriales", con un "join" para


obtener la cantidad de libros de cada editorial agrupando por el nombre de la
editorial y calculando la cantidad con "count()":

select e.nombre,count(*)
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
group by e.nombre;

obteniendo una salida como la siguiente:

nombre cantidad
___________________
Emece 3
Paidos 4
Planeta 2

3º paso: insertar los registros necesarios en la tabla "editoriales":

insert into editoriales values('Emece',3);


insert into editoriales values('Paidos',4);
insert into editoriales values('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:

create table cantidadporeditorial


select e.nombre,count(*) as cantidad
from libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
group by e.nombre;

La tabla "cantidadporeditorial" se ha creado con el campo llamado "nombre"


seleccionado del campo "nombre" de "editoriales" y con el campo "cantidad" con el
valor calculado con count() de la tabla "libros".

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.

Si seleccionamos todos los registros de la tabla "cantidadporeditorial" aparece lo


siguiente:

nombre cantidad
_______________________
Emece 3
Paidos 4
Planeta 2

Si visualizamos la estructura de "cantidadporeditorial", vemos que el campo


"nombre" se creó con el mismo tipo y longitud del campo "nombre" de "editoriales"
y el campo "cantidad" se creó como "bigint".

Ejemlo:
Tenemos la tabla "libros" de una librería y queremos crear una tabla llamada
"editoriales" que contenga los nombres de las editoriales.

Eliminamos las tablas "libros" y "editoriales", si existen:


drop table if exists libros, editoriales;

Creamos la tabla "libros" con la siguiente estructura:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40) not null,
autor varchar(30) not null default 'Desconocido',
editorial varchar(20) not null,
precio decimal(5,2) unsigned,
primary key (codigo)
);
La tabla "editoriales" debe tener la siguiente estructura:

-nombre: nombre de la editorial.

No la creamos aún.

Ingresamos algunos registros para "libros":


insert into libros values (1,'El aleph','Borges','Emece',23.5);
insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);

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);

Podemos lograrlo en 3 pasos: 1º) crear la tabla "editoriales", 2º) realizar la


consulta en la tabla "libros" para obtener los nombres de las distintas editoriales y
3º) insertar los registros necesarios en la tabla "editoriales".

Pero lo haremos de la manera simplificada. Crearemos la tabla "editoriales" con el


campo necesario consultando la tabla "libros" y en el mismo momento
insertaremos la información:
create table editoriales
select distinct editorial as nombre
from libros;

La tabla "editoriales" se ha creado con el campo llamado "nombre" seleccionado


del campo "editorial" de "libros".

Seleccionamos todos los registros de la tabla "editoriales":


select * from editoriales;

Visualicemos la estructura de "editoriales":


describe editoriales;

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.

Queremos crear una tabla llamada "cantidadporeditorial" que contenga la cantidad


de libros de cada editorial.

Eliminamos la tabla "cantidadporeditorial" si existe:


drop table if exists cantidadporeditorial;

La tabla "cantidadporeditorial" debe tener la siguiente estructura:

-nombre: nombre de la editorial,


-cantidad: cantidad de libros.

No la creamos aún.

Podemos lograrlo en 3 pasos: 1º) crear la tabla "cantidadporeditorial", 2º) realizar


la consulta en la tabla "libros" para obtener la cantidad de libros de cada editorial
agrupando por "editorial" y calculando la cantidad con "count()", 3º) insertar los
registros necesarios en la tabla "cantidadporeditorial" con "insert into".

411
Pero lo haremos de la manera simplificada.

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;

La tabla "cantidadporeditorial" se ha creado con el campo llamado "nombre"


seleccionado del campo "editorial" de "libros" y con el campo "cantidad" con el
valor calculado con count() de la tabla "libros".

Seleccionamos los registros de la tabla "cantidadporeditorial":


select * from cantidadporeditorial;

Visualizamos la estructura de "cantidadporeditorial":


describe cantidadporeditorial;

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',
editorial varchar(20) not null,
precio decimal(5,2) unsigned,
primary key (codigo)
);
insert into libros values (1,'El aleph','Borges','Emece',23.5);
insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);
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);
create table editoriales
select distinct editorial as nombre
from libros;
select * from editoriales;
describe editoriales;
drop table if exists cantidadporeditorial;
create table cantidadporeditorial
select editorial as nombre,count(*) as cantidad
from libros
group by editorial;
select * from cantidadporeditorial;

describe cantidadporeditorial;

412
Problema:

Un comercio guarda la información de sus ventas en una tabla llamada "facturas".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table facturas(
numero int(10) zerofill auto_increment,
numeroitem smallint unsigned not null,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (numero,numeroitem)
);
3- Ingrese algunos registros:
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,1,'escuadra 20 cm.',2.50,20);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,2,'escuadra 50 cm.',5,30);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,3,'goma lapiz-tinta',0.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,1,'lapices coloresx6',4.40,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,2,'lapices coloresx12',8,60);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(255,1,'lapices coloresx24',12.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,1,'compas plastico',12,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,2,'compas metal',18.90,80);

4- Se quiere guardar la siguiente información en una tabla denominada


"montofacturas":
-numero: número de factura,
-total: total en dinero de todos los items de cada factura (precioporunidad x
cantidad).

5- Elimine la tabla "montofacturas" si existe.

6- Realice una consulta de la tabla "facturas", agrupando por "numero", en la cual


aparezca el número de factura y el monto total de todos sus items:
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;

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;

8- Muestre todos los registros de la tabla "montofacturas".

9- Visualice la estructura de la nueva tabla creada.

Otros problemas:

A) Una empresa registra los datos de sus empleados en una tabla llamada
"empleados".

1- Elimine la tabla "empleados" si existe.

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');

4- La empresa necesita almacenar en una tabla llamada "ingresos" la cantidad de


empleados que ingresaron a la empresa por año. Muestre la información desde la
tabla "empleados":
select year(fechaingreso),count(*)
from empleados
group by year(fechaingreso);

5- Elimine la tabla "ingresos" si existe.

6- Cree la tabla "ingresos" consultando la tabla "empleados":


create table ingresos
select year(fechaingreso) as año,
count(*) as cantidad
from empleados
group by year(fechaingreso);

7- Seleccione todos los registros y campos de la tabla "ingresos".

8- Vea la estructura de la tabla "ingresos".

B) Un club dicta clases de distintos deportes a sus socios. Guarda la información


de las inscripciones en una tabla denominada "inscriptos".

1- Elimine la tabla, si existe.

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;

5- El club quiere almacenar esa información en una tabla. Elimine la


tabla "inscriptospordeporteporaño", si existe.

6- Cree la tabla utilizando la consulta del punto 5:


create table inscriptospordeporteporaño
select deporte,año,count(*)
from inscriptos
group by deporte,año;

7- Muestre todos los registros de la nueva tabla.

8- El club desea saber cuántas veces se ha inscripto una persona en algún


deporte:
select documento,count(*)
from inscriptos
group by documento;

9- Elimine la tabla "cantidadinscripcionesporsocio" si existe.

10- Guarde la información anterior en una tabla llamada


"cantidadinscripcionesporsocio", creándola a partir de la consulta del punto 8:
create table cantidadinscripcionesporsocio
select documento,count(*)
from inscriptos
group by documento;

C) Una academia de enseñanza dicta distintos cursos de informática. Los cursos


se dictan por la mañana (de 8 a 12 hs.) o por la tarde (de 16 a 20 hs.), distintos
días a la semana. La academia guarda los datos de los cursos en una tabla
llamada "cursos" en la cual almacena el código del curso, el tema, los días de la
semana que se dicta, el horario, por la mañana (AM) o por la tarde (PM), la
cantidad de clases que incluye cada curso (clases), la fecha de inicio y el costo del
curso.

1- Elimine la tabla si existe.

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);

4- Muestre la cantidad de cursos por horario:


select horario,count(*)
from cursos
group by horario;

5- Elimine la tabla "cantidadcursosporhorario" si existe.

6- Guarde la información obtenida en el punto 4 en una tabla llamada


"cantidadcursosporhorario"
creando la tabla a partir de aquella consulta:
create table cantidadcursosporhorario
select horario,count(*) as cantidad
from cursos
group by horario;

7- Vea todos los registros de la tabla creada anteriormente.

8- Visualice la estructura de la tabla "cantidadcursosporhorario".

417
9- Se quiere saber el promedio de clases por tema:
select tema,avg(clases)
from cursos
group by tema;

10- Elimine la tabla "clasesportema" si existe.

11- Cree la tabla "clasesportema" a partir de la consulta del punto 9:


create table clasesportema
select tema,avg(clases) as promedioclases
from cursos
group by tema;

12- Vea la estructura de la tabla creada anteriormente y realice una consulta


mostrando todos los registros.

13- Muestre los distintos temas de las clases:


select distinct tema
from cursos;

14- Elimine la tabla "temas" si existe.

15- Cree la tabla "temas" a partir de la consulta del punto 12:


create table temas
select distinct tema
from cursos;

16- Vea todos los registros de la tabla creada anteriormente.

D) Un profesor guarda en una tabla llamada "notas" las notas de los alumnos de
un curso.

1- Elimine la tabla "notas" si existe.

2- Cree la tabla con la siguiente estructura:


create table notas(
documento char(8) not null,
nombre varchar(30),
nota decimal(4,2) unsigned
);
Algunos alumnos tienen más notas que otros porque presentaron trabajos
especiales.

3- Ingrese los siguientes registros:


insert into notas values('30333444','Juan Perez',8);
insert into notas values('30433444','Ana Maria Garcia',7.5);

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);

4- El profesor necesita generar una tabla llamada "promedios" que contenga el


documento del alumno y el promedio de sus notas. Cree la tabla con los campos
"documento" y "promedio" realizando la consulta necesaria a la tabla "notas":
create table promedios
select documento,nombre,avg(nota) as promedio
from notas
group by documento;

5- Vea los registros de "promedios".

6- Vea la estructura de la tabla "promedios".

7- Agrupe por documento y seleccione el documento y nombre de los alumnos


aprobados (promedio mayor o igual a 4):
select documento,nombre
from notas
group by documento
having avg(nota)>=4;

8- Elimine la tabla "aprobados" si existe.

9- Cree una tabla llamada "aprobados" donde guarde el resultado de la consulta


anterior, es decir, documento y nombre de los alumnos que pasan de curso por
estar aprobados:
create table aprobados
select documento,nombre
from notas
group by documento
having avg(nota)>=4;

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);

4- Agrupe por documento y muestre el documento del cliente, en una columna


llamada "cantidad" calcule la cantidad de cuentas de cada cliente y en otra
columna llamada "total" calcule la suma de todas las cuentas de cada cliente:
select documento
count(*) as cantidad,
sum(saldo) as total
from cuentas
group by documento;

5- Elimine la tabla "cuentasporcliente", si existe.

6- Cree la tabla "cuentasporcliente" en la cual guarde el documento, la cantidad de


cuentas que tiene en el banco y la suma de las mismas:
create table cuentasporcliente
select documento
count(*) as cantidad,
sum(saldo) as total
from cuentas
group by documento;

7- Vea los registros de "cuentasporcliente".

8-Vea la estructura de la tabla "cuentasporcliente".

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;

5- Elimine la tabla "prestados" si existe.

6- Cree la tabla "prestados" e ingrese al momento de crearla el resultado de la


consulta del punto 4:
create table prestados
select titulo,fechaprestamo
from prestamos
where fechadevolucion is null;

7- Muestre todos los registros de la tabla "prestados".

8- Muestre el documento, la primera fecha de préstamo y cantidad de libros no


devueltos de todos los morosos:
select documento, min(fechaprestamo),count(*)
from prestamos
where fechadevolucion is null
group by documento;

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;

G) Un pequeño restaurante tiene almacenados los nombres, rubros y precios de


sus comidas en una tabla llamada "comidas".

1- Elimine la tabla si existe.

2- Cree la tabla con esta estructura:


create table comidas(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
rubro enum ('entrada','principal','postre'),
precio decimal (5,2) unsigned,
primary key(codigo)
);
3- Ingrese algunos registros:
insert into comidas (nombre,rubro,precio)
values('fiambres',1,2.5);
insert into comidas (nombre,rubro,precio)
values('arroz',1,1.6);
insert into comidas (nombre,rubro,precio)
values('sopa',1,2.4);
insert into comidas (nombre,rubro,precio)
values('milanesa y fritas',2,3.4);
insert into comidas (nombre,rubro,precio)
values('cuarto de pollo',2,2.5);
insert into comidas (nombre,rubro,precio)
values('hamburguesa',2,2.8);
insert into comidas (nombre,rubro,precio)
values('flan',3,1);
insert into comidas (nombre,rubro,precio)
values('porcion de torta',3,2.1);
insert into comidas (nombre,rubro,precio)
values('gelatina',3,0.9);

422
4- Muestre todos los registros:

5- Realice un "cross join" combinando entrada, plato principal y postre:


select c1.nombre,c2.nombre,c3.nombre,
c1.precio+c2.precio+c3.precio as total
from comidas as c1
cross join comidas as c2
cross join comidas as c3
where c1.rubro=1 and
c2.rubro=2 and
c3.rubro=3;

6- Elimine la tabla "menues" si existe.

7- Cree la tabla "menues" para guardar el resultado de la consulta del punto 5:


create table menues
select c1.nombre as entrada,
c2.nombre as principal,
c3.nombre as postre,
c1.precio+c2.precio+c3.precio as total
from comidas as c1
cross join comidas as c2
cross join comidas as c3
where c1.rubro=1 and
c2.rubro=2 and
c3.rubro=3;

8- Visualice la estructura de la tabla "menues".

9- Vea todos los registros de la nueva tabla creada.

75 - Insertar datos en una tabla buscando un valor en otra (insert - select)


Trabajamos con las tablas "libros" y "editoriales" de una librería.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(40) not null,
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-precio: decimal(5,2) unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene la siguiente estructura:

423
-codigo: tinyint unsigned auto_increment,
-nombre: varchar(20),
-domicilio: varchar(30),
-clave primaria: codigo.

Ambas tablas contienen registros. La tabla "editoriales" contiene los siguientes


registros:

1,Planeta,San Martin 222,


2,Emece,San Martin 590,
3,Paidos,Colon 245.

Queremos ingresar en "libros", el siguiente libro: Harry Potter y la piedra filosofal,


J.K. Rowling, Emece, 45.90. , pero no recordamos el código de la editorial
"Emece".

Podemos lograrlo en 2 pasos:

1º paso: consultar en la tabla "editoriales" el código de la editorial "Emece":

select codigo
from editoriales
where nombre='Emece';

nos devuelve el valor "2".

2º paso: ingresar el registro en "libros":

insert into libros (titulo,autor,codigoeditorial,precio)


values('Harry Potter y la piedra filosofal','J.K.Rowling',2,45.90);

O podemos realizar la consulta del código de la editorial al momento de la


inserción:

insert into libros (titulo,autor,codigoeditorial,precio)


select 'Harry Potter y la camara secreta','J.K.Rowling',codigo,45.90
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".

Si la consulta no devuelve ningún valor, porque buscamos el código de una


editorial que no existe en la tabla "editoriales", aparece un mensaje indicando que
no se ingresó ningún registro. Por ejemplo:

insert into libros (titulo,autor,codigoeditorial,precio)


select 'Cervantes y el quijote','Borges',codigo,35
from editoriales
where nombre='Plaza & Janes';

Hay que tener cuidado al establecer la condición en la consulta, el "insert"


ingresará tantos registros como filas retorne la consulta. Si la consulta devuelve 2
filas, se insertarán 2 filas en el "insert". Por ello, el valor de la condición (o
condiciones), por el cual se busca, debe retornar un sólo registro.

Veamos un ejemplo. Queremos ingresar el siguiente registro:

Harry Potter y la camara secreta, J.K. Rowling,54.

pero no recordamos el código de la editorial ni su nombre, sólo sabemos que su


domicilio es en calle "San Martin". Si con un "select" localizamos el código de
todas las editoriales que tengan sede en "San Martin", el resultado retorna 2 filas,
porque hay 2 editoriales en esa dirección ("Planeta" y "Emece"). Tipeeemos la
sentencia:

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%';

Se ingresarán 2 registros con los mismos datos, excepto el código de la editorial.

Recuerde entonces, el valor de la condición (condiciones), por el cual se busca el


dato desconocido en la consulta debe retornar un sólo registro.

También se pueden consultar valores de varias tablas incluyendo en el "select" un


"join". Veremos ejemplos en "Ejercicios propuestos".

Ejemplo:
Trabajamos con las tablas "libros" y "editoriales" de una librería.

Eliminamos las tablas si existen.

Creamos las tablas con las siguientes estructuras:

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)
);

Ingresamos algunos regsitros:


insert into libros values (1,'El aleph','Borges',2,23.5);
insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,12);

insert into editoriales values(1,'Planeta','San Martin 222');


insert into editoriales values(2,'Emece','San Martin 590');
insert into editoriales values(3,'Paidos','Colon 245');

Queremos ingresar en "libros", el siguiente libro:

Harry Potter y la piedra filosofal, J.K. Rowling, Emece, 45.90.

pero no recordamos el código de la editorial "Emece".

Podemos realizar la consulta del código de la editorial al momento de la inserción:

insert into libros (titulo,autor,codigoeditorial,precio)


select 'Harry Potter y la camara secreta','J.K.Rowling',codigo,45.90
from editoriales
where nombre='Emece';

El registro se cargará con el valor de código de la editorial "Emece".

Si buscamos el código de una editorial que no existe en la tabla "editoriales", la


consulta no retornará ningún registro y la inserción no se realizará. Veamos un
ejemplo:
insert into libros (titulo,autor,codigoeditorial,precio)
select 'Cervantes y el quijote','Borges',codigo,35
from editoriales

426
where nombre='Plaza & Janes';

Queremos ingresar el siguiente registro:

Harry Potter y la camara secreta, J.K. Rowling,54.

pero no recordamos el código de la editorial ni su nombre, sólo sabemos que su


domicilio es en calle "San Martin". Si con un "select" localizamos el código de
todas las editoriales que tengan sede en "San Martin", el resultado retorna 2 filas,
porque hay 2 editoriales en esa dirección ("Planeta" y "Emece"). Tipeeemos la
sentencia:
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%';

Veamos qué sucedió:

select * from libros;

ingresó 2 registros con los mismos datos, excepto el código de la editorial.

drop table if exists libros,editoriales;


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)
);
insert into libros values (1,'El aleph','Borges',2,23.5);
insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,12);

insert into editoriales values(1,'Planeta','San Martin 222');


insert into editoriales values(2,'Emece','San Martin 590');
insert into editoriales values(3,'Paidos','Colon 245');

insert into libros (titulo,autor,codigoeditorial,precio)


select 'Harry Potter y la camara secreta','J.K.Rowling',codigo,45.90
from editoriales
where nombre='Emece';

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:

Un club de dicta clases de distintos deportes a sus socios. Guarda la información


de sus socios en una tabla llamada "socios" y las inscripciones en "inscriptos".

1- Elimine las tablas, si existen.

2- Cree las tablas:


create table socios(
numero int unsigned auto_increment,
documento char(8) not null,
nombre varchar(30) not null,
domicilio varchar(30),
primary key(numero)
);
create table inscriptos(
numerosocio int unsigned,
deporte varchar(20),
año year not null,
cuota char(1), /*'s' o 'n', si esta paga o no*/
primary key(numerosocio,deporte,año)
);
3- Ingrese los siguientes registros:
insert into socios values(23,'22333444','Juan Perez','Colon 123');
insert into socios values(56,'23333444','Ana Garcia','Sarmiento 984');
insert into socios values(102,'24333444','Hector Fuentes','Sucre 293');
insert into socios values(150,'25333444','Agustin Perez','Avellaneda 1234');
insert into socios values(230,'26333444','Maria Perez','Urquiza 283');
insert into socios values(231,'29333444','Agustin Perez','Urquiza 283');

insert into inscriptos values(23,'tenis','2005','s');


insert into inscriptos values(23,'tenis','2006','s');
insert into inscriptos values(23,'natacion','2005','s');
insert into inscriptos values(102,'tenis','2005','s');
insert into inscriptos values(102,'natacion','2006','s');

4- El socio con documento "23333444" quiere inscribirse en "basquet" este año,


pero no recuerda su número de socio. Inscriba al socio en la tabla "inscriptos"

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';

5- Intente inscribir una persona cuyo número de documento no exista en la tabla


"socios":
insert into inscriptos (numerosocio,deporte,año,cuota)
select numero,'tenis','2006','s'
from socios
where documento='30333444';
No se realiza la inserción porque no encuentra el documento en la tabla "socios".

6- La madre de los socios "Perez" quiere inscribir a su hijo "Agustín" en "basquet"


este año, pero no recuerda su número de socio ni su documento. Si se busca el
número de socio a partir del nombre ("Agustin Perez"), la consulta retornará 2
registros, porque hay 2 socios llamados "Agustin Perez".
Obtendremos como resultado, la inscripción a "basquet" este año, de ambos
socios. Si localizamos el número de socio a partir del domicilio ("Urquiza 283"),
también obtendremos 2 inscripciones, porque hay 2 socios con ese domicilio.
Ingrese la inscripción del socio, localizando su número de socio con el nombre y
domicilio:
insert into inscriptos (numerosocio,deporte,año,cuota)
select numero,'basquet','2006','n'
from socios
where nombre='Agustin Perez' and
domicilio='Urquiza 283';

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';

8- Vea si las inscripciones anteriores se cargaron:


select s.nombre,i.deporte,i.año
from socios as s
join inscriptos as i
on s.numero=i.numerosocio;

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".

1- Elimine las tablas, si existen.

2- Cree las tablas:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(40),
autor varchar (30),
editorial varchar (15),
primary key (codigo)
);
create table socios(
numero int unsigned auto_increment,
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key (numero)
);
create table prestamos(
codigolibro int unsigned not null,
numerosocio int not null,
fechaprestamo date not null,
fechadevolucion date,
primary key(codigolibro,fechaprestamo)
);

3- Ingrese algunos registros para las 3 tablas:


insert into socios values(20,'20222000','Juan Perez','Colon 123');
insert into socios values(31,'25222111','Juan Perez','Sucre 34');
insert into socios values(52,'25333222','Ana Maria Lopez','Avellaneda 235');
insert into socios values(82,'28333222','Luisa Duarte','San Martin 877');
insert into socios values(90,'29333222','Carlos Fuentes','Rivadavia 864');

insert into libros values (15,'Manual de 1º grado','Moreno Luis','Emece');


insert into libros values (28,'Manual de 2º grado','Moreno Luis','Emece');
insert into libros values (30,'Alicia en el pais de las maravillas','Lewis
Carroll','Planeta');
insert into libros values (35,'El aleph','Borges','Emece');
insert into libros values (36,'Aprenda PHP','Molina Marcos','Planeta');
insert into libros values (40,'Cervantes y el quijote','Borges','Paidos');
insert into libros values (46,'Aprenda Java','Molina Marcos','Planeta');

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');

4- El socio con número de documento "25333222" solicita en préstamos el libro


con código 40. El socio no recuerda su número de socio pero si su documento.
Ingrese el préstamo ubicando el número de socio a partir del documento en
"socios":
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select 40,numero,'2006-09-15'
from socios
where documento='25333222';

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;

7- La biblioteca necesita una tabla en la cual almacene el documento y nombre de


los socios morosos. Elimine la tabla "morosos" si existe:
drop table if exist morosos;

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;

10- El socio con documento "20222000" solicita el préstamo de un libro. El socio


no recuerda su número pero si su documento. Se desea realizar el préstamo sólo
si dicho socio no se encuentra en "morosos". Realice una consulta a la tabla
"socios" y "morosos" que retorne los números de socio de aquellos socios que no
adeudan libros y luego busque en dicho resultado el valor del número de
socio a partir del documento, si encuentra coincidencia, ingresará el registro, en
caso contrario (la persona es un socio es deudor o no es socio), la inserción no se
realiza:
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select 15,s.documento,'2006-07-28'
from socios as s
left join morosos as m
on s.documento=m.documento
where m.documento is null
and s.documento='20222000';
No se realizó la carga del préstamo porque no encontró el documento en el
resultado de la consulta.

11- El socio con documento "29333222" solicita el préstamo de un libro. El socio


no recuerda su número pero si su documento. Se desea realizar el préstamo sólo
si dicho socio no se encuentra en "morosos". Realice una consulta a la tabla
"socios" y "morosos" que retorne los números de socio de aquellos socios que no
adeudan libros y luego busque en dicho resultado el valor del número de
socio a partir del documento:
insert into prestamos (codigolibro,numerosocio,fechaprestamo)
select 36,s.numero,'2006-07-28'
from socios as s
left join morosos as m
on s.documento=m.documento
where m.documento is null
and s.documento='29333222';

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;

15- Cree la tabla a partir de la consulta del punto 13:


create table librosausentes
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;

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.

B) 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.

1- Elimine las 3 tablas, si existen.

2- Cree las tablas con las siguientes estructuras:


create table carreras(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
primary key(codigo)
);
create table materias(
codigo tinyint unsigned auto_increment,
codigocarrera tinyint unsigned,
nombre varchar(30),
profesor varchar(30),
primary key(codigo,codigocarrera)
);
create table inscriptos(
documento char(8) not null,
codigocarrera tinyint unsigned,
codigomateria tinyint unsigned,
año year,
cuota char(1),/* si esta paga o no*/
primary key (documento,codigocarrera,codigomateria,año)
);
3- Ingrese algunos registros:
insert into carreras values(1,'Analista de sistemas');
insert into carreras values(2,'Diseñador web');

insert into materias values(1,1,'Programacion I','Alfredo Lopez');

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');

insert into inscriptos values('22333444',1,1,'2005','s');


insert into inscriptos values('22333444',1,2,'2005','s');
insert into inscriptos values('22333444',1,3,'2006','n');
insert into inscriptos values('23222222',1,1,'2005','s');
insert into inscriptos values('23222222',1,2,'2006','s');
insert into inscriptos values('24555666',1,1,'2005','s');
insert into inscriptos values('24555666',2,1,'2005','s');
insert into inscriptos values('25000999',1,1,'2005','s');
insert into inscriptos values('25000999',1,2,'2005','s');
insert into inscriptos values('25000999',2,1,'2006','n');
insert into inscriptos values('25000999',2,2,'2006','s');

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;

5- Se quiere inscribir un alumno en la materia "Programacion basica" de la carrera


"Diseñador web" pero la secretaria no recuerda los códigos de las mismas.
Inscriba al alumno consultando los valores de las tablas "carreras" y "materias":
insert into inscriptos (documento,codigocarrera,codigomateria,año,cuota)
select '30222333',c.codigo,m.codigo,'2006','s'
from carreras as c
join materias as m
on c.codigo=m.codigocarrera
where c.nombre='Diseñador web' and
m.nombre='Programacion basica';

435
76 - Insertar registros con valores de otra tabla (insert - select)

Tenemos las tabla "libros" y "editoriales" creadas. La tabla "libros" contiene


registros; "editoriales", no.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-editorial: varchar(20),
-precio: decimal(5,2) unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene la siguiente estructura:

-nombre: varchar(20).

Queremos insertar registros en la tabla "editoriales", los nombres de las distintas


editoriales de las cuales tenemos libros.

Podemos lograrlo en 2 pasos, con varias sentencias:

1º paso: consultar los nombres de las distintas editoriales de "libros":

select distinct editorial


from libros;

obteniendo una salida como la siguiente:


editorial
_________
Emece
Paidos
Planeta

2º paso: insertar los registros uno a uno en la tabla "editoriales":

insert into editoriales (nombre) values('Emece');


insert into editoriales (nombre) values('Paidos');
insert into editoriales (nombre) values('Planeta');

O podemos lograrlo en un solo paso, realizando el "insert" y el "select" en una


misma sentencia:

insert into editoriales (nombre)


select distinct editorial from libros;

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.

También podemos crear una tabla llamada "cantidadporeditorial":

create table cantidadporeditorial(


nombre varchar(20),
cantidad smallint unsigned
);

e ingresar registros a partir de una consulta a la tabla "libros":

insert into cantidadporeditorial (nombre,cantidad)


select editorial,count(*) as cantidad
from libros
group by editorial;

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.

La tabla "libros" contiene registros; "editoriales", no.

Eliminamos las tablas, si existen:


drop table if exists libros, editoriales;

Creamos las tablas:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
create table editoriales(
nombre varchar(20)
);

437
Ingresamos algunos registros en la tabla "libros":

insert into libros values (1,'El aleph','Borges','Emece',23.5);


insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);
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);

Queremos insertar registros en la tabla "editoriales", los nombres de las distintas


editoriales de las cuales tenemos libros.

Podemos lograrlo en 2 pasos, con 4 sentencias: 1º) realizar la consulta de los


nombres de las distintas editoriales de "libros" y 2º) insertar los registros uno a uno
en la tabla "editoriales" (3 "insert").

O podemos lograrlo en un solo paso, realizando el "insert" y el "select" en una


misma sentencia:
insert into editoriales (nombre)
select distinct editorial from libros;

Veamos los registros de "editoriales":


select * from editoriales;

Queremos conocer la cantidad de libros por editorial, realizamos una consulta:


select editorial,count(*)
from libros
group by editorial;

Queremos guardar esa información en una tabla llamada "cantidadporeditorial".

Eliminamos la tabla "cantidadporeditorial" si existe:


drop table if exists cantidadporeditorial;

Creamos la tabla "cantidadporeditorial" con la siguiente estructura:


create table cantidadporeditorial(
nombre varchar(20),
cantidad smallint unsigned
);
Recuerde que los campos presentados entre paréntesis deben ser del mismo tipo
y cantidad que las columnas devueltas por la consulta.

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;

aparece un mensaje de error y la sentencia no se ejecuta.

Ingresamos correctamente la información:


insert into cantidadporeditorial (nombre,cantidad)
select editorial,count(*) as cantidad
from libros
group by editorial;

Veamos los registros de la tabla "cantidadporeditorial":


select * from cantidadporeditorial;

los datos fueron cargados correctamente.

drop table if exists libros, editoriales;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(30),
editorial varchar(20),
precio decimal(5,2) unsigned,
primary key(codigo)
);
create table editoriales(
nombre varchar(20)
);
insert into libros values (1,'El aleph','Borges','Emece',23.5);
insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll','Planeta',15);
insert into libros values (3,'Matematica estas ahi','Paenza','Emece',34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez','Paidos',43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez','Planeta',12);
insert into libros values (6,'Aprenda PHP','Mario Molina','Paidos',21.8);
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);

insert into editoriales (nombre)


select distinct editorial from libros;
select * from editoriales;
select editorial,count(*)
from libros
group by editorial;
drop table if exists cantidadporeditorial;

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:

Un comercio guarda la información de sus ventas en una tabla llamada "facturas".

1- Elimine la tabla si existe.

2- Cree la tabla con la siguiente estructura:


create table facturas(
numero int(10) zerofill auto_increment,
numeroitem smallint unsigned not null,
descripcion varchar(30),
precioporunidad decimal(5,2) unsigned,
cantidad tinyint unsigned,
primary key (numero,numeroitem)
);

3- Ingrese algunos registros:


insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,1,'escuadra 20 cm.',2.50,20);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,2,'escuadra 50 cm.',5,30);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(100,3,'goma lapiz-tinta',0.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,1,'lapices coloresx6',4.40,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(102,2,'lapices coloresx12',8,60);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(255,1,'lapices coloresx24',12.35,100);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,1,'compas plastico',12,50);
insert into facturas (numero,numeroitem,descripcion,precioporunidad,cantidad)
values(567,2,'compas metal',18.90,80);

440
4- Elimine la tabla "montofacturas" si existe.

5- Se quiere guardar en una tabla denominada "montofacturas" el número de


factura y el monto total en dinero de todos los items de cada factura
(precioporunidad x cantidad). Cree la tabla con la siguiente estructura:
create table montofacturas(
numero int(10) zerofill,
total decimal(9,2) unsigned,
primary key(numero)
);

6- Realice una consulta de la tabla "facturas", agrupando por "numero", en la cual


aparezca el número de factura y el monto total de todos sus items:
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;

7- Ingrese el resultado de la consulta anterior en la tabla "montofacturas":


insert into montofacturas (numero,total)
select numero,
sum(precioporunidad*cantidad) as total
from facturas
group by numero;

8- Muestre todos los registros de la tabla "montofacturas".

Otros problemas:

A) Un club se dicta clases de distintos deportes a sus socios. Guarda la


información de las inscripciones en una tabla denominada "inscriptos".

1- Elimine la tabla, si existe.

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;

5- El club quiere almacenar esa información en una tabla. Elimine la


tabla "inscriptospordeporteporaño", si existe.

6- Cree la tabla:
create table inscriptospordeporteporaño(
deporte varchar(20),
año year,
cantidad smallint unsigned
);

7- Intente ingresar los registros colocando un campo menos en la lista de campos:


insert into inscriptospordeporteporaño (deporte,cantidad)
select deporte,año,count(*)
from inscriptos
group by deporte,año;
La sentencia no se ejecuta.

8- Intente ingresar los registros colocando los 3 campos de la nueva tabla y


quitándole una columna a la selección:
insert into inscriptospordeporteporaño (deporte,año,cantidad)
select deporte,año
from inscriptos
group by deporte,año;
La sentencia no se ejecuta.

9- Ingrese los registros a partir de la consulta del punto 4, correctamente:


insert into inscriptospordeporteporaño (deporte,año,cantidad)
select deporte,año,count(*)
from inscriptos
group by deporte,año;

10- Muestre todos los registros de la nueva tabla.

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;

12- Elimine la tabla "inscripcionesporpersona" si existe.

13- Cree la tabla con la siguiente estructura:


create table inscripcionesporpersona(
documento char(8),
cantidad tinyint unsigned,
primary key(documento)
);
14- Guarde la información del punto 11 en la tabla recientemente creada:
insert into inscripcionesporpersona (documento,cantidad)
select documento,count(*)
from inscriptos
group by documento;

15- Vea los registros de la nueva tabla.

B) Un profesor guarda en una tabla llamada "notas" las notas de los alumnos de
un curso.

1- Elimine la tabla "notas" si existe.

2- Cree la tabla con la siguiente estructura:


create table notas(
documento char(8) not null,
nombre varchar(30),
nota decimal(4,2) unsigned
);
Algunos alumnos tienen más notas que otros porque presentaron trabajos
especiales.

3- Ingrese los siguientes registros:


insert into notas values('30333444','Juan Perez',8);
insert into notas values('30433444','Ana Maria Garcia',7.5);
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);

443
insert into notas values('30633444','Fabiola Juarez',6.7);

4- El profesor necesita una tabla llamada "promedios" que contenga el documento


y nombre del alumno y el promedio de sus notas. Elimine la tabla "notas" si existe.

5- Cree la tabla con los campos "documento" y "promedio":


create table promedios (
documento char(8) not null,
nombre varchar(30),
promedio decimal(4,2),
primary key(documento)
);
6- Realice la consulta necesaria a la tabla "notas":
select documento,nombre,avg(nota) as promedio
from notas
group by documento;

7- Ingrese el resultado de la consulta anterior en la tabla "promedios":


insert into promedios (documento,nombre,promedio)
select documento,nombre,avg(nota)
from notas
group by documento;

8- Vea los registros de "promedios".

9- Agrupe por documento y seleccione el documento y nombre de los alumnos


aprobados (promedio mayor o gual a 4):
select documento,nombre
from notas
group by documento
having avg(nota)>=4;

10- Elimine la tabla "aprobados" si existe.

11- Cree una tabla llamada "aprobados" con la siguiente estructura:


create table aprobados(
numero tinyint unsigned auto_increment,
documento char(8),
nombre varchar(30),
primary key (numero)
);
12- Ingrese los registros resultado de la consulta del punto 9 en la tabla creada
anteriormente:
insert into aprobados (documento,nombre)
select documento,nombre
from notas
group by documento

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.

14- Muestre el documento y nombre del alumno y en una columna informe si el


alumno está aprobado (promedio de notas mayor o igual a 4) o desaprobado
(promedio menor a 4), empleando un "if" en una consulta a la tabla "notas" :
select documento,nombre,
if (avg(nota)>4,'aprobado','desaprobado') as condicion
from notas
group by documento;

15- Elimine la tabla "condicion" si existe.

16- Cree la tabla "condicion" con la siguiente estructura:


create table condicion(
documento char(8) not null,
nombre varchar(30),
condicion varchar(15)
);
17- Ingrese registros en la tabla creada anteriormente a partir de la consulta del
punto 14:
insert into condicion (documento,nombre,condicion)
select documento,nombre,
if (avg(nota)>4,'aprobado','desaprobado')
from notas
group by documento;

18- Vea todos los registros de la tabla "condicion".

C) Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla
llamada "cuentas".

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)
);

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);

4- Agrupe por documento y muestre el documento del cliente, en una columna


llamada "cantidad" calcule la cantidad de cuentas de cada cliente y en otra
columna llamada "total" calcule la suma de todas las cuentas de cada cliente:
select documento
count(*) as cantidad,
sum(saldo) as total
from cuentas
group by documento;

5- Elimine la tabla "cuentasporcliente", si existe.

6- Cree la tabla "cuentasporcliente" con la siguiente estructura:


create table cuentasporcliente(
numero int unsigned auto_increment,
documento char(8),
cantidad tinyint unsigned,
total decimal(9,2) unsigned,
primary key(numero)
);
7- Inserte el resultado de la consulta del punto 4 en la tabla creada anteriormente:
insert into cuentasporcliente (documento,cantidad,total)
select documento,count(*),sum(saldo)
from cuentas
group by documento;

8- Vea los registros de "cuentasporcliente".

D) Una agencia matrimonial almacena la información de sus clientes en una tabla


llamada "clientes".

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
);

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);

4- La agencia necesita la combinación de todas las personas de sexo femenino


con las de sexo masculino. Además, las edades de las posibles parejas no deben
tener una diferencia superior a 10 años. Use "cross join":
select f.nombre,f.edad,
m.nombre,m.edad
from clientes as f
cross join clientes as m
where f.sexo='f' and m.sexo='m' and
m.edad - f.edad between -10 and 10;

5- La agencia quiere organizar encuentros entre dichas parejas. Elimine la tabla


"encuentros" si existe.

6- Cree la tabla "encuentros" con la siguiente estructura:


create table encuentros(
codigo tinyint unsigned auto_increment,
dama varchar(30),
edaddama tinyint unsigned,
caballero varchar(30),
edadcaballero tinyint unsigned,
fecha date,
primary key (codigo)
);
7- Inserte las parejas resultado de la consulta del punto 4:
insert into encuentros (dama,edaddama,caballero,edadcaballero)
select f.nombre,f.edad,m.nombre,m.edad
from clientes as f
cross join clientes as m
where f.sexo='f' and m.sexo='m' and
m.edad - f.edad between -10 and 10;

8- Vea la información que se almacenó en "encuentros":


select * from encuentros;
Note que el código se cargó automáticamente y en las fechas de encuentro
contienen todas el
valor "null" para luego ser llenadas.

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.

1- Elimine la tabla, si existe.

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');

4- Realice un "cross join" combinando los distintos equipos y sedes de encuentro:


select e1.nombre,e2.nombre,e1.barrio as 'sede'
from equipos as e1
cross join equipos as e2
where e1.nombre<>e2.nombre;

5- Se necesita almacenar en una tabla los datos de la consulta anterior y una


fecha de encuentro. Elimine la tabla "encuentros" si existe.

6- Cree la tabla "encuentros" con la siguiente estructura:


create table encuentros(
codigo tinyint unsigned auto_increment,
equipo1 varchar(30),
equipo2 varchar(30),
lugarencuentro varchar(30),
barrioencuentro varchar(20),
fecha date,
primary key(codigo)
);

7- Ingrese los datos de la consulta del punto 4 en la tabla recientemente creada:


insert into encuentros(equipo1,equipo2,lugarencuentro,barrioencuentro)
select e1.nombre,e2.nombre,e1.domicilio,e1.barrio
from equipos as e1
cross join equipos as e2
where e1.nombre<>e2.nombre;

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.

77 - Insertar registros con valores de otra tabla (insert - select - join)

Tenemos las tabla "libros" y "editoriales", que contienen registros, y la tabla


"cantidadporeditorial", que no contiene registros.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-precio: decimal(5,2) unsigned,
-clave primaria: codigo.

La tabla "editoriales":

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
-clave primaria: codigo.

La tabla "cantidadporeditorial":

-nombre: varchar(20),
-cantidad: smallint unsigned.

Queremos insertar registros en la tabla "cantidadporeditorial", los nombres de las


distintas editoriales de las cuales tenemos libros y la cantidad de libros de cada
una de ellas.

Podemos lograrlo en 2 pasos:

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

2º paso: insertar los registros uno a uno en la tabla "cantidadporeditorial":

insert into cantidadporeditorial values('Emece',3);


insert into cantidadporeditorial values('Paidos',1);
insert into cantidadporeditorial values('Planeta',1);
insert into cantidadporeditorial values('Plaza & Janes',0);

O podemos lograrlo en un solo paso, realizando el "insert" y el "select" en una


misma sentencia:

insert into cantidadporeditorial


select e.nombre,count(l.codigoeditorial)
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;

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).

Recuerde que la cantidad de columnas devueltas en la consulta debe ser la misma


que la cantidad de campos a cargar en el "insert".

Ejemplo:
Tenemos las tabla "libros", "editoriales" y "cantidadporeditorial".

Eliminamos las 3 tablas si existen:


drop table libros, editoriales, cantidadporeditorial;

Creamos las tablas:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
autor varchar(30),
codigoeditorial tinyint unsigned,

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:

insert into libros values (1,'El aleph','Borges',2,23.5);


insert into libros values (2,'Alicia en el pais de las maravillas',
'Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,12);

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');

Queremos insertar registros en la tabla "cantidadporeditorial", los nombres de las


distintas editoriales de las cuales tenemos libros y la cantidad de libros de cada
una de ellas.

Podemos lograrlo en 2 pasos: 1º) realizar la consulta a las tablas "libros" y


"editoriales" para obtener el nombre y la cantidad de cada editorial y 2º) insertar
los registros uno a uno en la tabla "cantidadporeditorial".

O podemos lograrlo en un solo paso, realizando el "insert" y el "select" en una


misma sentencia:
insert into cantidadporeditorial
select e.nombre,count(l.codigoeditorial)
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;

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;

create table libros(


codigo int unsigned auto_increment,
titulo varchar(30),
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),
primary key(codigo)
);
create table cantidadporeditorial(
nombre varchar(20),
cantidad smallint unsigned
);
insert into libros values (1,'El aleph','Borges',2,23.5);
insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,15);
insert into libros values (3,'Matematica estas ahi','Paenza',2,34.6);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3,43.5);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2,12);

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');

insert into cantidadporeditorial


select e.nombre,count(l.codigoeditorial)
from editoriales as e
left join libros as l
on e.codigo=l.codigoeditorial
group by e.nombre;
select * from cantidadporeditorial;

Problema:

Un club de dicta clases de distintos deportes a sus socios. Guarda la información


de sus socios en
una tabla llamada "socios", la de los deportes que dicta en "deportes" y las
inscripciones
en "inscriptos".

1- Elimine las 3 tablas, si existen.

2- Cree las tablas:

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');

insert into deportes (nombre,profesor) values('tenis','Tadeo Torres');


insert into deportes (nombre,profesor) values('natacion','Natalia Nores');
insert into deportes (nombre,profesor) values('basquet','Bautista Pereyra');
insert into deportes (nombre,profesor) values('paddle','Bautista Pereyra');

insert into inscriptos values('22333444',1,'2005','s');


insert into inscriptos values('22333444',1,'2006','n');
insert into inscriptos values('22333444',2,'2005','s');
insert into inscriptos values('23333444',1,'2005','s');
insert into inscriptos values('23333444',2,'2006','s');
insert into inscriptos values('23333444',1,'2006','s');
insert into inscriptos values('24333444',1,'2006','s');
insert into inscriptos values('24333444',3,'2006','n');

4- Se desea saber la cantidad de alumnos inscriptos en cada deporte cada año,


sin considerar los deportes para los cuales no hay inscriptos:
select d.nombre,i.año,count(i.codigodeporte) as cantidad
from deportes as d
join inscriptos as i
on d.codigo=i.codigodeporte
group by d.nombre,i.año;

453
5- El club quiere almacenar esa información en una tabla llamada
"inscriptospordeporteporaño".
Elimine la tabla, si existe.

6- Cree la tabla con la siguiente estructura:


create table inscriptospordeporteporaño(
deporte varchar(15),
año year,
cantidad tinyint unsigned
);
7- Ingrese registros en la tabla creada anteriormente, a partir de la consulta del
punto 4:
insert into inscriptospordeporteporaño
select d.nombre,i.año,count(i.codigodeporte)
from deportes as d
join inscriptos as i
on d.codigo=i.codigodeporte
group by d.nombre,i.año;

8- Muestre el nombre del socio, el nombre del deporte y el año de inscripción de


todas las inscripciones con cuota impaga:
select s.nombre as socio,d.nombre as deporte,i.año
from socios as s
join inscriptos as i
on s.documento=i.documento
join deportes as d
on i.codigodeporte=d.codigo
where i.cuota='n';

9- Elimine la tabla "sociosdeudores" si existe.

10- Cree la tabla:


create table sociosdeudores(
socio varchar(30),
deporte varchar(15),
año year
);
11- Intente ingresar en la tabla anteriormente creada los registros resultado de la
consulta del punto 8, colocando los campos "socio" y "deporte" en la lista de
campos a cargar:
insert into sociosdeudores (socio,deporte)
select s.nombre,d.nombre,i.año
from socios as s
join inscriptos as i
on s.documento=i.documento
join deportes as d

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.

12- Ingrese en la tabla anteriormente creada los registros resultado de la consulta


del punto 8, correctamente:
insert into sociosdeudores
select s.nombre,d.nombre,i.año
from socios as s
join inscriptos as i
on s.documento=i.documento
join deportes as d
on i.codigodeporte=d.codigo
where i.cuota='n';

13- Vea los registros de "sociosdeudores".

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;

15- Elimine la tabla "alumnosporprofesor" si existe.

16- Cree la tabla "alumnosporprofesor":


create table alumnosporprofesor(
profesor varchar(30),
deporte varchar(15),
cantidad tinyint unsigned
);
17- Ingrese en la tabla creada en el punto anterior con el resultado de la consulta
del punto 14:
insert into alumnosporprofesor
select d.profesor,d.nombre,count(i.codigodeporte)
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:

A) Un profesor guarda en una tabla llamada "alumnos" los datos personales de


sus alumnos y en otra
tabla llamada "notas" las calificaciones de los mismos.

1- Elimine las tablas si existen.

2- Cree las tablas con las siguientes estructuras:


create table alumnos(
documento char(8),
nombre varchar(30),
domicilio varchar(30)
);
create table notas(
documento char(8) not null,
nota decimal(4,2) unsigned
);
Algunos alumnos tienen más notas que otros porque presentaron trabajos
especiales.

3- Ingrese los siguientes registros:


insert into alumnos (documento,nombre) values('22333444','Juan Perez');
insert into alumnos (documento,nombre) values('23333444','Marta Molina');
insert into alumnos (documento,nombre) values('24333444','Carlos Fuentes');
insert into alumnos (documento,nombre) values('25333444','Sandra Lopez');

insert into notas values('22333444',8);


insert into notas values('23333444',3);
insert into notas values('24333444',6);
insert into notas values('25333444',9);
insert into notas values('23333444',2);
insert into notas values('24333444',5);
insert into notas values('25333444',8);
insert into notas values('25333444',10);

4- El profesor necesita conocer el documento, el nombre del alumno y el promedio


de sus notas:
select a.documento,nombre,avg(n.nota) as promedio
from alumnos as a
join notas as n
on a.documento = n.documento
group by a.documento;

456
5- Elimine la tabla "promedios" si existe.

6- Cree la tabla "promedios" con la siguiente estructura:


create table promedios(
documento char(8),
nombre carchar(30),
promedio decimal(4,2) unsigned
);
7- Ingrese los registros resultado de la consulta del punto 4 en la tabla
"promedios":
insert into promedios
select a.documento,nombre,avg(n.nota)
from alumnos as a
join notas as n
on a.documento = n.documento
group by a.documento;

8- Muestre el documento, nombre y promedio de los alumnos aprobados:


select a.documento,nombre,avg(n.nota) as promedio
from alumnos as a
join notas as n
on a.documento = n.documento
group by a.documento
having promedio>=4;

9- Elimine la tabla "aprobados" si existe.

10- Cree la tabla "aprobados" con esta estructura:


create table aprobados(
documento char(8),
nombre varchar(30),
promedio decimal(4,2) unsigned
);
11- Ingrese los registros resultado de la consulta del punto 8 en la tabla creada en
el punto anterior:
insert into aprobados
select a.documento,nombre,avg(n.nota) as promedio
from alumnos as a
join notas as n
on a.documento = n.documento
group by a.documento
having promedio>=4;

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".

1- Elimine las tablas, si existen.

2- Cree las tablas:


create table clientes(
documento char(8),
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
create table cuentas(
numero int(8) zerofill auto_increment,
documento char(8) not null,
saldo decimal(9,2),
primary key(numero)
);
3- Ingrese los siguientes registros:
insert into clientes (documento,nombre) values ('22333444','Juan Perez');
insert into clientes (documento,nombre) values ('23333444','Maria Pereyra');
insert into clientes (documento,nombre) values ('24333444','Marcos Torres');
insert into clientes (documento,nombre) values ('25333444','Ana Juarez');

insert into cuentas values(1234,'22333444',2000.60);


insert into cuentas values(2566,'23333444',5050);
insert into cuentas values(5987,'24333444',200);
insert into cuentas values(14434,'25333444',8000.60);
insert into cuentas values(28566,'23333444',8050);
insert into cuentas values(35987,'24333444',2000);
insert into cuentas values(35997,'24333444',2000);

4- Agrupe por documento y muestre el documento del cliente, su nombre, en una


columna llamada "cantidad" calcule la cantidad de cuentas de cada cliente y en
otra columna llamada "total" calcule la suma de todas las cuentas de cada cliente:
select cl.documento,nombre,
count(*) as cantidad,
sum(saldo) as total
from cuentas as cu
join clientes as cl
on cl.documento=cu.documento
group by cl.documento;

458
5- Elimine la tabla "cuentasporcliente", si existe.

6- Cree la tabla "cuentasporcliente" con la siguiente estructura:


create table cuentasporcliente(
numero int unsigned auto_increment,
documento char(8),
cantidad tinyint unsigned,
total decimal(9,2) unsigned,
primary key(numero)
);
7- Inserte el resultado de la consulta del punto 4 en la tabla creada anteriormente:
insert into cuentasporcliente (documento,nombre,cantidad,total)
select cl.documento,nombre,
count(*) as cantidad,
sum(saldo)
from cuentas as cu
join clientes as cl
on cl.documento=cu.documento
group by cl.documento;

8- Vea los registros de "cuentasporcliente".

78 - Actualizar datos con valores de otra tabla (update)


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.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene esta estructura:

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
-clave primaria: codigo.

Ambas tablas contienen registros.

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".

En primer lugar debemos alterar la tabla "libros", vamos a agregarle un campo


llamado "editorial" en el cual guardaremos el nombre de la editorial.

alter table libros add editorial varchar(20);

La tabla "libros" contiene un nuevo campo "editorial" con todos los registros con
valor "null".

Ahora debemos actualizar los valores para ese campo.

Podemos hacerlo en 2 pasos:

1º paso: consultamos los códigos de las editoriales:

select codigo,nombre
from editoriales;

obtenemos una salida similar a la siguiente:

codigo nombre
_________________
1 Planeta
2 Emece
3 Paidos

2º paso: comenzamos a actualizar el campo "editorial" de los registros de "libros"


uno a uno:

update libros set editorial='Planeta'


where codigoeditorial=1;
update libros set editorial='Emece'
where codigoeditorial=2;
update libros set editorial='Paidos'
where codigoeditorial=3;
... con cada editorial...

Luego, eliminamos el campo "codigoeditorial" de "libros" y la tabla "editoriales".

Pero podemos simplificar la tarea actualizando el campo "editorial" de todos los


registros de la tabla "libros" al mismo tiempo que realizamos el "join" (paso 1 y 2
en una sola sentencia):

460
update libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
set libros.editorial=editoriales.nombre;

Luego, eliminamos el campo "codigoeditorial" de "libros" con "alter table" y la tabla


"editoriales" con "drop table".

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.

Eliminamos ambas tablas si existen:


drop table if exists libros, editoriales;

Creamos las tablas:


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)
);
Ingresamos algunos registros:

insert into editoriales values(1,'Planeta');


insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);

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".

En primer lugar debemos alterar la tabla "libros", vamos a agregarle un campo


llamado "editorial" en el cual guardaremos el nombre de la editorial.
alter table libros add editorial varchar(20);

Si visualizamos la estructura de la tabla:


describe libros;

vemos que la tabla "libros" contiene un nuevo campo "editorial".

Veamos los registros:


select * from libros;

vemos que todos los registros tienen el campo "editorial" con valor "null".

Ahora debemos actualizar los valores para ese campo.

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".

Pero podemos simplificar la tarea actualizando el campo "editorial" de todos los


registros de la tabla "libros" al mismo tiempo que realizamos el "join" para que
localice los códigos de las editoriales (paso 1 y 2 en una sola sentencia). Lo
hacemos de esta manera:
update libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
set libros.editorial=editoriales.nombre;

Veamos cómo quedaron los registros luego de la actualización:


select * from libros;

Ahora si, eliminamos el campo "codigoeditorial" de "libros":


alter table libros drop codigoeditorial;

y finalmente eliminamos la tabla "editoriales":


drop table editoriales;

Veamos todos los registros y todos los campos:


select * from libros;

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');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);

alter table libros add editorial varchar(20);


describe libros;
select * from libros;
update libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
set libros.editorial=editoriales.nombre;
select * from libros;
alter table libros drop codigoeditorial;
drop table editoriales;
select * from libros;

Problema:

Una empresa tiene registrados sus clientes en una tabla llamada "clientes",
también tiene una tabla "provincias" donde registra los nombres de las provincias.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
nombre varchar(30) not null,
domicilio varchar(30),
ciudad varchar(20),
codigoprovincia tinyint unsigned,
telefono varchar(11),
primary key(codigo)

463
);

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');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
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');

4- La empresa quiere eliminar la tabla "provincias" y almacenar el nombre de la


provincia de la cual son oriundos sus clientes en la misma tabla "clientes".

5- Altere la tabla "clientes" para que se almacene en ella el nombre de la provincia:


alter table clientes add provincia varchar(20);

6- Actualice el campo "provincia" de todos los registros de "clientes", con el valor


del campo "nombre" de la tabla "provincias" mediante un "join":
update clientes as c
join provincias as p

464
on c.codigoprovincia=p.codigo
set c.provincia=p.nombre;

7- Elimine el campo innecesario en "clientes" y la tabla "provincias".

Otros problemas:

A) 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.

1- Elimine las tablas si existen.

2- Cree las tablas:


create table socios(
documento char(8) not null,
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
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)
);
3- Ingrese algunos registros para ambas tablas:
insert into socios values('22333444','Juan Perez','Colon 234');
insert into socios values('23333444','Maria Lopez','Sarmiento 465');
insert into socios values('24333444','Antonio Juarez','Caseros 980');

insert into inscriptos values ('22333444','natacion','2005','s');


insert into inscriptos values ('22333444','natacion','2006','n');
insert into inscriptos values ('23333444','natacion','2005','s');
insert into inscriptos values ('23333444','tenis','2006','s');
insert into inscriptos values ('23333444','natacion','2006','s');
insert into inscriptos values ('24333444','tenis','2006','n');
insert into inscriptos values ('24333444','basquet','2006','n');

4- El club quiere eliminar la tabla "socios" porque en adelante, para inscribirse en


un deporte ya no será necesario ser socio. Se quiere almacenar el nombre y
domicilio de quien se inscribe en la misma tabla en la cual se registran las
inscripciones. Agregue los campos necesarios a la tabla "inscriptos":
alter table inscriptos add nombre varchar(30), add domicilio varchar(30);

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;

6- Elimine la tabla "socios".

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".

1- Elimine las tablas "empleados" y "dependencias" si existen.

2- Cree las tablas:


create table empleados(
documento char(8) not null,
nombre varchar(30) not null,
domicilio varchar(30),
fechaingreso date,
primary key(documento)
);
create table dependencias(
documento char(8) not null,
seccion varchar(30),
sueldo decimal (6,2) unsigned,
primary key(documento)
);

3- Ingrese algunos registros:


insert into empleados values ('22333111','Juan Perez','Colon 123','1990-02-01');
insert into empleados values ('25444444','Susana Morales','Avellaneda
345','1995-04-01');
insert into empleados values ('20111222','Hector Pereyra','Caseros 987','1995-04-
01');
insert into empleados values ('30000222','Luis Luque','Urquiza 456','1980-09-01');
insert into empleados values ('20555444','Laura Torres','San Martin 1122','2000-
05-15');
insert into empleados values ('30000234','Alberto Soto','Peru 232','2003-08-15');
insert into empleados values ('30154269','Oscar Mendez','Colon 1245','2004-06-
23');

insert into dependencias values('22333111','Gerencia',2000);


insert into dependencias values ('25444444','Sistemas',1500);
insert into dependencias values ('20111222','Sistemas',1400);
insert into dependencias values ('30000222','Contaduría',1400);

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);

4- La empresa quiere eliminar la tabla "dependencias" y guardar la información


que la misma contiene en la tabla "empleados". Agregue los campos necesarios a
la tabla "empleados":
alter table empleados add seccion varchar(30) not null, add sueldo decimal(6,2)
unsigned;

5- Vea los registros de la tabla "empleados":


select *from empleados;

6- Actualice los nuevos campos realizando un "join" con la tabla "dependencias":


update empleados as e
join dependencias as d
on d.documento=e.documento
set e.seccion=d.seccion,
e.sueldo=d.sueldo;

7- Elimine la tabla "dependencias".

8- Visualice la nueva estructura de la tabla "empleados" y sus registros.

C) Un instituto de enseñanza guarda en una tabla llamada "alumnos" los datos


personales de sus alumnos.

1- Elimine la tabla "alumnos" si existe.

2- Cree la tabla con la siguiente estructura:


create table alumnos(
apellido varchar(20) not null,
nombre varchar(20),
documento char(8),
domicilio varchar(30),
primary key(documento)
);
3- Ingrese los siguientes registros:
insert into alumnos values('Perez','Luis','22333444','Colon 123');
insert into alumnos values('Lopez','Natalia','23333444','Caseros 980');
insert into alumnos values('Torres','Mariano','24333444','Bulnes 256');
insert into alumnos values('Garcia','Ana','25333444','Sucre 209');
insert into alumnos values('Perez','Antonio','26333444','Avellaneda 1083');

4- Se desea alterar la tabla "alumnos" para que guarde en un mismo campo el


apellido y el nombre del alumno.
update alumnos

467
set nombre=concat(apellido,' ',nombre);

5- Muestre todos los registros de la tabla "alumnos".

6- Elimine el campo "apellido".

79 - Actualización en cascada (update - join)

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.

Las tablas tienen las siguientes estructuras:

create table libros(


codigo int unsigned auto_increment,
titulo varchar(30),
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),
primary key(codigo)
);

Ambas tablas contienen registros.

Queremos modificar el código de la editorial "Emece" a "9" y también todos los


"codigoeditorial" de los libros de dicha editorial. Podemos hacerlo en 3 pasos:

1) buscar el código de la editorial "Emece":

select * from editoriales


where nombre='Emece';

recordamos el valor devuelto (valor 2) o lo almacenamos en una variable;

2) actualizar el código en la tabla "editoriales":

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;

O podemos hacerlo en una sola sentencia:

update libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
set l.codigoeditorial=9, e.codigo=9
where e.nombre='Emece';

El cambio se realizó en ambas tablas.

Si modificamos algún dato de un registro que se encuentra en registros de otras


tablas (generalmente campos que son clave ajena) debemos modificar también los
registros de otras tablas en los cuales se encuentre ese dato (generalmente clave
primaria). Podemos realizar la actualización en cascada (es decir, en todos los
registros de todas las tablas que contengan el dato modificado) en una sola
sentencia, combinando "update" con "join" y seteando los campos involucrados de
todas las tablas.

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 las tablas si existen:


drop table if exists libros, editoriales;

Creamos las tablas con las siguientes estructuras:


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
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),
primary key(codigo)
);

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');

insert into libros values (1,'El aleph','Borges',2,44.20);


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);

Queremos modificar el código de la editorial "Emece" a "9" y también todos los


"codigoeditorial" de los libros de dicha editorial. Podemos hacerlo en 3 pasos: 1)
buscar el código de la editorial "Emece" (nos retorna 2); 2) actualizar el código en
la tabla "editoriales" y 3) actualizar todos los libros de dicha editorial con el valor
"9". O podemos hacerlo en una sola sentencia:
update libros as l
join editoriales as e
on l.codigoeditorial=e.codigo
set l.codigoeditorial=9, e.codigo=9
where e.nombre='Emece';

Verificamos el cambio en ambas tablas:

select * from libros;


select * from editoriales;

drop table if exists libros, editoriales;


create table libros(
codigo int unsigned auto_increment,
titulo varchar(30),
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),
primary key(codigo)
);
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');

insert into libros values (1,'El aleph','Borges',2,44.20);

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.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,
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)

471
values('Buenos Aires');
insert into provincias (nombre)
values('Neuquen');

insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoProvincia,telefono)
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');

4- Se quiere cambiar el código correspondiente a la provincia "Cordoba" por "10" y


modificar todos los códigos de provincia de los clientes de "Cordoba" en una sola
sentencia:
update clientes as c
join provincias as p
on c.codigoprovincia=p.codigo
set c.codigoprovincia=10, p.codigo=10
where p.nombre='Cordoba';

5- Verifique el cambio en ambas tablas:


select * from clientes;
select * from provincias;

Otros problemas:

Un profesor guarda los promedios de sus alumnos de un curso en una tabla


llamada "alumnos" y las notas de los mismos en la tabla "notas".

1- Elimine las tablas si existen.

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');

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);

4- El alumno "Juan Perez" registrado con documento "22333444" dice que su


documento ha sido almacenado erróneamente, en realidad es "22333445".
Modifique el documento del alumno en "alumnos" y "notas en una sola sentencia:
update alumnos as a
join notas as n
on a.documento=n.documento
set a.documento='22333445', n.documento='22333445'
where a.documento='22333444';

473
80 - Borrar registros consultando otras tablas (delete - join)

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.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene esta estructura:

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
-clave primaria: codigo.

Ambas tablas contienen registros.

Queremos eliminar todos los libros de la editorial "Emece" pero no recordamos el


código de dicha editorial.

Podemos hacerlo en 2 pasos:

1º paso: consultamos el código de la editorial "Emece":

select codigo
from editoriales
where nombre='Emece';

recordamos el valor devuelto (valor 2) o lo almacenamos en una variable.

2º paso: borramos todos los libros con código de editorial "2":

delete libros
where codigoeditorial=2;

O podemos realizar todo en un solo paso:


delete libros
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';

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.

Eliminamos ambas tablas si existen:


drop table if exists libros, editoriales;

Creamos las tablas:


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)
);
Ingresamos algunos registros:
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);

Queremos eliminar todos los libros de la editorial "Emece" pero no recordamos el


código de dicha editorial.

Podemos hacerlo en 2 pasos: 1) consultamos el código de la editorial "Emece" y


recordamos el valor devuelto (valor 2) y 2) borramos todos los libros con código de
editorial "2".

475
O podemos realizar todo en una sola consulta:
delete libros
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';

Veamos si se eliminaron los registros solicitados:


select * from libros;

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');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);
delete libros
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';
select * from libros;

Problema:

Una empresa tiene registrados sus clientes en una tabla llamada "clientes",
también tiene una tabla "provincias" donde registra los nombres de las provincias.

1- Elimine la tabla "clientes" y "provincias", si existen:


drop table if exists clientes, provincias;

2- Créelas con las siguientes estructuras:


create table clientes (
codigo int unsigned auto_increment,

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');

insert into clientes (nombre,domicilio,ciudad,codigoprovincia,telefono)


values ('Lopez Marcos', 'Colon 111', 'Córdoba',1,'null');
insert into clientes (nombre,domicilio,ciudad,codigoprovincia,telefono)
values ('Perez Ana', 'San Martin 222', 'Cruz del Eje',1,'4578585');
insert into clientes (nombre,domicilio,ciudad,codigoprovincia,telefono)
values ('Garcia Juan', 'Rivadavia 333', 'Villa Maria',1,'4578445');
insert into clientes (nombre,domicilio,ciudad,codigoprovincia,telefono)
values ('Perez Luis', 'Sarmiento 444', 'Rosario',2,null);
insert into clientes (nombre,domicilio,ciudad,codigoprovincia,telefono)
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',5,'0457858745');

4- Se quiere borrar de la tabla "clientes" todos los clientes de la provincia "Santa


Fe", pero no se recuerda el código de la provincia. Elimine dichos clientes
consultando el código de provincia en "provincias" en la misma sentencia:
delete clientes
from clientes

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.

1- Elimine las 3 tablas, si existen:


drop table if exists carreras, materias, inscriptos;

2- Cree las tablas con las siguientes estructuras:


create table carreras(
codigo tinyint unsigned auto_increment,
nombre varchar(30),
primary key(codigo)
);
create table materias(
codigo tinyint unsigned auto_increment,
codigocarrera tinyint unsigned,
nombre varchar(30),
profesor varchar(30),
primary key(codigo,codigocarrera)
);
create table inscriptos(
documento char(8) not null,
codigocarrera tinyint unsigned,
codigomateria tinyint unsigned,
año year
);
3- Ingrese algunos registros:
insert into carreras values(1,'Analista de sistemas');
insert into carreras values(2,'Diseñador web');

insert into materias values(1,1,'Programacion I','Alfredo Lopez');


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');

insert into inscriptos values('22333444',1,3,'2006');


insert into inscriptos values('23222222',1,2,'2006');

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');

4- La materia "Sistemas de datos I" no se va a dictar por cambios en el programa.


Elimine todas las inscripciones a dicha materia de la tabla "inscriptos" consultando
el código en "materias" y "carreras":
delete inscriptos
from inscriptos as i
join materias as m
on i.codigomateria=m.codigo
join carreras as c
on i.codigocarrera=c.codigo and
c.codigo=m.codigocarrera
where m.nombre='Sistemas de datos I';

5- Verifique la eliminación en "inscriptos".

6- Elimine la materia de la tabla "materias":


delete from materias
where nombre='Sistemas de datos I';

81 - Borrar registros buscando coincidencias en otras tablas (delete - join)


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.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene esta estructura:

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
-clave primaria: codigo.

Ambas tablas contienen registros.

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":

select l.* from libros as l


left join editoriales as e
on l.codigoeditorial=e.codigo
where e.codigo is null;

recordamos el valor de los códigos de libro devueltos (valor 5) o lo almacenamos


en una variable.

2º paso: borramos todos los libros mostrados en la consulta anterior (uno solo, con
código 5):

delete libros
where codigo=5;

O podemos realizar la eliminción en el mismo momento que realizamos el "left


join":

delete libros
FROM libros
left join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.codigo is null;

Es decir, usamos "delete" junto al nombre de la tabla de la cual queremos eliminar


registros, luego realizamos el "left join" correspondiente nombrando las tablas
involucradas y agregamos la condición "where" para que seleccione solamente los
libros cuyo código de editorial no se encuentre en "editoriales".

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;

Creamos las tablas:


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)
);

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');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);
insert into libros values (6,'Aprenda PHP','Mario Molina',9);

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).

O podemos realizar la eliminación en el mismo momento que realizamos el "left


join":
delete libros
from libros
left join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.codigo is null;

Veamos si el libro se ha eliminado:


select * from libros;

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;

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');
insert into editoriales values(4,'Plaza & Janes');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);
insert into libros values (6,'Aprenda PHP','Mario Molina',9);

delete libros
FROM libros
left join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.codigo is null;

select * from libros;

delete editoriales
from editoriales
left join libros
on libros.codigoeditorial=editoriales.codigo
where libros.codigo is null;

select * from editoriales;

482
Ejemplo:

Un club de dicta clases de distintos deportes a sus socios. Guarda la información


de los deportes que dicta en una tabla llamada "deportes", los datos de los
profesores en "profesores" y las inscipciones en "inscriptos".

1- Elimine las tablas, si existen.

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,
cuota char(1), /*'s' o 'n', si esta paga o no*/
primary key(numerosocio,deporte,año)
);
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');

insert into deportes values(1,'tenis',1);


insert into deportes values(2,'natacion',2);
insert into deportes values(3,'basquet',3);
insert into deportes values(4,'futbol',1);

insert into inscriptos values(102,1,'2006','s');


insert into inscriptos values(102,2,'2006','s');
insert into inscriptos values(104,2,'2006','s');
insert into inscriptos values(104,3,'2006','s');
insert into inscriptos values(106,1,'2006','s');
insert into inscriptos values(109,2,'2006','s');

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;

5- se quiere eliminar de la tabla "profesores" a aquellos profesores que no dictan


ningún deporte, es decir, que no están en la tabla "deportes":
delete profesores
from profesores as p
left join deportes as d
on d.profesor=p.codigo
where d.profesor 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".

1- Elimine las tablas si existen:


drop table if exists alumnos, aprobados;

2- Cree las tablas:


create table alumnos(
legajo int(3) unsigned,
nombre varchar(30)
);
create table aprobados(
legajo int(3) unsigned,
promedio decimal(4,2) unsigned
);
3- Ingrese los siguientes registros:
insert into alumnos values(123,'Juan Perez');
insert into alumnos values(223,'Marta Molina');
insert into alumnos values(343,'Patricia Vargas');
insert into alumnos values(456,'Hector Fuentes');
insert into alumnos values(467,'Alfredo Lopez');
insert into alumnos values(678,'Carla Juarez');

insert into aprobados values(223,9.4);


insert into aprobados values(456,6);
insert into aprobados values(467,4.5);
insert into aprobados values(678,7.8);

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.

1- Elimine las tablas, si existen.

2- Cree las tablas:


create table socios(
documento char(8),
nombre varchar(30),
domicilio varchar(30),
primary key(documento)
);
create table morosos(
documento char(8),
fecha date
);
3- Ingrese algunos registros:
insert into socios values(234,'Juan Lopez','Colon 345');
insert into socios values(345,'Ana Ferrero','Caseros 98');
insert into socios values(456,'Juan Perez','Urquiza 356');
insert into socios values(567,'Karina Torres','Peru 743');
insert into socios values(678,'Juan Lopez','Avellaneda 234');
insert into socios values(789,'Laura Juarez','Sarmiento 765');

insert into morosos values(345,'2006-08-10');


insert into morosos values(567,'2006-09-24');
insert into morosos values(789,'2006-10-06');

4- Se quiere borrar de la tabla "socios" los socios morosos:


delete socios
from socios as s
join morosos as m
on s.documento=m.documento;

485
82 - Borrar registros en cascada (delete - join)

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.

La tabla "libros" tiene la siguiente estructura:

-codigo: int unsigned auto_increment,


-titulo: varchar(30),
-autor: varchar(30),
-codigoeditorial: tinyint unsigned,
-clave primaria: codigo.

La tabla "editoriales" tiene esta estructura:

-codigo: tinyint unsigned auto_increment,


-nombre: varchar(20),
-clave primaria: codigo.

Ambas tablas contienen registros.

La librería ya no trabaja con la editorial "Emece", entonces quiere eliminar dicha


editorial de la tabla "editoriales" y todos los libros de "libros" de esta editorial.
Podemos hacerlo en 2 pasos:

1º paso: buscar el código de la editorial "Emece" y almacenarlo en una variable:

select @valor:= codigo from editoriales


where nombre='Emece';

2º paso: eliminar dicha editorial de la tabla "editoriales":

delete editoriales
where codigo=@valor;

3º paso: eliminar todos los libros cuyo código de editorial sea igual a la variable:

delete libros where codigoeditorial=@valor;

O podemos hacerlo en una sola consulta:


delete libros,editoriales
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';

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".

Es decir, podemos realizar la eliminación de registros de varias tablas (en


cascada) empleando "delete" junto al nombre de las tablas de las cuales
queremos eliminar registros y luego del correspondiente "join" colocar la condición
"where" que afecte a los registros a eliminar.

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;

Creamos las tablas:


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)
);
Ingresamos algunos registros:
insert into editoriales values(1,'Planeta');
insert into editoriales values(2,'Emece');
insert into editoriales values(3,'Paidos');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);

La librería ya no trabaja con la editorial "Emece", entonces quiere eliminar dicha


editorial de la tabla "editoriales" y todos los libros de "libros" de esta editorial.
Podemos hacerlo en 2 pasos: 1) buscar el código de la editorial "Emece" y
almacenarlo en una variable, 2) eliminar la editorial con código igual al valor de la
variable de "editoriales" y 3) eliminar todos los libros cuyo código de editorial sea
igual a la variable, de la tabla "libros".

487
O podemos hacerlo en una sola consulta:
delete libros,editoriales
from libros
join editoriales
on libros.codigoeditorial=editoriales.codigo
where editoriales.nombre='Emece';

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".

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');

insert into libros values (1,'El aleph','Borges',2);


insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1);
insert into libros values (3,'Matematica estas ahi','Paenza',2);
insert into libros values (4,'Martin Fierro','Jose Hernandez',3);
insert into libros values (5,'Martin Fierro','Jose Hernandez',2);

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.

1- Elimine las tablas si existen.

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');

insert into pacientes values('22333444','Juan Lopez','Guemes 235',1);


insert into pacientes values('23444555','Analia Juarez','Avellaneda 367',1);
insert into pacientes values('24555666','Juan Lopez','Guemes 235',2);
insert into pacientes values('25666777','Jose Ferrero','Urquiza 312',3);
insert into pacientes values('26777888','Hhector Garcia','Caseros 411',3);
insert into pacientes values('27888999','Susana Duarte','Peru 211',3);

4- La clínica ya no atiende a pacientes de la obra social "PAMI". Se quiere eliminar


de la tabla "obrassociales" a dicha obra social y de la tabla "pacientes" a todos los
pacientes que de "PAMI":
delete pacientes,obrassociales
from pacientes as p
join obrassociales as os
on p.codigoobrasocial=os.codigo
where os.nombre='PAMI';

5- Verifique las eliminaciones.

Otros problemas:

Un club de dicta clases de distintos deportes a sus socios. Guarda la información


de los deportes
que dicta en una tabla llamada "deportes", los datos de los profesores en
"profesores" y las inscipciones en "inscriptos".

1- Elimine las tablas, si existen.

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');

insert into deportes values(1,'tenis',1);


insert into deportes values(2,'natacion',2);
insert into deportes values(3,'basquet',3);
insert into deportes values(4,'futbol',1);

insert into inscriptos values(102,1,'2006');


insert into inscriptos values(102,2,'2006');
insert into inscriptos values(104,2,'2006');
insert into inscriptos values(104,3,'2006');
insert into inscriptos values(106,1,'2006');
insert into inscriptos values(109,2,'2006');

4- El club ha cancelado el deporte "tenis"; se quiere eliminar dicho deporte de la


tabla "deportes" y las inscripciones a "tenis" de "inscriptos":
delete deportes,inscriptos
from deportes as d
join inscriptos as i
on d.codigo=i.deporte
where d.nombre='tenis';

490
5- Verifique las eliminaciones.

6- El profesor "Carlos García" renunció al club. Se quiere borrar a dicho profesor


de la tabla "profesores" y eliminar todos los deportes que dictaba "Carlos García",
además, de todas las inscripciones a todos los deportes que dictaba dicho
profesor:
delete inscriptos,profesores,deportes
from inscriptos as i
join deportes as d
on d.codigo=i.deporte
join profesores as p
on d.profesor=p.codigo
where p.nombre='Carlos Garcia';

7- Verifique las eliminaciones en todas las tablas involucradas.

83 - Chequear y reparar tablas (check - repair)


Para chequear el estado de una tabla usamos "check table":

check table libros;

"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".

Existen distintas opciones de chequeo de una tabla, si no se especifica, por


defecto es "medium".

Los tipos de chequeo son:

- quick: no controla los enlaces incorrectos de los registros.

- 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:

check table libros fast quick;

Para reparar una tabla corrupta usamos "repair table":

repair table libros;

"repair table" puede recuperar los datos de una tabla.

Devuelve la siguiente información: en la columna "Table" nuestra el nombre de la


tabla; en "Op" siempre muestra "repair"; en "Msg_type" muestra "status", "error",
"info" o "warning" y en "Msg_text" muestra un mensaje que genealmente es "OK".

Ejemplo:

Eliminamos la tabla "libros" si existe:


drop table if exists libros;

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;

Nos devuelve la siguiente información:

"Table" "Op" "Msg_type" "Msg_text"


libros check status OK

Para realizar un chequeo rápido de la tabla "libros" y verificar si se cerró


correctamente tipeamos:
check table libros fast quick;

Si el resultado indica que la tabla está corrupta podemos emplear "repair table"
para repararla:
repair table libros;

drop table if exists libros;


create table libros(
codigo int unsigned auto_increment,

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;

84 - Encriptación de datos (encode - decode)


Las siguientes funciones encriptan y desencriptan valores.

Si necesitamos almacenar un valor que no queremos que se conozca podemos


encriptar dicho valor, es decir, transformarlo a un código que no pueda leerse.

Con "encode" se encripta una cadena. La función recibe 2 argumentos: el primero,


la cadena a encriptar; el segundo, una cadena usada como contraseña para luego
desencriptar:

select encode('feliz','dia');

El resultado es una cadena binaria de la misma longitud que el primer argumento.

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 decode('§ ¡Ý7','dia');

Si la cadena de contraseña es diferente a la ingresada al encriptar, el resultado


será incorrecto.

Retomamos la tabla "usuarios" que constaba de 2 campos: nombre del usuario


(varchar de 30) y clave (varchar de 10).

Podemos ingresar registros encriptando la clave:

insert into usuarios values ('MarioPerez',encode('Marito','octubre'));

La forma más segura es no transferir la contraseña a través de la conexión, para


ello podemos almacenar la clave en una variable y luego insertar la clave
encriptada:

select @clave:=encode('RealMadrid','ganador');
insert into usuarios values ('MariaGarcia',@clave);

493
Veamos los registros ingresados:

select * from usuarios;

Desencriptamos la clave del usuario "MarioPerez":

select decode(clave,'octubre') from usuarios


where nombre='MarioPerez';

Desencriptamos la clave del usuario "MariaGarcia":

select decode(clave,'ganador') from usuarios


where nombre='MariaGarcia';

Ejemplo:
Retomamos la tabla "usuarios".

Eliminamos la tabla si existe:


drop table if exists 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'));

La forma más segura es no transferir la contraseña a través de la conexión, para


ello podemos almacenar la clave en una variable y luego insertar la clave
encriptada:
select @clave:=encode('RealMadrid','ganador');
insert into usuarios values ('MariaGarcia',@clave);

Veamos los registros ingresados:


select * from usuarios;

Desencriptamos la clave del usuario "MarioPerez":


select decode(clave,'octubre') from usuarios
where nombre='MarioPerez';

Desencriptamos la clave del usuario "MariaGarcia":


select decode(clave,'ganador') from usuarios
where nombre='MariaGarcia';

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);

Guardamos la clave para el siguiente usuario en una variable llamada


"@clavecodificada" y luego ingresamos el registro con la clave encriptada, usamos
la misma contraseña para la encriptación:
select @clavecodificada:=encode('Boca','SQL');
insert into usuarios values ('AnaMariaJuarez',@clavecodificada);

Ahora desencriptamos las claves al momento de la consulta los usuarios:


select decode(clave,'SQL') from usuarios;

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.

drop table if exists usuarios;


create table usuarios (
nombre varchar(30),
clave varchar(10)
);
insert into usuarios values ('MarioPerez',encode('Marito','octubre'));
select @clave:=encode('RealMadrid','ganador');
insert into usuarios values ('MariaGarcia',@clave);
select * from usuarios;
select decode(clave,'octubre') from usuarios
where nombre='MarioPerez';
select decode(clave,'ganador') from usuarios
where nombre='MariaGarcia';
select @clavecodificada:=encode('River','SQL');
insert into usuarios values ('JuanJoseTorres',@clavecodificada);
select @clavecodificada:=encode('Boca','SQL');
insert into usuarios values ('AnaMariaJuarez',@clavecodificada);
select decode(clave,'SQL') from usuarios;

495

También podría gustarte