jueves, 8 de noviembre de 2012

58 - Tipo de dato set.


El tipo de dato "set" representa un conjunto de cadenas.

Puede tener 1 ó más valores que se eligen de una lista de valores permitidos que se especifican al definir el campo y se separan con comas. Puede tener un máximo de 64 miembros. Ejemplo: un campo definido como set ('a', 'b') not null, permite los valores 'a', 'b' y 'a,b'. Si carga un valor no incluido en el conjunto "set", se ignora y almacena cadena vacía.

Es similar al tipo "enum" excepto que puede almacenar más de un valor en el campo.

Una empresa necesita personal, varias personas se han presentado para cubrir distintos cargos. La empresa almacena los datos de los postulantes a los puestos en una tabla llamada "postulantes". Le interesa, entre otras cosas, saber los distintos idiomas que conoce cada persona; para ello, crea un campo de tipo "set" en el cual guardará los distintos idiomas que conoce cada postulante.

Para definir un campo de tipo "set" usamos la siguiente sintaxis:

create table postulantes(
 numero int unsigned auto_increment,
 documento char(8),
 nombre varchar(30),
 idioma set('ingles','italiano','portuges'),
 primary key(numero)
);

Ingresamos un registro:

 insert into postulantes (documento,nombre,idioma)
  values('22555444','Ana Acosta','ingles');

Para ingresar un valor que contenga más de un elemento del conjunto, se separan por comas, por ejemplo:

 insert into postulantes (documento,nombre,idioma)
  values('23555444','Juana Pereyra','ingles,italiano');

No importa el orden en el que se inserten, se almacenan en el orden que han sido definidos, por ejemplo, si ingresamos:

 insert into postulantes (documento,nombre,idioma)
  values('23555444','Juana Pereyra','italiano,ingles');

en el campo "idioma" guardará 'ingles,italiano'.

Tampoco importa si se repite algún valor, cada elemento repetido, se ignora y se guarda una vez y en el orden que ha sido definido, por ejemplo, si ingresamos:

 insert into postulantes (documento,nombre,idioma)
  values('23555444','Juana Pereyra','italiano,ingles,italiano');
en el campo "idioma" guardará 'ingles,italiano'.

Si ingresamos un valor que no está en la lista "set", se ignora y se almacena una cadena vacía, por ejemplo:

 insert into postulantes (documento,nombre,idioma) 
  values('22255265','Juana Pereyra','frances');

Si un "set" permite valores nulos, el valor por defecto es "null"; si no permite valores nulos, el valor por defecto es una cadena vacía.

Si se ingresa un valor de índice fuera de rango, coloca una cadena vacía. Por ejemplo:

 insert into postulantes (documento,nombre,idioma)
  values('22255265','Juana Pereyra',0);
 insert into postulantes (documento,nombre,idioma)
  values('22255265','Juana Pereyra',8);

Si se ingresa un valor numérico, lo interpreta como índice de la enumeración y almacena el valor de la lista con dicho número de índice. Los valores de índice se definen en el siguiente orden, en este ejemplo:

1='ingles',
2='italiano',
3='ingles,italiano',
4='portugues',
5='ingles,portugues',
6='italiano,portugues',
7='ingles,italiano,portugues'.

Ingresamos algunos registros con valores de índice:

 insert into postulantes (documento,nombre,idioma)
   values('22255265','Juana Pereyra',2);
 insert into postulantes (documento,nombre,idioma)
  values('22555888','Juana Pereyra',3);

En el campo "idioma", con la primera inserción se almacenará "italiano" que es valor de índice 2 y con la segunda inserción, "ingles,italiano" que es el valor con índice 3.

Para búsquedas de valores en campos "set" se utiliza el operador "like" o la función "find_in_set()".

Para recuperar todos los valores que contengan la cadena "ingles" podemos usar cualquiera de las siguientes sentencias:

 select * from postulantes
  where idioma like '%ingles%';
 select * from postulantes
  where find_in_set('ingles',idioma)>0;

La función "find_in_set()" retorna 0 si el primer argumento (cadena) no se encuentra en el campo set colocado como segundo argumento. Esta función no funciona correctamente si el primer argumento contiene una coma.

Para recuperar todos los valores que incluyan "ingles,italiano" tipeamos:

 select * from postulantes
  where idioma like '%ingles,italiano%';

Para realizar búsquedas, es importante respetar el orden en que se presentaron los valores en la definición del campo; por ejemplo, si se busca el valor "italiano,ingles" en lugar de "ingles,italiano", no retornará registros.

Para buscar registros que contengan sólo el primer miembro del conjunto "set" usamos:

 select * from postulantes
  where idioma='ingles';

También podemos buscar por el número de índice:

 select * from postulantes
  where idioma=1;

Para buscar los registros que contengan el valor "ingles,italiano" podemos utilizar cualquiera de las siguientes sentencias:

 select * from postulantes
  where idioma='ingles,italiano'; 
 select * from postulantes
  where idioma=3;

