36 - Selección de un grupo de registros (having) |
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;