esquema de la base de datos: esquema.txt
datos: datos.txt
Vamos a empezar a trabajar con las consultas. Para extraer datos de una tabla se necesita la orden select. A medida que avancemos en el curso iremos añadiendo modificaciones que conseguirán distintos tipos de resultados.
Utilizaremos la base de datos tienda que ya suponemos cargada en tu servidor. Ahora mismo, solo vamos a utilizar la tabla ARTICULO, que contiene las siguientes columnas:
un código identificador
un nombre
precio
y unidad, si se vende por kilos, litros o unidades, por ejemplo.
Ya ves que hay varias formas de consultar el esquema de una tabla pero te recomendamos que tengas siempre a mano el esquema de toda la base de datos:
CREATE TABLE IF NOT EXISTS provincia (
codp char(2) NOT NULL,
nombre char(25) NOT NULL,
PRIMARY KEY (codp)
);
CREATE TABLE IF NOT EXISTS usuario (
email varchar(50) NOT NULL,
nombre varchar(35) NOT NULL,
apellidos varchar(55) NOT NULL,
dni varchar(12) NOT NULL,
telefono varchar(15) DEFAULT NULL,
calle varchar(45) DEFAULT NULL,
codpos varchar(5) DEFAULT NULL,
provincia char(2) DEFAULT NULL,
localidad char(4) DEFAULT NULL,
nacido date DEFAULT NULL,
PRIMARY KEY (email),
UNIQUE KEY dni_UNIQUE (dni),
CONSTRAINT FK_usuario_loc FOREIGN KEY (provincia, localidad) REFERENCES localidad (provincia, codloc)
);
CREATE TABLE IF NOT EXISTS articulo (
cod char(5) NOT NULL,
nombre varchar(45) DEFAULT NULL,
precio decimal(5,2) DEFAULT NULL,
unidad char(1) DEFAULT NULL,
PRIMARY KEY (cod),
CONSTRAINT articulo_ibfk_1 FOREIGN KEY (unidad) REFERENCES unidad (unidad)
);
CREATE TABLE IF NOT EXISTS contiene (
empaquetado char(7) NOT NULL,
articulo char(5) NOT NULL,
cantidad decimal(5,2) DEFAULT NULL,
PRIMARY KEY (empaquetado,articulo),
CONSTRAINT fk_contiene_articulo1 FOREIGN KEY (articulo) REFERENCES articulo (cod),
CONSTRAINT fk_contiene_empaquetado FOREIGN KEY (empaquetado) REFERENCES empaquetado (cod)
);
CREATE TABLE IF NOT EXISTS pedido (
numpedido mediumint(8) unsigned NOT NULL,
usuario varchar(50) NOT NULL,
fecha datetime NOT NULL,
transportista char(4) DEFAULT NULL,
PRIMARY KEY (numpedido),
CONSTRAINT fk_PEDIDO_TRANSPORTE FOREIGN KEY (transportista) REFERENCES transporte (cod),
CONSTRAINT FK_pedido_usu FOREIGN KEY (usuario) REFERENCES usuario (email)
);
CREATE TABLE IF NOT EXISTS unidad (
unidad char(1) NOT NULL,
nombre varchar(15) DEFAULT NULL,
PRIMARY KEY (unidad)
);
CREATE TABLE IF NOT EXISTS localidad (
provincia char(2) NOT NULL DEFAULT '',
codloc char(4) NOT NULL DEFAULT '',
nombre varchar(80) DEFAULT NULL,
PRIMARY KEY (provincia,codloc),
CONSTRAINT localidad_ibfk_1 FOREIGN KEY (provincia) REFERENCES provincia (codp)
);
CREATE TABLE IF NOT EXISTS empaquetado (
cod char(7) NOT NULL,
nombre varchar(45) DEFAULT NULL,
pvp decimal(7,2) DEFAULT NULL,
especificaciones varchar(1024) DEFAULT NULL,
PRIMARY KEY (cod)
);
CREATE TABLE IF NOT EXISTS transporte (
cod char(4) NOT NULL,
nombre varchar(25) DEFAULT NULL,
url varchar(60) DEFAULT NULL,
PRIMARY KEY (cod)
);
CREATE TABLE IF NOT EXISTS linped (
numpedido mediumint(8) unsigned NOT NULL,
linea tinyint(3) unsigned NOT NULL,
articulo char(7) NOT NULL,
pagado decimal(9,2) NOT NULL,
cantidad tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (linea,numpedido),
CONSTRAINT FKpedido FOREIGN KEY (numPedido) REFERENCES pedido (numpedido),
CONSTRAINT fk_LINPED_ARTICULO FOREIGN KEY (articulo) REFERENCES empaquetado (cod));
use tienda;
En realidad ahora mismo no vamos a usar la tabla, simplemente veremos que la orden select sirve igualmente para mostrar constantes, incluso el resultado de algún cálculo.
select 'hola';
select 1+1;
select '1+1';
select 'el resultado de 1+1 es',1+1;
Lo que vemos son tablas encabezadas por la expresión que sigue a la palabra select y, a continuación, una fila con el resultado: una cadena de caracteres, 2 como suma de 1 y 1, la cadena "1+1" y, finalmente, un texto informativo y nuevamente el cálculo.
También podemos usar funciones del sistema. Esta, por ejemplo, nos dice la fecha y la hora en el momento en que se ha ejecutado.
select now();
La mayoría de las veces vamos a consultar tablas. Para eso necesitamos la parte from.
Si usamos el asterisco queremos decir "todas la columnas". Con el from le estamos diciendo de qué tabla saldrán los datos.
select * from articulo;
Si no queremos todas sino algunas de las columnas de las tablas, las especificamos en la select:
select cod from articulo;
Incluso todas, no necesariamente en el mismo orden en el que aparecen en la definición de la tabla:
select cod,nombre,unidad from articulo;
Es fácil que una consulta produzca duplicados, sobre todo si solo pedimos alguna de las columnas:
select unidad
from articulo;
select distinct unidad
from articulo;
Fíjate que la primera consulta ha obtenido 20 filas y un montón de duplicados. Sin embargo, en la segunda consulta, vemos que realmente solo hay 3 valores diferentes almacenados en la tabla en este momento.
Es el efecto del modificador distinct. Pero, cuidado, cuando decimos duplicado es duplicado de filas. Por ejemplo:
select cod,unidad
from articulo;
select distinct cod,unidad
from articulo;
No hay diferencia entre los resultados, y es porque ninguna fila se repite.
Te habrás fijado en que las cabeceras de los resultados han sido hasta ahora los nombres originales de las columnas de ARTICULO. Si queremos cambiarlo solo hay que poner un nombre alternativo a continuación del nombre de columna, y antes de la coma o del from.
select precio PVP, unidad, cod Artículo, nombre descripcion
from articulo;
Para ordenar por una columna, order by; y si lo queremos en orden ascendente o descendente.
select * from articulo order by unidad;
select * from articulo order by unidad ASC;
select * from articulo order by unidad DESC;
Si no decimos nada, ascendente, aunque podemos usar ASC. Sin embargo, si lo queremos descendente necesitamos el modificador DESC.
Se puede ordenar por varias columnas.
select cod,precio,unidad from articulo order by unidad,precio;
El resultado se ordena por la primera columna del order by y, para las filas donde este valor se repite, se utiliza la segunda columna.
En esta consulta se ordena primero por "unidad" ascendentemente y, cuando hay valores repetidos, por "precio" descendentemente:
select cod,precio,unidad
from articulo
order by unidad,precio DESC;
En esta otra el orden de "unidad" es descendente pero el de precio es ascendente:
select cod,precio,unidad
from articulo
order by unidad DESC,precio;
Y en esta última, ambos criterios son descendentes:
select cod,precio,unidad
from articulo
order by unidad DESC,precio DESC;
La posibilidad de equivocarse es alta, estamos escribiendo en un teclado. Cuando se produzca un error, siempre tienes que mirar en primer lugar el panel de mensajes. Lo normal es que te dé una pista fiable de qué ha pasado.
El caso típico del nombre de tabla erróneo.
select * from article;
Más típico, no acordarse del nombre real de una columna.
select codigo,nombre from articulo;
Estos son difíciles de ver sin ayuda, nos falta un carácter en distinct.
select distint unidad from articulo;
Y el más importante, la orden select tiene una sintaxis rígida, select va antes que from, from antes que order by… y más cosas que veremos más adelante.
from articulo select unidad;