También podemos usar el operador "not". Para recuperar todos los valores que no contengan la cadena "ingles" podemos usar cualquiera de las siguientes sentencias:

 select * from postulantes
  where idioma not like '%ingles%';
 select * from postulantes
  where not find_in_set('ingles',idioma)>0;

Los tipos "set" admiten cláusula "default".

Los bytes de almacenamiento del tipo "set" depende del número de miembros, se calcula así: (cantidad de miembros+7)/8 bytes; entonces puede ser 1,2,3,4 u 8 bytes.


PROBLEMA RESUELTO


Una empresa necesita personal, varias personas se han presentado para cubrir distintos cargos. La empresa almacena los datos de los postulantes a los puestos en una tabla llamada "postulantes". Le interesa, entre otras cosas, saber los distintos idiomas que conoce cada persona; para ello, crea un campo de tipo "set" en el cual guardará los distintos idiomas que conoce cada postulante.

Eliminamos la tabla, si existe.

Creamos la tabla definiendo un campo de tipo "set" usando la siguiente sintaxis:

 create table postulantes(
  numero int unsigned auto_increment,
  documento char(8),
  nombre varchar(30),
  idioma set('ingles','italiano','portuges'),
  primary key(numero)
 );

Ingresamos un registro:

 insert into postulantes (documento,nombre,idioma)
  values('22555444','Ana Acosta','ingles');

Ingresamos un valor que contiene 2 elementos del conjunto:

 insert into postulantes (documento,nombre,idioma)
  values('23555444','Juana Pereyra','ingles,italiano');

Recuerde que no importa el orden en el que se inserten, se almacenan en el orden que han sido definidos:

 insert into postulantes (documento,nombre,idioma)
  values('25555444','Andrea Garcia','italiano,ingles');

Tampoco importa si se repite algún valor, cada elemento repetido, se ignora y se guarda una vez y en el orden que ha sido definido:

 insert into postulantes (documento,nombre,idioma)
  values('27555444','Diego Morales','italiano,ingles,italiano');

Si ingresamos un valor que no está en la lista "set", se ignora y se almacena una cadena vacía:

 insert into postulantes (documento,nombre,idioma)
  values('27555464','Diana Herrero','frances');

También coloca una cadena vacía si ingresamos valore de índice fuera de rango:

 insert into postulantes (documento,nombre,idioma)
  values('28255265','Pedro Perez',0);
 insert into postulantes (documento,nombre,idioma)
  values('22255260','Nicolas Duarte',8);

Si un "set" permite valores nulos, el valor por defecto el "null":

 insert into postulantes (documento,nombre)
  values('28555464','Ines Figueroa');

Ingresemos un registro con el valor "ingles,italiano,portugues" para el campo "idioma" con su núméro de índice):

 insert into postulantes (documento,nombre,idioma)
  values('29255265','Esteban Juarez',7);

Busquemos valores de campos "set" utilizando el operador "like". Recuperemos todos los valores que contengan la cadena "ingles":

 select * from postulantes
  where idioma like '%ingles%';

Para recuperar todos los valores que incluyen "ingles,italiano", tipeamos:

 select * from postulantes
  where idioma like '%ingles,italiano%';

Recuerde que para las búsquedas, es importante respetar el orden en que se presentaron los valores en la definición del campo; intentemos buscar el valor "italiano,ingles" en lugar de "ingles,italiano", no retornará registros:

 select * from postulantes
  where idioma like '%italiano,ingles%';

Busquemos valores de campos "set" utilizando la función "find_in_set()". Recuperemos todos los postulantes que sepan inglés:

 select * from postulantes
  where find_in_set('ingles',idioma)>0;

Para localizar los registros que sólo contienen el primer miembro del conjunto "set" usamos:

 select * from postulantes
  where idioma='ingles';

También podemos buscar por el número de índice:

 select * from postulantes
  where idioma=1;

Para buscar los registros que contengan el valor "ingles,italiano,portugues" podemos utilizar:

 select * from postulantes
  where idioma=7;

Para recuperar todos los valores que NO contengan la cadena "ingles" podemos usar cualquiera de las siguientes sentencias:

 select * from postulantes
  where idioma not like '%ingles%';
 select * from postulantes
  where not find_in_set('ingles',idioma)>0;


PROBLEMA PROPUESTO

Una academia de enseñanza dicta distintos cursos de informática. Los cursos se dictan por la mañana 
(de 8 a 12 hs.) o por la tarde (de 16 a 20 hs.), distintos días a la semana. La academia guarda los 
datos de los cursos en una tabla llamada "cursos" en la cual almacena el código del curso, el tema, 
los días de la semana que se dicta, el horario, por la mañana (AM) o por la tarde (PM), la cantidad 
de clases que incluye cada curso (clases), la fecha de inicio y el costo del curso.

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

2- Cree la tabla "cursos" con la siguiente estructura:
 create table cursos(
  codigo tinyint unsigned auto_increment,
  tema varchar(20) not null,
  dias set ('lunes','martes','miercoles','jueves','viernes','sabado') not null,
  horario enum ('AM','PM') not null,
  clases tinyint unsigned default 1,
  fechainicio date,
  costo decimal(5,2) unsigned,
  primary key(codigo)
 );

