pasos para crear una base de datos en MySQL
pasos para crear una
base de datos
para saber crear una base de datos aquí hay un ejemplo hecho
en MySQL:
Suponga que en su hogar posee varias mascotas y desea registrar
distintos tipos de información sobre ellas. Puede hacerlo si crea tablas para
almacenar sus datos e introduce en ellas la información deseada. Entonces,
podrá responder una variedad de preguntas acerca de sus mascotas recuperando
datos desde las tablas. Esta sección le muestra como:
·
Crear una base de datos
·
Crear una tabla
·
Introducir datos en la tabla
·
Recuperar datos desde la tabla de varias maneras
·
Emplear múltiples tablas
Mediante la sentencia SHOW se encuentran las bases de datos
que existen actualmente en el servidor:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
Probablemente la lista obtenida sea
distinta en su ordenador, pero es casi seguro que tendrá las bases de datosmysql y test. La base de datos mysql es necesaria porque es la que
describe los privilegios de acceso de los usuarios. La base de datos test se provee para que los usuarios
hagan pruebas.
Tenga en cuenta que si no tiene el
privilegio SHOW
DATABASES, no podrá ver todas las bases de datos que hay en el servidor.
Si la base de datos test existe, intente acceder a ella:
mysql> USE test
Database changed
Advierta que, al igual que QUIT, USE no necesita que ponga un punto y
coma al final (aunque puede hacerlo si lo desea). La sentencia USE tiene otra particularidad: debe
escribirse en una sola linea.
Puede colocar los ejemplos siguientes
en la base de datos test, si tiene acceso a ella, pero si
trabaja en un ambiente compartido, lo que deposite allí puede ser fácilmente
borrado por alguien más que tenga el acceso. Por este motivo, debería pedirle a
su administrador permiso para usar una base de datos propia. Suponga que quiere
llamarla menagerie. El administrador
necesitará ejecutar un comando como este:
mysql> GRANT
ALL ON menagerie.* TO 'su_nombre_mysql'@'su_host_cliente';
Donde su_nombre_mysql es el nombre de
usuario que se le asignó, y su_host_cliente es el host u ordenador desde
donde se conectará.
Crear una tabla
La creación de la base de datos ha sido
una tarea sencilla, pero hasta ahora permanece vacía, como le muestra SHOW TABLES:
mysql> SHOW
TABLES;
Empty set (0.00
sec)
Querrá una tabla para contener un
registro por cada mascota. Esta tabla puede llamarse pet, y debería contener, como mínimo, el
nombre de cada animal. Dado que el nombre no es muy relevante por sí mismo,
tendría que tener más información. Por ejemplo, si más de una persona en su
familia tendrá mascotas, querrá listar también el dueño de cada animal. Y
algunos otros datos descriptivos básicos, como especie y sexo.
¿Qué hacer con la edad? Podría ser de interés, pero no es un buen dato
para almacenar en una base de datos. La edad cambia a medida que pasa el
tiempo, lo cual significa que debería actualizar la base de datos a menudo. En
lugar de esto, es mejor almacenar un valor fijo, como la fecha de nacimiento.
De este modo, cada vez que requiera saber la edad, podrá calcularla como la
diferencia entre la fecha de nacimiento y la fecha actual. MySQL provee
funciones para realizar cálculos con fechas, por lo que no es dificultoso.
Almacenar la fecha de nacimiento en lugar de la edad tiene otras ventajas:
·
Puede usar la base de datos para tareas como generar recordatorios para
los próximos cumpleaños de mascotas. (Si piensa que este tipo de consultas no
es importante, considere que es lo mismo que haría en un contexto de base de
datos de negocios para identificar aquellos clientes a los que habrá que enviar
una tarjeta por su cumpleaños, para conseguir ese toque personal con la
asistencia del ordenador).
·
Puede calcular edades en relación a otras fechas además de la actual.
Por ejemplo, almacenar la fecha de muerte de una mascota le posibilita calcular
la edad que tenía a ese momento.
Probablemente pensará en otros tipos de
información que resultarían útiles dentro de la tabla pet pero los identificados hasta
ahora son suficientes: name (nombre), owner (propietario), species (especie),
sex (sexo), birth (nacimiento) y death (muerte).
Debe usar la sentencia CREATE TABLE para
especificar la estructura de una tabla:
mysql>
CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(1),
birth DATE, death DATE);
El tipo de dato VARCHAR es una buena
elección para las columnas name, owner, y species porque los
datos que allí se almacenan no son de longitud uniforme. En realidad no es
necesario que todas estas columnas tengan la misma longitud ni que ésta
sea 20. En MySQL 5.0.3 y
versiones posteriores, normalmente se puede adoptar cualquier longitud
entre 1 y 65535, según lo que se crea más razonable. (Nota: Anteriormente a
MySQL 5.0.3, el límite de longitud era 255.) Si en el futuro debiera aumentar
la longitud de estos campos, MySQL tiene la sentencia ALTER TABLE.
Hay varios tipos de datos que podrían
usarse para representar el sexo en los registros de animales, tal como 'm' y 'f', o 'male' (masculino)
y 'female' (femenino). Lo
más simple es usar los caracteres 'm' y 'f'.
Es obvio el uso del tipo de dato DATE para las columnas birth y death.
Luego de crear una tabla, SHOW TABLES debería
producir una salida:
mysql> SHOW
TABLES;
+---------------------+
| Tables in
menagerie |
+---------------------+
| pet |
+---------------------+
Para verificar que la tabla ha sido
creada en la forma esperada, utilice la sentencia DESCRIBE:
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field |
Type | Null | Key | Default |
Extra |
+---------+-------------+------+-----+---------+-------+
| name |
varchar(20) | YES | | NULL
| |
| owner | varchar(20)
| YES | | NULL
| |
| species | varchar(20) | YES | |
NULL | |
| sex |
char(1) | YES | |
NULL | |
| birth |
date | YES | |
NULL | |
| death |
date | YES | |
NULL | |
+---------+-------------+------+-----+---------+-------+
Luego de crear la tabla, necesitará
completarla con datos. Para esto, le serán de utilidad las sentencias LOAD DATA e INSERT.
Suponga que los registros de mascotas
fueran como los mostrados a continuación. (Observe que MySQL espera que las
fechas tengan el formato 'AAAA-MM-DD', esto puede ser diferente a lo que
acostumbra utilizar).
|
name
|
owner
|
species
|
sex
|
birth
|
death
|
|
Fluffy
|
Harold
|
cat
|
f
|
1993-02-04
|
|
|
Claws
|
Gwen
|
cat
|
m
|
1994-03-17
|
|
|
Buffy
|
Harold
|
dog
|
f
|
1989-05-13
|
|
|
Fang
|
Benny
|
dog
|
m
|
1990-08-27
|
|
|
Bowser
|
Diane
|
dog
|
m
|
1979-08-31
|
1995-07-29
|
|
Chirpy
|
Gwen
|
bird
|
f
|
1998-09-11
|
|
|
Whistler
|
Gwen
|
bird
|
|
1997-12-09
|
|
|
Slim
|
Benny
|
snake
|
m
|
1996-04-29
|
|
Dado que está comenzando con una tabla vacía, una forma fácil de
completarla es creando un fichero de texto que contenga una línea por cada
animal, y luego insertando el contenido del fichero en la tabla mediante una
sola sentencia.
Para esto, debería crear un fichero de
texto llamado pet.txt, conteniendo un
registro por linea, con cada valor separado por un carácter de tabulación, y
dispuestos en el orden en el cual se especificaron las columnas en la
sentencia CREATE
TABLE. Para valores ausentes (como sexo desconocido o fechas de muerte de
animales con vida), puede usar valores NULL. Para representar estos valores en el
archivo de texto, utilice \N (barra diagonal y N mayúscula).
Por ejemplo, el registro de Whistler se vería del modo siguiente (el espacio en
blanco entre cada valor es un solo carácter de tabulación):
|
name
|
owner
|
species
|
sex
|
birth
|
death
|
|
Whistler
|
Gwen
|
bird
|
\N
|
1997-12-09
|
\N
|
Para cargar el fichero pet.txt dentro de la tabla pet, utilice este comando:
mysql> LOAD
DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
Si trabaja en Windows, con un editor
que emplea \r\n (retorno de
carro + nueva linea) como caracteres de fin de línea, debería usar:
mysql> LOAD
DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
-> LINES TERMINATED BY '\r\n';
(En un ordenador Apple bajo OS X,
probablemente quiera utilizar LINES TERMINATED BY '\r'.)
Opcionalmente puede especificar en la
sentencia LOAD
DATA los caracteres que actuarán como separador de campo y fin de
línea, pero los valores por defecto son tabulación y nueva línea. Estos son suficientes
para que la sentencia lea correctamente el fichero pet.txt
Si ocurre un error al ejecutar la sentencia, probablemente se deba a que
su instalación de MySQL no tiene habilitada por defecto la capacidad de manejar
archivos locales.
Cuando lo que desea es agregar nuevos
registros de a uno por vez, la sentencia INSERT resulta de
utilidad. De esta sencilla manera, se suministran valores para cada columna,
dispuestos en el orden en el cual se especificaron las columnas en la
sentencia CREATE
TABLE statement. Suponga que Diane obtiene un nuevo hamster llamado
"Puffball". Se podría agregar un nuevo registro, usando la
sentencia INSERT de este modo:
mysql>
INSERT INTO pet
-> VALUES
('Puffball','Diane','hamster','f','1999-03-30',NULL);
Observe que las cadenas alfanuméricas y
las fechas son representados como cadenas delimitadas por apóstrofos. También,
con INSERT, se pueden insertar
valores NULL directamente,
para indicar un valor ausente. No se debe utilizar \N como se hace con LOAD DATA.
A partir de este
ejemplo queda demostrado que lleva mucho más trabajo realizar una carga inicial
de registros empleando varias sentencias INSERT que si se hace
mediante la sentencia LOAD DATA.
Extraer información de una tabla
para extraer información de una tabla se debe seguir los
siguientes pasos
1. Seleccionar todos los dato
2. Seleccionar registros específicos
.3. Seleccionar columnas concretas
.4. Ordenar registros
.5. Cálculos sobre fechas
6. Trabajar con valores NULL
7. Coincidencia de patrones
8. Contar registros
9. Utilizar más de una tabla
La sentencia SELECT es utilizada
para traer información desde una tabla. La sintaxis general de esta sentencia
es:
SELECT seleccionar_Esto
FROM desde_tabla
WHERE condiciones;
seleccionar_esto es lo que se
quiere ver. Puede ser una lista de columnas, o * para indicar “todas
las columnas.” desde_tabla indica la tabla donde
están los datos a recuperar. La cláusula WHERE es opcional. Si está
presente, condiciones representa las
condiciones que cada registro debe cumplir para retornar como resultado.
Seleccionar todos los datos
La forma más simple de SELECT recupera todo
lo que hay en la tabla:
mysql>
SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name | owner
| species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Fluffy | Harold | cat | f
| 1993-02-04 | NULL |
| Claws | Gwen
| cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f
| 1989-05-13 | NULL |
| Fang | Benny
| dog | m | 1990-08-27 | NULL |
| Bowser | Diane
| dog | m | 1979-08-31 | 1995-07-29 |
| Chirpy | Gwen
| bird | f | 1998-09-11 | NULL |
| Whistler |
Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny
| snake | m | 1996-04-29 | NULL |
| Puffball |
Diane | hamster | f | 1999-03-30 | NULL |
+----------+--------+---------+------+------------+------------+
Esta forma de SELECT es útil si se
quiere revisar la tabla completa, por ejemplo, después de haberla cargado con
un conjunto de datos inicial. Por ejemplo, puede ocurrir que la fecha de
nacimiento de Bowser no parezca correcta. Consultando los papeles de pedigri,
se descubre que el año correcto de nacimiento es 1989, no 1979.
Existen al menos dos formas de solucionarlo:
·
Editando el fichero pet.txt para corregir el error, vaciando
la tabla y volviendola a llenar con los datos. Para esto se usan las
sentencias DELETE y LOAD DATA:
·
mysql> DELETE FROM pet;
·
mysql> LOAD DATA LOCAL
INFILE 'pet.txt' INTO TABLE pet;
No obstante, si opta
por esto, deberá volver a cargar el registro de Puffball.
·
Corrigiendo únicamente el registro erróneo. Para esto se usa la
sentencia UPDATE:
·
mysql> UPDATE pet SET
birth = '1989-08-31' WHERE name = 'Bowser';
UPDATE modifica solo
el registro en cuestión y no requiere que se vuelva a llenar la tabla.
Seleccionar registros específicos
Como se ha visto en la sección anterior, es fácil recuperar una tabla en
su totalidad. Sólo debe omitir la cláusula WHERE en la sentencia SELECT. Pero, generalmente,
no se desea ver la tabla completa, especialmente cuando alcanza un gran tamaño.
En cambio, usualmente, se tiene interés en obtener una respuesta para una
consulta en particular, en cuyo caso se especifican algunas restricciones para
la información que se traerá. A continuación se verán algunas consultas que
responden preguntas acerca de las mascotas.
Se pueden seleccionar sólo algunos registros de la tabla. Por ejemplo, si
quisiera verificar los cambios realizados sobre la fecha de nacimiento de
Bowser, seleccione el registro de Bowser de esta manera:
mysql>
SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth
| death |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog | m
| 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
La salida confirma que el año fue correctamente registrado como 1989, ya
no es 1979.
Normalmente, las comparaciones de cadenas no son case sensitive, por eso
puede escribir el nombre como 'bowser', 'BOWSER', etc. El resultado
de la consulta será el mismo.
Se pueden indicar condiciones a cumplir por cualquier columna, no
solamente por name. Por ejemplo, si
quisiera saber qué animales han nacido luego de 1998, necesita evaluar la
columna birth:
mysql>
SELECT * FROM pet WHERE birth > '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth
| death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen
| bird | f | 1998-09-11 | NULL |
| Puffball |
Diane | hamster | f | 1999-03-30 | NULL |
+----------+-------+---------+------+------------+-------+
Se pueden combinar condiciones, por ejemplo para localizar perros
hembra:
mysql>
SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Buffy |
Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
La consulta anterior emplea el operador lógico AND. También existe el operador OR:
mysql>
SELECT * FROM pet WHERE species = 'snake' OR species = 'bird';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth
| death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen
| bird | f | 1998-09-11 | NULL |
| Whistler |
Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m
| 1996-04-29 | NULL |
+----------+-------+---------+------+------------+-------+
AND and OR pueden ser combinadas, si
bien AND tiene mayor
precedencia que OR. Si utiliza ambos
operadores, es buena idea emplear paréntesis para indicar explicitamente la
forma en que las condiciones deben agruparse:
mysql>
SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
-> OR (species = 'dog' AND sex = 'f');
+-------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws |
Gwen | cat | m
| 1994-03-17 | NULL |
| Buffy |
Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Seleccionar columnas concretas
Si no se quieren ver filas completas, solo hace falta indicar las
columnas en las que se está interesado, separadas por comas. Por ejemplo, si
desea saber cuándo nació cada animal, seleccione las columnas name ybirth:
mysql>
SELECT name, birth FROM pet;
+----------+------------+
| name | birth |
+----------+------------+
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Buffy | 1989-05-13 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Chirpy | 1998-09-11 |
| Whistler |
1997-12-09 |
| Slim | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
Para saber quien posee mascotas, utilice esta consulta:
mysql>
SELECT owner FROM pet;
+--------+
| owner |
+--------+
| Harold |
| Gwen |
| Harold |
| Benny |
| Diane |
| Gwen |
| Gwen |
| Benny |
| Diane |
+--------+
Observe que esta sentencia retorna el
campo owner de cada
registro, y algunos de ellos aparecen más de una vez. Para reducir la salida,
recupere solamente una vez cada registro repetido, agregando la palabra
clave DISTINCT:
mysql>
SELECT DISTINCT owner FROM pet;
+--------+
| owner |
+--------+
| Benny |
| Diane |
| Gwen |
| Harold |
+--------+
Puede emplearse una clásula WHERE para combinar la selección de
ciertas filas y de ciertas columnas. Por ejemplo, para obtener únicamente la
fecha de nacimiento de perros y gatos, ejecute esta consulta:
mysql>
SELECT name, species, birth FROM pet
-> WHERE species = 'dog' OR species =
'cat';
+--------+---------+------------+
| name | species | birth |
+--------+---------+------------+
| Fluffy |
cat | 1993-02-04 |
| Claws | cat
| 1994-03-17 |
| Buffy | dog
| 1989-05-13 |
| Fang | dog
| 1990-08-27 |
| Bowser | dog
| 1989-08-31 |
+--------+---------+------------+
Ordenar registros
Quizá advirtió, en los ejemplos
anteriores, que las filas resultantes se mostraron sin ningún orden en
particular. A menudo es más fácil examinar la salida de una consulta cuando las
filas se ordenan de algún modo significativo. Para ordenar un resultado, se usa
la clásula ORDER
BY.
Aqui tiene las fechas de cumpleaños de
los animales, ordenadas por fecha:
mysql>
SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name | birth
|
+----------+------------+
| Buffy | 1989-05-13 |
| Bowser | 1989-08-31 |
| Fang | 1990-08-27 |
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Slim | 1996-04-29 |
| Whistler |
1997-12-09 |
| Chirpy | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
Por lo general, cuando se trata de
columnas de tipo carácter, la ordenación, — al igual que otras operaciones de
comparación — no es case-sensitive. Significa que el orden permanece indefinido
para las columnas que son idénticas excepto por sus mayúsculas y minúsculas.
Puede no obstante forzar a que una columna se ordene en forma sensible a
mayúsculas empleando el modificador BINARY: ORDER BY BINARY columna.
El sentido de ordenación, por defecto,
es ascendente, con los valores más pequeños primero. Para ordenar en sentido
inverso (descendente), agregue la palabra clave DESC luego del nombre de la columna
por la que ordena:
mysql>
SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name | birth |
+----------+------------+
| Puffball |
1999-03-30 |
| Chirpy | 1998-09-11 |
| Whistler |
1997-12-09 |
| Slim | 1996-04-29 |
| Claws | 1994-03-17 |
| Fluffy | 1993-02-04 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Buffy | 1989-05-13
|
+----------+------------+
Puede ordenar basándose en varias
columnas, y cada columna en un sentido diferente. Por ejemplo, para ordenar por
tipo de animal en sentido ascendente y, dentro de cada tipo, ordenar por
nacimiento en sentido descendente (los animales más jóvenes primero) utilice la
siguiente consulta:
mysql>
SELECT name, species, birth FROM pet
-> ORDER BY species, birth DESC;
+----------+---------+------------+
| name | species | birth |
+----------+---------+------------+
| Chirpy | bird
| 1998-09-11 |
| Whistler |
bird | 1997-12-09 |
| Claws | cat
| 1994-03-17 |
| Fluffy | cat
| 1993-02-04 |
| Fang | dog
| 1990-08-27 |
| Bowser | dog
| 1989-08-31 |
| Buffy | dog
| 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim |
snake | 1996-04-29 |
+----------+---------+------------+
Advierta que la
palabra clave DESC se aplica sobre
la columna inmediatamente anterior (birth); no afecta el sentido de ordenación
de la columna species.
Cálculos sobre fechas
MySQL provee varias funciones que se
aplican a cálculos entre fechas, por ejemplo, para calcular edades u obtener
partes de una fecha.
Para determinar cuántos años de edad
tiene cada mascota, hay que calcular la diferencia entre el año de la fecha
actual y el de la fecha de nacimiento, y luego restar 1 al resultado si el dia
y mes actuales son anteriores al día y mes indicados por la fecha de
nacimiento. La siguiente consulta devuelve, para cada mascota, el nombre, la fecha
de nacimiento, la fecha actual, y la edad en años.
mysql>
SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> -
(RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS age
-> FROM pet;
+----------+------------+------------+------+
| name | birth | CURDATE() | age
|
+----------+------------+------------+------+
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Chirpy |
1998-09-11 | 2003-08-19 | 4 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
| Slim |
1996-04-29 | 2003-08-19 | 7 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
+----------+------------+------------+------+
En el ejemplo anterior, YEAR() trae la parte
correspondiente al año de una fecha, y RIGHT() trae los 5
primeros caracteres contando desde la derecha, que representan la parte MM-DD de la fecha. La porción de la expresión
que compara los valores MM-DD devuelve 1 o 0, lo cual se
corresponde con la diferencia de 1 año a restar de la edad si el dia de la
fecha devuelto por CURDATE() ocurre antes que la fecha de
nacimiento birth. La expresión
completa es un tanto confusa para usar como encabezado, por lo que se emplea
un alias (age) para que el encabezado sea más
comprensible.
La consulta funciona bien, pero los
resultados podrían revisarse más fácilmente si las filas se presentaran en
algún orden. Esto puede hacerse agregando la cláusula ORDER BY name para ordenar
por nombre la salida:
mysql>
SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> -
(RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS age
-> FROM pet ORDER BY name;
+----------+------------+------------+------+
| name | birth | CURDATE() | age
|
+----------+------------+------------+------+
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
| Slim |
1996-04-29 | 2003-08-19 | 7 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
+----------+------------+------------+------+
Para ordenar la salida por edad (age) en lugar de por nombre (name), solo hay que utilizar una
cláusula ORDER
BY diferente:
mysql>
SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> -
(RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS YEAR
-> FROM pet ORDER BY age;
+----------+------------+------------+------+
| name | birth | CURDATE() | age
|
+----------+------------+------------+------+
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Puffball |
1999-03-30 | 2003-08-19 | 4 |
| Whistler |
1997-12-09 | 2003-08-19 | 5 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Fang |
1990-08-27 | 2003-08-19 | 12 |
| Bowser |
1989-08-31 | 2003-08-19 | 13 |
| Buffy |
1989-05-13 | 2003-08-19 | 14 |
+----------+------------+------------+------+
Una consulta similar se utiliza para
determinar la edad a la fecha de muerte de los animales. Se determinan los
animales que han muerto verificando si el valor de la columna death es NULL. Entonces, para todos los valores
no NULL calcula la
diferencia entre las fechas de muerte (death) y nacimiento (birth):
mysql>
SELECT name, birth, death,
-> (YEAR(death)-YEAR(birth)) -
(RIGHT(death,5)<RIGHT(birth,5))
-> AS age
-> FROM pet WHERE death IS NOT NULL
ORDER BY age;
+--------+------------+------------+------+
| name | birth
| death | age |
+--------+------------+------------+------+
| Bowser |
1989-08-31 | 1995-07-29 | 5 |
+--------+------------+------------+------+
La consulta utiliza la expresión death IS NOT NULL en lugar
de death
<> NULL porque NULL es un valor especial, que no
puede ser comparado mediante los operadores lógicos habituales.
¿Qué tal si se quisiera saber qué
animales cumplen años el próximo mes? Para esta clase de cálculos, el año y el
día son irrelevantes; simplemente se desea extraer de la columna birth la parte correspondiente al mes.
MySQL cuenta con varias funciones para extraer partes de fechas, como YEAR(), MONTH(), y DAYOFMONTH(). MONTH()es la función
apropiada para este caso. Para verla en funcionamiento, ejecute una consulta
que muestra tanto el valor de birth como el de MONTH(birth):
mysql>
SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name | birth | MONTH(birth) |
+----------+------------+--------------+
| Fluffy | 1993-02-04 | 2 |
| Claws | 1994-03-17 | 3 |
| Buffy | 1989-05-13 | 5 |
| Fang | 1990-08-27 | 8 |
| Bowser | 1989-08-31 | 8 |
| Chirpy | 1998-09-11 | 9 |
| Whistler | 1997-12-09 | 12 |
| Slim | 1996-04-29
| 4 |
| Puffball | 1999-03-30 | 3 |
+----------+------------+--------------+
Encontrar los animales que cumplen años
el mes siguiente es también sencillo. Suponga que el mes actual es abril. De
modo que su número es 4, y se buscan los animales nacidos en
Mayo (mes 5), de esta forma:
mysql>
SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name |
birth |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
Esto se complica ligeramente cuando el
mes actual es Diciembre. No se puede simplemente sumarle 1 al número del mes (12) y buscar animales nacidos en el
mes 13, porque no existe
tal mes. En lugar de eso, se debe buscar por animales nacidos en Enero
(mes 1).
Se puede incluso escribir la consulta
de forma que funcione sin importar cual es el mes actual. Así, no se necesitará
indicar un mes en particular en la consulta. DATE_ADD() sirve para
sumar un intervalo de tiempo a una fecha dada. Si se adiciona un mes al valor
de CURDATE(), y se extrae el mes
mediante MONTH(), el resultado será
el mes en el que se buscarán cumpleaños:
mysql>
SELECT name, birth FROM pet
-> WHERE MONTH(birth) =
MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
Una manera alternativa de alcanzar el
mismo resultado es sumar 1 al mes actual para obtener el mes
siguiente (después de emplear la función módulo (MOD) para dejar el número de mes en 0 si resultara ser 12:
mysql>
SELECT name, birth FROM pet
-> WHERE MONTH(birth) =
MOD(MONTH(CURDATE()), 12) + 1;
Advierta que MONTH devuelve un número entre 1 y 12. Y MOD(algun_valor,12) devuelve un
número entre 0 y 11. La suma debe ser realizada después
de MOD(), en otro caso se
estaría pasando de Noviembre (11) a Enero (1).
Trabajar con valores NULL
El valor NULL puede resultar un poco
desconcertante hasta que se comienza a utilizar. Conceptualmente, NULL significa valor
inexistente o desconocido, y es tratado de forma diferente a otros valores.
Para verificar que un valor es NULL, no se pueden emplear operadores de
comparación aritmética como =, <, o <>. Para comprobar
esto, intente la siguiente consulta:
mysql> SELECT 1 = NULL, 1 <> NULL, 1 <
NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 >
NULL |
+----------+-----------+----------+----------+
| NULL
| NULL | NULL |
NULL |
+----------+-----------+----------+----------+
Claramente, no se obtienen valores
significtivos a partir de estas comparaciones. Use en su lugar los
operadores IS
NULL y IS
NOT NULL:
mysql>
SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1
IS NOT NULL |
+-----------+---------------+
| 0
| 1 |
+-----------+---------------+
Observe que en MySQL, 0 o NULL se intepretan como falso, y
cualquier otro valor, como verdadero. El valor por defecto para una operación
booleana es 1.
Este tratamiento especial de NULL es debido a que, en la sección
anterior, fue necesario determinar qué animales ya no estaban vivos
utilizando death
IS NOT NULL en lugar de death <> NULL.
Dos valores NULL son considerados iguales por la
cláusula GROUP
BY.
Cuando se realiza un ORDER BY, los valores NULL se presentan en primer lugar si
se emplea ORDER
BY ... ASC, y al final si se ordena con ORDER BY ... DESC.
Un error muy común cuando se trabaja
con valores NULL es asumir que
es imposible insertar un valor cero o una cadena vacía en una columna definida
como NOT
NULL, pero no es así. Los mencionados son efectivamente valores, mientras
que NULL significa "no
hay un valor". Puede comprobar esto fácilmente empleando IS [NOT] NULL como se muestra
aquí:
mysql>
SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0
IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
| 0
| 1 | 0 | 1 |
+-----------+---------------+------------+----------------+
Por lo tanto, es totalmente posible insertar cadenas vacias o ceros en
columnas marcadas como NOT NULL, ya que son valores NOT NULL.
Coincidencia de patrones
MySQL posee capacidades estándar para
utilizar patrones así como también una forma de patrones basada en expresiones
regulares extendidas similares a las que se encuentran en utilidades de UNIX,
como ser vi, grep, y sed.
Los patrones SQL permiten emplear el
carácter '_' para representar
coincidencia con un carácter individual y '%' En MySQL, por defecto, los patrones
SQL no son case-sensitive. Abajo se muestran algunos ejemplos. Advierta que no
se emplean los operadores = o <> para trabajar
con patrones SQL, en lugar de eso se usan los operadores de comparación LIKE o NOT LIKE.
Para encontrar nombres que comiencen
con 'b':
mysql>
SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name | owner
| species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f
| 1989-05-13 | NULL |
| Bowser | Diane
| dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
Para encontrar nombres que terminen con
'fy':
mysql>
SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy |
Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f
| 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Para encontrar nombres que contengan 'w':
mysql>
SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name |
owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen
| cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m
| 1989-08-31 | 1995-07-29 |
| Whistler |
Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Para encontrar nombres que contengan
exactamente 5 caracteres, use 5 veces el carácter patrón '_':
mysql>
SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws |
Gwen | cat | m
| 1994-03-17 | NULL |
| Buffy |
Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Los otros patrones que pueden emplearse
con MySQL usan expresiones regulares extendidas. Cuando busque coincidencias
con este tipo de patrones, use los operadores REGEXP y NOT REGEXP (o bien los
sinónimos RLIKE y NOT RLIKE).
Algunas características de las
expresiones regulares extendidas:
·
'.' detecta
coincidencia con cualquier carácter individual.
·
Una clase de carácter '[...]' detecta coincidencia con cualquier carácter
entre los corchetes. Por ejemplo, '[abc]' coincidirá con 'a', 'b', o 'c'. Para hacer referencia a un rango de
caracteres, use un guión. '[a-z]' detecta coincidencia con cualquier
letra, mientras que '[0-9]' lo hace con
cualquier dígito.
·
'*' detecta
coincidencia con cero o más apariciones de los caracteres que lo preceden. Por
ejemplo, 'x*' detecta cualquier
número de caracteres 'x', '[0-9]*' detecta cualquier
cantidad de dígitos, y '.*' coincidirá con cualquier número de
cualquier carácter.
·
REGEXP tendrá éxito si el patrón
suministrado encuentra coincidencia en cualquier parte del valor examinado
(esto difiere de LIKE en que este
último solo tiene éxito si el patrón concuerda con todo el valor).
·
Para lograr que un patrón detecte coincidencias solamente al principio o
al final del valor examinado, utilice '^' al principio o '$' al final del patrón.
Para demostrar el funcionamiento de las
expresiones regulares extendidas, las consultas con LIKE expuestas anteriormente se han
reescrito utilizando REGEXP.
Para hallar nombres que comiencen con 'b', use '^' para buscar coincidencia al principio
del valor:
mysql>
SELECT * FROM pet WHERE name REGEXP '^b';
+--------+--------+---------+------+------------+------------+
| name | owner
| species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f
| 1989-05-13 | NULL |
| Bowser | Diane
| dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
En MySQL 5.0, si realmente quiere
forzar a que la comparación realizada por REGEXP sea case
sensitive, utilice la palabra clave BINARY para convertir a una de las
cadenas en una cadena binaria. Esta consulta solamente encontrará coincidencia
con 'b' minúsculas al
comienzo de un nombre:
mysql>
SELECT * FROM pet WHERE name REGEXP BINARY '^b';
Para hallar nombres finalizados en 'fy', emplee '$' para buscar la coincidencia en el
final del nombre:
mysql>
SELECT * FROM pet WHERE name REGEXP 'fy$';
+--------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy |
Harold | cat | f |
1993-02-04 | NULL |
| Buffy | Harold | dog | f
| 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Para encontrar nombres conteniendo una
'w', utilice esta
consulta:
mysql>
SELECT * FROM pet WHERE name REGEXP 'w';
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth
| death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen
| cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m
| 1989-08-31 | 1995-07-29 |
| Whistler |
Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Debido a que un patrón de expresión
regular encuentra coincidencia sin importar el lugar del valor donde se
produce, en la consulta previa no es necesario colocar un comodín a cada lado
del patrón para obtener coincidencia en cualquier parte del valor, como hubiera
sucedido de utilizar un patrón SQL
Para hallar nombres conteniendo
exactamente cinco caracteres, use '^' y '$' para obligar a que la coincidencia
deba estar al principio y al final del nombre, y cinco instancias de '.' entre ellas.
mysql>
SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws |
Gwen | cat | m
| 1994-03-17 | NULL |
| Buffy |
Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
La consulta anterior también se podría
haber escrito empleando el operador '{n}' “repetir-n-veces”:
+-------+--------+---------+------+------------+-------+
| name | owner
| species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws |
Gwen | cat | m
| 1994-03-17 | NULL |
| Buffy |
Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Contar registros
Una pregunta
frecuente que deben responder las bases de datos es: “¿qué
tan a menudo aparece en la tabla un cierto tipo de dato?” Por ejemplo, se
podría querer averiguar la cantidad de mascotas de que se dispone, o cuantas
mascotas tiene cada propietario, o varios otros recuentos sobre los animales.
Contar la cantidad total de animales es la misma pregunta que “¿cuántos
registros hay en la tabla pet?”, ya que hay un
registro por mascota. COUNT(*) cuenta el número de filas, por
ello, la consulta para contar animales luce así:
mysql>
SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
| 9 |
+----------+
Anteriormente se recuperaban los nombres de la gente que poseía
mascotas. Se puede usar COUNT() para hallar cuantas mascotas
tiene cada propietario:
mysql>
SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny |
2 |
| Diane |
2 |
| Gwen |
3 |
| Harold |
2 |
+--------+----------+
Observe el uso de GROUP BY para agrupar todos los registros
de cada propietario. Sin dicha cláusula, todo lo que se hubiera obtenido sería
un mensaje de error:
mysql>
SELECT owner, COUNT(*) FROM pet;
ERROR 1140
(42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
with no GROUP
columns is illegal if there is no GROUP BY clause
COUNT() y GROUP BY son útiles para
presentar datos en varias formas. Los siguientes ejemplos muestran diferentes
operaciones:
Cantidad de animales por especies:
mysql>
SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species |
COUNT(*) |
+---------+----------+
| bird |
2 |
| cat |
2 |
| dog |
3 |
| hamster |
1 |
| snake
| 1 |
+---------+----------+
Cantidad de animales por sexo:
mysql>
SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex | COUNT(*) |
+------+----------+
| NULL | 1 |
| f |
4 |
| m |
4 |
+------+----------+
(En esta salida, NULL indica "sexo
desconocido")
Cantidad de animales por combinación de especies y sexo:
mysql>
SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species |
sex | COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f
| 1 |
| cat | f
| 1 |
| cat | m
| 1 |
| dog | f
| 1 |
| dog | m
| 2 |
| hamster |
f |
1 |
| snake |
m | 1 |
+---------+------+----------+
No es necesario examinar una tabla entera cuando se emplea COUNT(). Por ejemplo, la
consulta anterior, se podria limitar a perros y gatos de esta manera:
mysql>
SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = 'dog' OR species =
'cat'
-> GROUP BY species, sex;
+---------+------+----------+
| species |
sex | COUNT(*) |
+---------+------+----------+
| cat | f
| 1 |
| cat | m
| 1 |
| dog |
f | 1 |
| dog |
m | 2 |
+---------+------+----------+
O si desea la cantidad de animales de cada sexo contando solamente los
que tienen sexo conocido:
mysql>
SELECT species, sex, COUNT(*) FROM pet
-> WHERE sex IS NOT NULL
-> GROUP BY species, sex;
+---------+------+----------+
| species |
sex | COUNT(*) |
+---------+------+----------+
| bird | f
| 1 |
| cat | f
| 1 |
| cat | m
| 1 |
| dog | f
| 1 |
| dog | m
| 2 |
| hamster |
f | 1 |
| snake | m
| 1 |
+---------+------+----------+
Utilizar más de una tabla
La tabla pet mantiene el registro de las
mascotas que se poseen. Si quisiera registrar otros datos acerca de ellas, como
eventos de su vida tales como visitas al veterinario o nacimiento de crías,
necesitaría otra tabla. ¿Cómo debería ser esta tabla? Se necesita:
·
Un campo con el nombre de la mascota para saber a quien pertenece cada
evento registrado.
·
La fecha en que ocurrió el evento.
·
Un campo con la descripción del evento.
·
Un campo con el tipo de evento, a fin de poder clasificarlo.
Teniendo en cuenta estas
consideraciones, la sentencia CREATE TABLE para la tabla event ("eventos", en inglés)
podría ser así:
mysql>
CREATE TABLE event (name VARCHAR(20), date DATE,
-> type VARCHAR(15), remark VARCHAR(255));
Como se hizo con la tabla pet, es más fácil realizar la carga
inicial de datos si se crea un archivo de texto delimitado con tabulaciones que
contenga la información a agregar:
|
name
|
date
|
type
|
remark
|
|
Fluffy
|
1995-05-15
|
litter
|
4
kittens, 3 female, 1 male
|
|
Buffy
|
1993-06-23
|
litter
|
5
puppies, 2 female, 3 male
|
|
Buffy
|
1994-06-19
|
litter
|
3
puppies, 3 female
|
|
Chirpy
|
1999-03-21
|
vet
|
needed
beak straightened
|
|
Slim
|
1997-08-03
|
vet
|
broken
rib
|
|
Bowser
|
1991-10-12
|
kennel
|
|
|
Fang
|
1991-10-12
|
kennel
|
|
|
Fang
|
1998-08-28
|
birthday
|
Gave him a new chew toy
|
|
Claws
|
1998-03-17
|
birthday
|
Gave him a new flea collar
|
|
Whistler
|
1998-12-09
|
birthday
|
First
birthday
|
Los registros se cargan así:
mysql> LOAD DATA
LOCAL INFILE 'event.txt' INTO TABLE event;
Con base en lo que se ha aprendido a
partir de las consultas efectuadas sobre la tabla pet, se debería poder recuperar registros
de la tabla event; los principios son
los mismos. Pero en un momento dado la tabla event por sí sola es insuficiente para
responder las preguntas que pueden formularse.
Suponga que se desea saber a qué edad
tuvo sus crías cada mascota. Anteriormente se aprendió a calcular edades a
partir de dos fechas. La fecha en que la mascota tuvo sus crias está en la
tabla event, pero para calcular
su edad, se necesita su fecha de nacimiento, la cual está localizada en la
tabla pet. Esto significa que
la consulta requiere ambas tablas:
mysql> SELECT pet.name,
-> (YEAR(date)-YEAR(birth)) - (RIGHT(date,5)<RIGHT(birth,5)) AS
age,
-> remark
-> FROM pet, event
-> WHERE pet.name = event.name AND
event.type = 'litter';
+--------+------+-----------------------------+
| name | age
| remark |
+--------+------+-----------------------------+
| Fluffy | 2 | 4 kittens, 3 female, 1 male |
| Buffy | 4
| 5 puppies, 2 female, 3 male |
| Buffy | 5
| 3 puppies, 3 female |
+--------+------+-----------------------------+
Hay varias cosas para observar en esta consulta:
·
La cláusula FROM menciona dos tablas porque la
consulta necesita traer datos de ambas
·
Cuando se combina (también se denomina join -unión, en inglés-)
información desde múltiples tablas, se necesita indicar qué registro de una
tabla se combinará con qué registro de la otra. Esto es sencillo porque ambas
tablas tienen una columna name. La consulta emplea la cláusula WHERE para hacer coincidir registros de
las dos tablas basándose en el valor de name.
·
Dado que la columna name aparece en ambas tablas, se debe
especificar a cuál tabla pertenece la columna al hacer referencia a ella. Esto
se hace anteponiendo el nombre de la tabla al nombre de la columna.
No es necesario tener dos tablas
diferentes para establecer una unión. A veces es útil combinar una tabla
consigo misma, si se desea comparar entre sí registros de una misma tabla. Por
ejemplo, para formar parejas de mascotas para reproducción, podría unir la
tabla pet consigo misma
para generar pares de animales macho y hembra de la misma especie:
mysql>
SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.species AND
p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name | sex
| name | sex | species |
+--------+------+--------+------+---------+
| Fluffy |
f | Claws | m
| cat |
| Buffy | f
| Fang | m | dog
|
| Buffy | f
| Bowser | m | dog |
+--------+------+--------+------+---------+
En la consulta anterior se especificaron
alias para la tabla con el fin de indicar a qué instancia de la tabla pertenece
cada columna referenciada.
No hay comentarios.:
Publicar un comentario