Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


Intro a SQL y MySQL - Tema 2 - Consultas básicas con dos tablas

2.1 Formalizando conceptos

Hay una serie de detalles que hemos pasado por alto y que deberíamos formalizar un poco antes de seguir:

SELECT nombre FROM personas;

 

2.2 ¿Por qué varias tablas?

Puede haber varios motivos:

Por una parte, podemos tener bloques de información claramente distintos. Por ejemplo, en una base de datos que guarde la información de una empresa tendremos datos como los artículos que distribuimos y los clientes que nos los compran, que no deberían guardarse en una misma tabla.

Por otra parte, habrá ocasiones en que descubramos que los datos, a pesar de que se podrían clasificar dentro de un mismo "bloque de información" (tabla), serían redundantes: existiría gran cantidad de datos repetitivos, y esto puede dar lugar a dos problemas:

 

Veamos unos datos de ejemplo, que podrían ser parte de una tabla ficticia:

+---------+-----------+-----------+
| nombre  | direccion | ciudad    |
+---------+-----------+-----------+
| juan    | su casa   | alicante  |
| alberto | calle uno | alicante  |
| pedro   | su calle  | alicantw  |
+---------+-----------+-----------+

Si en vez de repetir "alicante" en cada una de esas fichas, utilizásemos un código de ciudad, por ejemplo "a", gastaríamos menos espacio (en este ejemplo, 7 bytes menos en cada ficha; con la capacidad de un ordenador actual eso no sería un gran problema).

Por otra parte, hemos tecleado mal uno de los datos: en la tercera ficha no hemos indicado "alicante", sino "alicantw", de modo que si hacemos consultas sobre personas de Alicante, la última de ellas no aparecería. Al teclear menos, es también más difícil cometer este tipo de errores.

A cambio, necesitaremos una segunda tabla, en la que guardemos los códigos de las ciudades, y el nombre al que corresponden (por ejemplo: si códigoDeCiudad = "a", la ciudad es "alicante").

Esta tabla se podría crear así:

create table ciudades (
  codigo varchar(3),
  nombre varchar(30)
);

 

2.3 Las claves primarias

Generalmente, y especialmente cuando se usan varias tablas enlazadas, será necesario tener algún dato que nos permita distinguir de forma clara los datos que tenemos almacenados. Por ejemplo, el nombre de una persona no es único: pueden aparecer en nuestra base de datos varios usuarios llamados "Juan López". Si son nuestros clientes, debemos saber cual es cual, para no cobrar a uno de ellos un dinero que corresponde a otro. Eso se suele solucionar guardando algún dato adicional que sí sea único para cada cliente, como puede ser el Documento Nacional de Identidad, o el Pasaporte. Si no hay ningún dato claro que nos sirva, en ocasiones añadiremos un "código de cliente", inventado por nosotros, o algo similar.

Estos datos que distinguen claramente unas "fichas" de otras los llamaremos "claves primarias".

Se puede crear una tabla indicando su calve primaria si se añade "PRIMARY KEY" al final de la orden "CREATE TABLE", así:

create table ciudades (
  codigo varchar(3),
  nombre varchar(30),
  primary key (codigo)
);

o bien al final de la definición del campo correspondiente, así:

create table ciudades (
  codigo varchar(3) primary key,
  nombre varchar(30)
);

 

2.4 Creando datos

Comenzaremos creando una nueva base de datos, de forma similar al ejemplo anterior:

create database ejemplo2;
use ejemplo2;

Después creamos la tabla de ciudades, que guardará su nombre y su código. Este código será el que actúe como "clave primaria", para distinguir otra ciudad. Por ejemplo, hay una ciudad llamado "Toledo" en España, pero también otra en Argentina, otra en Uruguay, dos en Colombia, una en Ohio (Estados Unidos)... el nombre claramente no es único, así que podríamos usar código como "te" para Toledo de España, "ta" para Toledo de Argentina y así sucesivamente.

La forma de crear la tabla con esos dos campos y con esa clave primaria sería:

create table ciudades (
  codigo varchar(3),
  nombre varchar(30),
  primary key (codigo)
);

Mientras que la tabla de personas sería casi igual al ejemplo anterior, pero añadiendo un nuevo dato: el código de la ciudad

create table personas (
  nombre varchar(20),
  direccion varchar(40),
  edad decimal(3),
  codciudad varchar(3)
);

