domingo, 13 de mayo de 2012

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.

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


Problema Resuelto: 

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.

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;
 
 
 
Problema Propuesto:
 
 
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');
 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.

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),
  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)
  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:
 
 
10- Agrupe los registros por serie y número de factura y muestre el total 
(en una columna calculada) de cada factura:
 


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.


Problema Resuelto: 

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

 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;
 
 
Problema Propuesto:

 
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- Obtenga el total de los registros que no tienen valor nulo en los teléfonos 
y coloque un alias para dicha columna:
 
5- Muestre la cantidad de clientes que se apellidan "Perez" colocando un alias 
para dicha salida:
 
6- Obtenga la cantidad de ciudades DISTINTAS por provincia en las cuales hay 
clientes, coloque un alias:
 



  

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


Problema Resuelto: 


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

 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.


Problema Propuesto:

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 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,
  horario char(2) not null,
  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:
 
5- Seleccione los cursos donde el tema incluya "PHP", sin repetir horario 
ni tema:
 

6- Cuente la cantidad de cursos DISTINTOS agrupados por horario: 
 
 
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:
 

5- Obtenga la cantidad de ciudades distintas, por provincia en las cuales 
hay clientes:
 


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','AnaMaria@hotmail.com','2006-10-10');
 insert into visitas (nombre,mail,fecha)
  values ('Gustavo Gonzalez','GustavoGGonzalez@hotmail.com','2006-10-10');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-10-11');
 insert into visitas (nombre,mail,fecha)
  values ('Fabiola Martinez','MartinezFabiola@hotmail.com','2006-10-12');
 insert into visitas (nombre,mail,fecha)
  values ('Fabiola Martinez','MartinezFabiola@hotmail.com','2006-09-12');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-09-12');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-09-15');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-09-15');

4- Obtenga los distintos nombres de quienes visitaron la página:
 
5- Muestre la cantidad de veces que cada persona ingresó a la página:
 
6- Muestre la cantidad de veces que cada persona ingresó a la página en 
distintas fechas:
 
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:
 
5- Muestre la cantidad de autos por marca, de diferentes modelos:
 
6- Muestre los distintos modelos de autps disponibles:
 


D) Un consultorio médico en el cual trabajan varios médicos 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(
  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:
 
6- Muestre los nombres de los distintos pacientes:
 
7- Muestre la cantidad de distintas obras sociales:
 
8- Cuente la cantidad de médicos (SIN REPETIR) que tienen consultas agrupado 
por mes y día:
 
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.

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:
 
5- Muestre los nombres de los deportes sin repetir:
 
6- Muestre la cantidad de alumnos DISTINTOS inscriptos en cada deporte:
 
7- Muestre la cantidad de inscriptos por año, sin considerar los alumnos que 
se inscribieron en más de un deporte:
 


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';
 
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;
 
Problema Resuelto: 

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:

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:

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;
 
 
 
Problema Propuesto: 

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- Obtenga el total de los registros agrupados por provincia:
 
5- Obtenga el total de los registros agrupados por ciudad y provincia:
 

6- Obtenga el total de los registros agrupados por ciudad y provincia sin considerar los que tienen 
menos de 2 clientes:
 

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: 
 
 
 
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- 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:
 
5- Obtenga el total de las compras agrupados por ciudad y sexo, considerando sólo las sumas 
superiores a 50 pesos:
 
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:
 
7- Agrupe por ciudad y muestre para cada grupo (ciudad) el total de visitantes, la suma de sus 
compras y el promedio de compras: 
 
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','AnaMaria@hotmail.com','Argentina',9);
 insert into visitas (nombre,mail,pais,puntaje)
  values ('Gustavo Gonzalez','GustavoGGonzalez@yahoo.com','Chile',8);
 insert into visitas (nombre,mail,pais,puntaje)
  values ('Juancito','JuanJosePerez@hotmail.com','Mexico',5);
 insert into visitas (nombre,mail,pais,puntaje)
  values ('Fabiola Martinez','MartinezFabiolaM@hotmail.com','Chile',9);
 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:
 
5- Muestre el promedio de los puntajes agrupados por pais, considerando sólo 

aquellos países cuyo promedio es mayor a 8:
 

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

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

domingo, 15 de abril de 2012

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.

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

Problema Resuleto:

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

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;
 
 
 
Problema Propuesto:
 
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- Obtenga el total de los registros (10):
 
5- Obtenga el total de los registros que no tienen valor nulo en los 
teléfonos (8):
 
6- Obtenga la cantidad de clientes agrupados por ciudad y provincia, 
ordenados por 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,
  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','AnaMaria@hotmail.com','2006-10-10');
 insert into visitas (nombre,mail,fecha)
  values ('Gustavo Gonzalez','GustavoGGonzalez@hotmail.com','2006-10-10');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-10-11');
 insert into visitas (nombre,mail,fecha)
  values ('Fabiola Martinez','MartinezFabiola@hotmail.com','2006-10-12');
 insert into visitas (nombre,mail,fecha)
  values ('Fabiola Martinez','MartinezFabiola@hotmail.com','2006-09-12');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-09-12');
 insert into visitas (nombre,mail,fecha)
  values ('Juancito','JuanJosePerez@hotmail.com','2006-09-15');

4- Obtenga el total de visitas.

5- Cantidad de visitas agrupadas por fecha:
 
6- Cantidad de visitas agrupadas por nombre y mes:
 


B) 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)
  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 
