61 - Funciones de control de flujo (case)


Problema:

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

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;



Retornar