Para introducir datos, el hecho de que exista una clave primaria no supone ningún cambio, salvo por el hecho de que no se nos dejaría introducir dos ciudades con el mismo código:

insert into ciudades values ('a', 'alicante');
insert into ciudades values ('b', 'barcelona');
insert into ciudades values ('m', 'madrid');

insert into personas values ('juan', 'su casa', 25, 'a');
insert into personas values ('pedro', 'su calle', 23, 'm');
insert into personas values ('alberto', 'calle uno', 22, 'b');

 

2.5 Mostrando datos

Cuando queremos mostrar datos de varias tablas a la vez, deberemos hacer unos pequeños cambios en las órdenes "select" que hemos visto:

Por eso, una consulta básica sería algo parecido (sólo parecido) a:

select personas.nombre, direccion, ciudades.nombre from personas, ciudades;

Pero esto todavía tiene problemas: estamos combinando TODOS los datos de la tabla de personas con TODOS los datos de la tabla de ciudades, de modo que obtenemos 3x3 = 9 resultados:

+---------+-----------+-----------+
| nombre | direccion | nombre |
+---------+-----------+-----------+
| juan | su casa | alicante |
| pedro | su calle | alicante |
| alberto | calle uno | alicante |
| juan | su casa | barcelona |
| pedro | su calle | barcelona |
| alberto | calle uno | barcelona |
| juan | su casa | madrid |
| pedro | su calle | madrid |
| alberto | calle uno | madrid |
+---------+-----------+-----------+
9 rows in set (0.00 sec)

Pero esos datos no son reales: si "juan" vive en la ciudad de código "a", sólo debería mostrarse junto al nombre "alicante". Nos falta indicar esa condición: "el código de ciudad que aparece en la persona debe ser el mismo que el código que aparece en la ciudad", así:

select personas.nombre, direccion, ciudades.nombre
from personas, ciudades 
where personas.codciudad = ciudades.codigo;

Esta será la forma en que trabajaremos normalmente. Este último paso se puede evitar en ciertas circunstancias, pero ya lo veremos más adelante. El resultado de esta consulta sería:

+---------+-----------+-----------+
| nombre | direccion | nombre |
+---------+-----------+-----------+
| juan | su casa | alicante |
| alberto | calle uno | barcelona |
| pedro | su calle | madrid |
+---------+-----------+-----------+

Ese sí es el resultado correcto. Cualquier otra consulta que implique las dos tablas deberá terminar comprobando que los dos códigos coinciden. Por ejemplo, para ver qué personas viven en la ciudad llamada "madrid", haríamos:

select personas.nombre, direccion, edad 
from personas, ciudades 
where ciudades.nombre='madrid' 
and personas.codciudad = ciudades.codigo;

+--------+-----------+------+
| nombre | direccion | edad |
+--------+-----------+------+
| pedro | su calle | 23 |
+--------+-----------+------+

Y para saber las personas de ciudades que comiencen con la letra "b", haríamos:

select personas.nombre, direccion, ciudades.nombre 
from personas, ciudades 
where ciudades.nombre like 'b%' 
and personas.codciudad = ciudades.codigo;

+---------+-----------+-----------+
| nombre | direccion | nombre |
+---------+-----------+-----------+
| alberto | calle uno | barcelona |
+---------+-----------+-----------+

Si en nuestra tabla puede haber algún dato que se repita, como la dirección, podemos pedir un listado sin duplicados, usando la palabra "distinct":

select distinct direccion from personas;

 

2.6 Ejecutando un lote de órdenes

Hasta ahora hemos tecleado todas las órdenes desde dentro del entorno de MySQL, una por una. Tenemos otra opción que también puede ser cómoda: crear un fichero de texto que contenga todas las órdenes (por ejemplo, usando un editor de texto avanzado, como Geany o Notepad++) y cargarlo después desde MySQL. Lo podemos hacer de tres formas:

source ejemplo2.sql;

mysql -u root < ejemplo2.sql;

(Pero esta alternativa tiene un problema: se darán los pasos que indiquemos en "ejemplo2.sql" y se abandonará el entorno de MySQL, sin que nos dé tiempo de comprobar si ha existido algún mensaje de error.)

2.7. Ejercicios propuestos

Ya sabes que deberías practicar antes de seguir avanzando. Aquí tienes una segunda tanda de ejercicios propuestos. Si te surgen dudas o quieres exponer tus soluciones, puedes usar el foro de SQL de AprendeAProgramar.com.