cuántas corbatas debe comprar para el mes de mayo:
 
5- Se necesita conocer la cantidad de empleados agrupados por año de ingreso 
a la empresa: 
 
 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:
 
5- Sume la cantidad de productos de las facturas:
 
6- Muestre el total en dinero de las facturas:
 
 
  

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


Problema Resuelto:

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


Problema Propuesto :
 
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.

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):
 
5- Muestre la suma de la compra de todos los visitantes de "Alta Gracia" (78.5):
 
6- Muestre el valor máximo de las compras efectuadas (53.50):
 
7- Muestre la edad menor de los visitantes (20):
 
8- Muestre el promedio de edades de los visitantes (33.66):
 
9- Muestre el promedio del monto de compra (24.55): 
 
 
 
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":
  
5- Calcule la suma recaudada por los pagos de los cursos el día "2006-08-10":
  
6- Calcule el promedio de los pagos de los inscriptos:
  
7- Muestre el máximo y el mínimo valor de pago, sin considerar quienes no pagan:
  
8- Vea en cuántos cursos se inscribió el alumno con documento "22333444" y cuánto 
abonó en total:
  


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:
 
5- Muestre el promedio de duración de las películas:
 
6- Cuente la cantidad de películas que comiencen con la cadena "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:
 

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:
 
5- Muestre el valor de auto más caro de 1990:
 
6- Muestre el promedio de los precios de los autos "Fiat 128":
 
7- Calcule el valor en dinero de todos los autos marca "Renault" con 
modelos menores a "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":
 
5- Sume la cantidad de productos de la factura número "2002":
 
6- Muestre el total en dinero de la factura "504":
 

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


Problema Resuelto: 

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


Problema Propuesto:
 
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
 );

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):
 
5- Solicite la cantidad de visitantes que tienen teléfono (valor no nulo) 
(8 registros):
 
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):
 
7- Muestre la cantidad de mujeres mayores de 25 años que acudieron al stand (4):
 
8- Muestre la cantidad de visitantes que no son de "Cordoba" (5):
 
9- Muestre la cantidad de visitantes que realizaron alguna compra (7):
 
10- Muestre la cantidad de visitantes que no realizaron compras (3):
 


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":
 
5- Cuente la cantidad de libros devueltos (contando por fechadevuelto):
 
6- Cuente la cantidad de veces que se le prestaron libros a la persona con 
documento "23456789":
 
7- Cuente la cantidad de libros prestados en el mes de agosto: 
 
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',
'juancito@gmail.com');
 insert into agenda values('Garcia','Ana','Urquiza 367','4226677',
'anamariagarcia@hotmail.com');
 insert into agenda values('Lopez','Juan','Avellaneda 900',null,
'juancitoLopez@gmail.com');
 insert into agenda values('Juarez','Mariana','Sucre 123','0525657687',
'marianaJuarez2@gmail.com');
 insert into agenda values('Molinari','Lucia','Peru 1254','4590987',
'molinarilucia@hotmail.com');
 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',
'perezluisalberto@hotmail.com');
 insert into agenda values('Lopez','Maria','Salta 314',null,
'lopezmariayo@gmail.com');

4- Cuente cuántos de sus amigos tienen mail:
 
5-Cuente cuántos de sus amigos tienen teléfono:
 
6- Cuente cuántos se apellidan "Perez":