3- Ingrese los siguientes registros:
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('PHP básico','lunes,martes,miercoles','AM',18,'2006-08-07',200);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('PHP básico','lunes,martes,miercoles','PM',18,'2006-08-14',200);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('PHP básico','sabado','AM',18,'2006-08-05',280);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('PHP avanzado','martes,jueves','AM',20,'2006-08-01',350);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('JavaScript','lunes,martes,miercoles','PM',15,'2006-09-11',150);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('Paginas web','martes,jueves','PM',10,'2006-08-08',250);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('Paginas web','sabado','AM',10,'2006-08-12',280);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('Paginas web','lunes,viernes','AM',10,'2006-08-21',200);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('Paginas web','lunes,martes,miercoles,jueves,viernes','AM',10,'2006-09-18',180);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('Paginas web','lunes,viernes','PM',10,'2006-09-25',280);
 insert into cursos (tema, dias,horario,clases,fechainicio,costo)
  values('JavaScript','lunes,martes,viernes,sabado','PM',12,'2006-09-18',150);

4- Una persona quiere inscribirse en un curso de "PHP" y sólo tiene disponibles los sábados. 
Localice los cursos de "PHP" que se dictan solamente los sábados:
 
5- Otra persona quiere aprender a diseñar páginas web, tiene disponibles todas las mañanas excepto 
los miércoles. Vea si existe algún curso que cumpla con sus necesidades:
 
6- Otra persona necesita aprender JavaScript, tiene disponibles todos las tardes excepto los jueves 
y quiere un curso que no supere las 15 clases para el mes de setiembre. Busque algún curso para 
esta persona:
 

Otros problemas:
 
A) Trabaje con la tabla "inmuebles" en la cual una inmobiliaria almacena la información referente a 
sus departamentos en venta.

1- Elimine la tabla "inmuebles" si existe.

2- Cree la tabla "inmuebles":
 create table inmuebles(
  detalles set ('estacionamiento','terraza','pileta','patio','ascensor'),
  domicilio varchar(30),
  propietario varchar(30),
  precio decimal (9,2) unsigned
 );

3- Ingrese algunos registros:
 insert into inmuebles (detalles,precio) 
  values('terraza,pileta',50000);
 insert into inmuebles (detalles,precio) 
  values('patio,terraza,pileta',60000);
 insert into inmuebles (detalles,precio) 
  values('ascensor,terraza,pileta',80000);
 insert into inmuebles (detalles,precio) 
  values('patio,estacionamiento',65000);
 insert into inmuebles (detalles,precio) 
  values('estacionamiento',90000);

4- Seleccione todos los datos de los departamentos con terraza:
 
5- Seleccione los departamentos que no tiene ascensor:
 
6- Muestre los inmuebles que tengan terraza y pileta solamente:
7-Muestre los inmuebles que no tengan ascensor y si estacionamiento, además de otros detalles:
 
8- Ingrese un registro con valor inexistente en "detalles":
 
9 Ingrese un registro sin valor para "detalles":
 

B) Una empresa de turismo vende paquetes de viajes a México y almacena la información referente a 
los mismos en una tabla llamada "viajes":

1- Elimine la tabla si existe.

2- Cree la tabla:
 create table viajes(
  codigo int unsigned auto_increment,
  nombre varchar(50),
  pension enum ('no','media','completa') not null,
  ciudades set ('Acapulco','DF','Cancun','Puerto Vallarta','Cuernavaca') not null,
  dias tinyint unsigned,
  salida date,
  precioporpersona decimal(8,2) unsigned,
  primary key(codigo)
 );

3- Ingrese los siguientes registros:
 insert into viajes (nombre,pension,ciudades,dias,salida)
  values ('Mexico mágico','completa','DF,Acapulco',15,'2005-12-01');
 insert into viajes (nombre,pension,ciudades,dias,salida)
  values ('Mexico especial','media','DF,Acapulco,Cuernavaca',28,'2005-05-10');
 insert into viajes (nombre,pension,ciudades,dias,salida)
  values ('Mexico unico','no','Acapulco,Puerto Vallarta',7,'2005-11-15');
 insert into viajes (nombre,pension,ciudades,dias,salida)
  values ('Mexico DF','no','DF',5,'2005-10-25');
 insert into viajes (nombre,pension,ciudades,dias,salida)
  values ('Mexico caribeño','completa','Cancun',15,'2005-10-25');

4- Ingrese un registro sin valor para el campo "ciudades":
 insert into viajes (nombre,pension,dias,salida)
  values ('Mexico maravilloso','completa',5,'2005-10-25');

5- Seleccione todos los viajes que incluyan "Acapulco":

6- Seleccione todos los viajes que no incluyan "Acapulco" y que incluyan pensión completa:
 
7- Muestre los viajes que incluyan "Puerto Vallarta" o "Cuernavaca":

No hay comentarios:

Publicar un comentario