Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
CONSULTAS Y LENGUAJE
DE MANIPULACIN DE DATOS (DDL)
DML (Data Manipulation Language) Lenguaje de manipulacin de datos. Es el que se usa para modificar y obtener datos desde las bases de datos. 3.1 INSTRUCCIONES INSERT, DELETE y UPDATE
Insert La forma ms directa de insertar una fila nueva en una tabla es mediante una sentencia INSERT. En la forma ms simple de esta sentencia debemos indicar la tabla a la que queremos aadir filas, y los valores de cada columna. Las columnas de tipo cadena o fechas deben estar entre comillas sencillas o dobles, para las columnas numricas esto no es imprescindible, aunque tambin pueden estar entrecomilladas. Para estos ejemplos, se utilizar la BD denominada Prueba, realizada en la unidad anterior;
mysql> INSERT INTO gente VALUES ('Fulano','1974-04-12'); Query OK, 1 row affected (0.05 sec) mysql> INSERT INTO gente VALUES ('Mengano','1978-06-15'); Query OK, 1 row affected (0.04 sec) mysql> INSERT INTO gente VALUES('Tulano','2000-12-02'),('Pegano','1993-02-10'); Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0
Si no se necesita asignar un valor concreto para alguna columna, se indica el valor por defecto indicado para esa columna cuando se cre la tabla, usando la palabra DEFAULT:
mysql> INSERT INTO ciudad2 VALUES ('Perillo', DEFAULT); Query OK, 1 row affected (0.03 sec)
Otra opcin consiste en indicar una lista de columnas para las que se van a suministrar valores. A las columnas que no se nombren en esa lista se les asigna el valor por defecto. Este sistema, adems, permite usar cualquier orden en las columnas, con la ventaja, con respecto a la anterior forma, de que no necesitamos conocer el orden de las columnas en la tabla para poder insertar datos:
mysql> INSERT INTO ciudad5 (poblacion,nombre) VALUES (7000000, 'Madrid'), (9000000, 'Pars'), (3500000, 'Berln'); Query OK, 3 rows affected (0.05 sec) Records: 3 Duplicates: 0 Warnings: 0
Pgina 24
Existe otra sintaxis alternativa, que consiste en indicar el valor para cada columna:
mysql> INSERT INTO ciudad5 SET nombre='Roma', poblacion=8000000; Query OK, 1 row affected (0.05 sec)
Si intentamos insertar dos filas con el mismo valor de la clave nica se produce un error y la sentencia no se ejecuta. Pero existe una opcin que podemos usar para los casos de claves duplicadas: ON DUPLICATE KEY UPDATE. En este caso podemos indicar a MySQL qu debe hacer si se intenta insertar una fila que ya existe en la tabla. Las opciones son limitadas: no podemos insertar la nueva fila, sino nicamente modificar la que ya existe. Por ejemplo, en la tabla 'ciudad3' podemos usar el ltimo valor de poblacin en caso de repeticin:
mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES('Madrid', 7000000); Query OK, 1 rows affected (0.02 sec) mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES ('Pars', 9000000), ('Madrid', 7200000) ON DUPLICATE KEY UPDATE poblacion=VALUES(poblacion); Query OK, 3 rows affected (0.06 sec) Records: 2 Duplicates: 1 Warnings: 0
En este ejemplo, la segunda vez que intentamos insertar la fila correspondiente a 'Madrid' se usar el nuevo valor de poblacin. Si en lugar de VALUES(poblacion) usamos poblacin el nuevo valor de poblacin se ignora. Tambin podemos usar cualquier expresin:
mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES -> ('Pars', 9100000) -> ON DUPLICATE KEY UPDATE poblacion=poblacion; Query OK, 2 rows affected (0.02 sec)
Update Podemos modificar valores de las filas de una tabla usando la sentencia UPDATE. En su forma ms simple, los cambios se aplican a todas las filas, y a las columnas que especifiquemos. UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] [ORDER BY ...] [LIMIT row_count] Por ejemplo, podemos aumentar en un 10% la poblacin de todas las ciudades de la tabla ciudad3 usando esta sentencia:
mysql> UPDATE ciudad3 SET poblacion=poblacion*1.10; Query OK, 5 rows affected (0.15 sec) Rows matched: 5 Changed: 5 Warnings: 0
Podemos, del mismo modo, actualizar el valor de ms de una columna, separndolas en la seccin SET mediante comas:
Pgina 25
mysql> UPDATE ciudad5 SET clave=clave+10, poblacion=poblacion*0.97; Query OK, 4 rows affected (0.05 sec) Rows matched: 4 Changed: 4 Warnings: 0
En este ejemplo hemos incrementado el valor de la columna 'clave' en 10 y disminuido el de la columna 'poblacion' en un 3%, para todas las filas. Pero no tenemos por qu actualizar todas las filas de la tabla. Podemos limitar el nmero de filas afectadas de varias formas. La primera es mediante la clusula WHERE. Usando esta clusula podemos establecer una condicin. Slo las filas que cumplan esa condicin sern actualizadas:
mysql> UPDATE ciudad5 SET poblacion=poblacion*1.03 WHERE nombre='Roma'; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0
En este caso slo hemos aumentado la poblacin de las ciudades cuyo nombre sea 'Roma'. Las condiciones pueden ser ms complejas. Existen muchas funciones y operadores que se pueden aplicar sobre cualquier tipo de columna, y tambin podemos usar operadores booleanos como AND u OR. Veremos esto con ms detalle en otros captulos. Otra forma de limitar el nmero de filas afectadas es usar la clusula LIMIT. Esta clusula permite especificar el nmero de filas a modificar:
mysql> UPDATE ciudad5 SET clave=clave-10 LIMIT 2; Query OK, 2 rows affected (0.05 sec) Rows matched: 2 Changed: 2 Warnings: 0
En este ejemplo hemos decrementado en 10 unidades la columna clave de las dos primeras filas.Esta clusula se puede combinar con WHERE, de modo que slo las 'n' primeras filas que cumplan una determinada condicin se modifiquen. Sin embargo esto no es lo habitual, ya que, si no existen claves primarias o nicas, el orden de las filas es arbitrario, no tiene sentido seleccionarlas usando slo la clusula LIMIT. La clusula LIMIT se suele asociar a la clusula ORDER BY. Por ejemplo, si queremos modificar la fila con la fecha ms antigua de la tabla 'gente', usaremos esta sentencia:
mysql> UPDATE gente SET fecha="1985-04-12" ORDER BY fecha LIMIT 1; Query OK, 1 row affected, 1 warning (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 1
Si queremos modificar la fila con la fecha ms reciente, usaremos el orden inverso, es decir, el descendente:
mysql> UPDATE gente SET fecha="2001-12-02" ORDER BY fecha DESC LIMIT 1; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0
Cuando exista una clave primaria o nica, se usar ese orden por defecto, si no se especifica una clusula ORDER BY.
Pgina 26
Delete Para eliminar filas se usa la sentencia DELETE. La sintaxis es muy parecida a la de UPDATE: DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT row_count] La forma ms simple es no usar ninguna de las clusulas opcionales:
mysql> DELETE FROM ciudad3; Query OK, 5 rows affected (0.05 sec)
De este modo se eliminan todas las filas de la tabla. Pero es ms frecuente que slo queramos eliminar ciertas filas que cumplan determinadas condiciones. La forma ms normal de hacer esto es usar la clusula WHERE:
mysql> DELETE FROM ciudad5 WHERE clave=2; Query OK, 1 row affected (0.05 sec)
Tambin podemos usar las clusulas LIMIT y ORDER BY del mismo modo que en la sentencia UPDATE, por ejemplo, para eliminar las dos ciudades con ms poblacin:
mysql> DELETE FROM ciudad5 ORDER BY poblacion DESC LIMIT 2; Query OK, 2 rows affected (0.03 sec)
Mediante la sentencia SELECT es posible hacer una proyeccin de una tabla, seleccionando las columnas de las que queremos obtener datos. En la sintaxis que hemos mostrado, la seleccin de columnas corresponde con la parte "expresion_select". En el ejemplo anterior hemos usado '*', que quiere decir que se muestran todas las columnas.
Pgina 27
Pero podemos usar una lista de columnas, y de ese modo slo se mostrarn esas columnas:
mysql> SELECT nombre FROM gente; mysql> SELECT clave,poblacion FROM ciudad5; Empty set (0.00 sec)
Tambin podemos aplicar funciones sobre columnas de tablas, y usar esas columnas en expresiones para generar nuevas columnas:
mysql> SELECT nombre, fecha, DATEDIFF(CURRENT_DATE(),fecha)/365 FROM gente; +---------+------------+------------------------------------+ | nombre | fecha | DATEDIFF(CURRENT_DATE(),fecha)/365 | +---------+------------+------------------------------------+ | Fulano | 1985-04-12 | 19.91 | | Mengano | 1978-06-15 | 26.74 | | Tulano | 2001-12-02 | 3.26 | | Pegano | 1993-02-10 | 12.07 | +---------+------------+------------------------------------+ 4 rows in set (0.00 sec)
Aprovechemos la ocasin para mencionar que tambin es posible asignar un alias a cualquiera de las expresiones select. Esto se puede hacer usando la palabra AS, aunque esta palabra es opcional:
mysql> SELECT nombre, fecha, DATEDIFF(CURRENT_DATE(),fecha)/365 AS edad -> FROM gente; +---------+------------+-------+ | nombre | fecha | edad | +---------+------------+-------+ | Fulano | 1985-04-12 | 19.91 | | Mengano | 1978-06-15 | 26.74 | | Tulano | 2001-12-02 | 3.26 | | Pegano | 1993-02-10 | 12.07 | +---------+------------+-------+ 4 rows in set (0.00 sec)
Podemos hacer:
mysql> SELECT 2+3 "2+3"; +-----+ | 2+3 | +-----+ |5| mysql> INSERT INTO gente VALUES ('Pimplano', '1978-06-15'), -> ('Frutano', '1985-04-12'); Query OK, 2 rows affected (0.03 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SELECT fecha FROM gente; +------------+ | fecha | +------------+ | 1985-04-12 | | 1978-06-15 | | 2001-12-02 | | 1993-02-10 | | 1978-06-15 |
Pgina 28
Vemos que existen dos valores de filas repetidos, para la fecha "1985-04-12" y para "1978-06-15". La sentencia que hemos usado asume el valor por defecto (ALL) para el grupo de opciones ALL, DISTINCT y DISTINCTROW. En realidad slo existen dos opciones, ya que las dos ltimas: DISTINCT y DISTINCTROW son sinnimos. La otra alternativa es usar DISTINCT, que har que slo se muestren las filas diferentes:
mysql> SELECT DISTINCT fecha FROM gente; +------------+ | fecha | +------------+ | 1985-04-12 | | 1978-06-15 | | 2001-12-02 | | 1993-02-10 | +------------+ 4 rows in set (0.00 sec)
Otra de las operaciones del lgebra relacional era la seleccin, que consista en seleccionar filas de una relacin que cumplieran determinadas condiciones. Lo que es ms til de una base de datos es la posibilidad de hacer consultas en funcin de ciertas condiciones. Generalmente nos interesar saber qu filas se ajustan a determinados parmetros. Por supuesto, SELECT permite usar condiciones como parte de su sintaxis, es decir, para hacer selecciones. Concretamente mediante la clusula WHERE, veamos algunos ejemplos:
mysql> SELECT FROM gente WHERE nombre="Mengano";* +---------+------------+ | nombre | fecha | +---------+------------+ | Mengano | 1978-06-15 | +---------+------------+ 1 row in set (0.03 sec) mysql> SELECT * FROM gente WHERE fecha>="1986-01-01"; +--------+------------+ | nombre | fecha | +--------+------------+ | Tulano | 2001-12-02 | | Pegano | 1993-02-10 | +--------+------------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM gente WHERE fecha>="1986-01-01" AND fecha < "2000-01-01"; +--------+------------+ | nombre | fecha | +--------+------------+ | Pegano | 1993-02-10 | +--------+------------+ 1 row in set (0.00 sec)
Pgina 29
ISC
La tabla empleados contiene los siguientes campos:
numemp: nmero del empleado nombre : nombre y apellidos del empleado edad : edad del empleado oficina : nmero de la oficina donde trabaja el empleado, p.ej. Antonio Viguer trabaja en la oficina 12 de Alicante titulo : el cargo que desempea el empleado contrato : fecha en que se contrat al empleado jefe : nmero de su jefe inmediato, p.ej. El jefe de Antonio Viguer es Jos Gonzlez. Observar que Luis Antonio no tiene jefe, es el director general. cuota : cuota del empleado, sera el importe mnimo de ventas que debe alcanzar el empleado en el ao ventas : importe de ventas realizadas durante este ao
Tabla Oficina con los siguientes campos: oficina: cdigo de la oficina ciudad: ciudad donde est ubicada region : regin a la que pertenece dir : director de la oficina (su nmero de empleado) por ejemplo la oficina 12 tiene como director el empleado104 Jos Gonzlez. objetivo : objetivo de ventas que debe alcanzar la oficina ventas: ventas de la oficina
Pgina 30
ISC
nombre : nombre y apellidos del cliente repclie : n del representante asignado al cliente. Cada cliente tiene un representante asignado (el que figura en repclie) que ser el que generalmente le atienda. limitecredito : lmite de crdito del cliente
del producto idproducto : cdigo que utiliza el fabricante para codificar el producto. Observar que aparecen varias lneas con el mismo idproducto (41003), por lo que la clave principal de la tabla deber ser idfab+idproducto descripcion: nombre del producto precio: precio del producto existencias: n de unidades del producto que tenemos en almacn
Pgina 31
Tabla pedidos: codigo : n secuencial que sirve de clave principal numpedido: n de pedido. Observar que un pedido puede tener varias lneas. fechapedido : fecha del pedido clie : cliente que efectua el pedido rep : representante que tramita el pedido fab: fabricante del producto que se pide producto : idproducto del producto que se pide. cant : cantidad que se pide del producto
Pgina 32
EJERCICIOS DE CONSULTAS 1.- SELECCIONAR TODOS LOS REGISTROS DE LA TABLA PRODUCTOS Select * from productos; 2.- SELECCIONAR EL ID DEL PRODUCTO, DESCRIPCION Y PRECIO DE LOS PRODUCTOS Select idproducto, descripcin, precio from productos; 3.- SELECCIONAR EL IDFAB, IDPRODUCTO Y DESCRIPCION DE LA TABLA PRODUCTOS, INDICANDO
COMO NOMBRE DEL PRIMER CAMPO FABRICANTE
ISC
Select idfab AS fabricante, idproducto, descripcin from productos; 4.- DE CADA PRODUCTO OBTIENER SU FABRICANTE, IDPRODUCTO, SU DESCRIPCIN Y EL VALOR
DEL INVENTARIO
SELECT idfab, idproducto, descripcion, (existencias * precio) AS valoracion FROM productos; 5.- LISTAR LAS VENTAS EN CADA OFICINA CON EL FORMATO: 22 TIENE VENTAS DE 186,042.00
PTAS
oficina,
'tiene
ventas
de
',
ventas
6.- LISTAR EL NOMBRE, OFICINA Y CONTRATO DEN CADA EMPLEADO ORDENADOS POR NMERO
DE OFICINA
SELECT nombre, oficina, contrato FROM empleados ORDER BY oficina; 7.- OBTIENE UN LISTADO ALFABTICO DE LOS EMPLEADOS SELECT nombre, numemp, oficinarep FROM empleados ORDER BY nombre;
8.- OBTIENE UN LISTADO DE LOS EMPLEADOS POR ORDEN DE ANTIGUEDAD EN LA EMPRESA EMPEZANDO POR LOS MS RECIENTEMENTE INCORPORADOS
SELECT nombre, numemp, contrato FROM empleados ORDER BY contrato DESC; 9.- MUESTRA LAS VENTAS DE CADA OFICINA, ORDENADAS POR ORDEN ALFABTICO DE REGIN Y
DENTRO DE CADA REGIN POR CIUDAD
SELECT region, ciudad, ventas FROM oficinas ORDER BY region, ciudad; 10.- LISTA LOS CDIGOS DE LOS DIRECTORES DE LAS OFICINAS. EL DIRECTOR 108 APARECE EN CUATRO OFICINAS, POR LO TANTO APARECER CUATRO VECES EN EL RESULTADO DE LA CONSULTA; SELECT dir FROM oficinas ; SELECT ALL dir FROM oficinas; SELECT DISTINCT dir FROM oficinas; 11.- LISTA EL CDIGO Y NOMBRE DE LOS EMPLEADOS ORDENNDOLOS POR FECHA DE CONTRATO, SACANDO NICAMENTE LOS DOS PRIMEROS (SERN LOS DOS MS ANTIGUOS). SELECT TOP 2 numemp, nombre FROM empleado ORDER BY contrato; 12.- EN ESTE CASO TIENE QUE SACAR LOS TRES PRIMEROS, PERO SI NOS FIJAMOS EN LAS FECHAS DE CONTRATO TENEMOS 20/10/86, 10/12/86, 01/03/87, 01/03/87, LA TERCERA FECHA ES IGUAL QUE LA CUARTA, EN ESTE CASO SACAR ESTAS CUATRO FILAS EN VEZ DE TRES, Y SACARA
TODAS LAS FILAS QUE TUVIESEN EL MISMO VALOR QUE LA TERCERA FECHA DE CONTRATO
Pgina 33
SELECT TOP 3 numemp, nombre FROM empleado ORDER BY contrato; 13.- LISTA EL NOMBRE DE LOS EMPLEADOS ORDENNDOLOS POR FECHA DE CONTRATO, SACANDO NICAMENTE UN 20% DEL TOTAL DE EMPLEADOS. COMO TENEMOS 10 EMPLEADOS, SACAR LOS DOS PRIMEROS, SI SE TUVIERAN 100 EMPLEADOS SACARA LOS 20 PRIMEROS. SELECT TOP 20 PERCENT nombre FROM empleado ORDER BY contrato; 14.- LISTA EL NOMBRE DE LOS EMPLEADOS DE LA OFICINA 12 SELECT nombre FROM empleados WHERE oficina = 12 15.- LISTA EL NOMBRE DE LOS EMPLEADOS DE LA OFICINA 12 QUE TENGAN MS DE 30 AOS. (OFICINA IGUAL A 12 Y EDAD MAYOR QUE 30) SELECT nombre FROM empleados WHERE oficina = 12 AND edad > 3 16.- LISTA LOS EMPLEADOS CONTRATADOS ANTES DEL AO 88 (CUYA FECHA DE CONTRATO SEA ANTERIOR AL 1 DE ENERO DE 1988). NOTA: LAS FECHAS ENTRE ALMOHADILLAS # # DEBEN ESTAR CON EL FORMATO MES,DIA,AO AUNQUE TENGAMOS DEFINIDO OTRO FORMATO PARA NUESTRAS FECHAS. SELECT numemp, nombre FROM empleados WHERE contrato < #01/01/1988#
17.- LISTA LAS OFICINAS CUYAS VENTAS ESTN POR DEBAJO DEL 80% DE SU OBJETIVO. HAY QUE UTILIZAR SIEMPRE EL PUNTO DECIMAL AUNQUE TENGAMOS DEFINIDA LA COMA COMO SEPARADOR DE DECIMALES.
ISC
SELECT oficina FROM oficinas WHERE ventas < objetivo * 0.8; 18.-LISTA LOS EMPLEADOS CUYAS VENTAS ESTN COMPRENDIDAS ENTRE 100.000 Y 500.00 SELECT numemp, nombre FROM empleados WHERE ventas BETWEEN 100000 AND 500000
19.-OBTENEMOS LO MISMO QUE EN EL EJEMPLO ANTERIOR. LOS PARNTESIS SON OPCIONALES SELECT numemp, nombre FROM empleados WHERE (ventas >= 100000) AND (ventas <= 500000) 20.-LISTA LOS EMPLEADOS DE LAS OFICINAS 12, 14 Y 16 SELECT numemp, nombre, oficina FROM empleados WHERE oficina IN (12,14,16) 21.-OBTENEMOS LO MISMO QUE EN EL EJEMPLO ANTERIOR. LOS PARNTESIS SON OPCIONALES SELECT numemp, nombre FROM empleados WHERE (oficina = 12) OR (oficina = 14) OR (oficina = 16) 22.-LISTA LAS OFICINAS QUE NO TIENEN DIRECTOR SELECT oficina, ciudad FROM oficinas WHERE dir IS NULL; 23.-LISTA LOS EMPLEADOS ASIGNADOS A ALGUNA OFICINA (LOS QUE TIENEN UN VALOR EN LA COLUMNA OFICINA). SELECT numemp, nombre FROM empleados WHERE oficina IS NOT NULL; 24.-LISTA LOS EMPLEADOS CUYO NOMBRE EMPIECE POR LUIS (LUIS SEGUIDO DE CERO O MS CARACTERES). SELECT numemp, nombre FROM empleados WHERE nombre LIKE 'Luis*';
Pgina 34
25.-LISTA LOS EMPLEADOS CUYO NOMBRE CONTIENE LUIS, EN ESTE CASO TAMBIN SALDRA LOS EMPLEADOS JOS LUIS (CERO O MS CARACTERES SEGUIDOS DE LUIS Y SEGUIDO DE CERO O MS CARACTERES). SELECT numemp, nombre FROM empleados WHERE nombre LIKE '*Luis*'; 26.-LISTA LOS EMPLEADOS CUYO NOMBRE CONTENGA UNA A COMO TERCERA LETRA (DOS CARACTERES, LA LETRA A, Y CERO O MS CARACTERES SELECT numemp, nombre FROM empleados WHERE nombre LIKE '??a*';
Pgina 35
La COMPOSICIN DE TABLAS consiste en concatenar filas de una tabla con filas de otra. En este caso obtenemos una tabla con las columnas de la primera tabla unidas a las columnas de la segunda tabla, y las filas de la tabla resultante son concatenaciones de filas de la primera tabla con filas de la segunda tabla. El ejemplo anterior quedara de la siguiente forma con la composicin:
ISC
A diferencia de la unin la composicin permite obtener una fila con datos de las dos tablas, esto es muy til cuando queremos visualizar filas cuyos datos se encuentran en dos tablas. Por ejemplo queremos listar los pedidos con el nombre del representante que ha hecho el pedido, pues los datos del pedido los tenemos en la tabla de pedidos pero el nombre del representante est en la tabla de empleados y adems queremos que aparezcan en la misma lnea; en este caso necesitamos componer las dos tablas (Nota: en el ejemplo expuesto a continuacin, hemos seleccionado las filas que nos interesan).
Existen distintos tipos de composicin, aprenderemos a utilizarlos todos y a elegir el tipo ms apropiado a cada caso. Los tipos de composicin de tablas son: El producto cartesiano El INNER JOIN El LEFT / RIGHT JOIN 3.3.1 Subconsultas. Una subconsulta es una consulta dentro de otra. El SGBD usa los resultados de la subconsulta para determinar los resultados de la consulta de alto nivel que
Pgina 36
contiene a la subconsulta. En las formas ms simples de una subconsulta, esta aparece dentro de una clausula WHERE o HAVING de otra instruccin SQL. Las subconsultas proporcionan una forma natural y eficiente de manejar las solicitudes de consultas que se expresan en trminos de los resultados de otras.
ISC
En la BD de ejemplo, se podra solicitar un listado de las oficinas en las que el objetivo de ventas exceda la suma de las cuotas de cada representante. La solicitud pide una lista de oficinas de la tabla OFICINAS donde el valor de la columna OBJETIVO cumple alguna condicin. Parece razonable que la instruccin SELECT que expresa la consulta pueda ser como:
Select ciudad from oficinas where objetivo ???
El valor ??? se debe rellenar y debe ser igual a la suma de las cuotas de los representantes asignados a la oficina en cuestin. Cmo puede especificarse ese valor en la consulta? (suponga que el numero de oficina es 21) entonces la consulta para la suma de las cuotas de una oficina quedara de la siguiente manera.
Select sum(cuota) from representantes where oficina_rep=21
Pero sera poco eficaz tener que escribir esta consulta, escribir los resultados y escribir en la consulta anterior la cantidad correcta. Cmo se pueden poner los resultados de esta consulta en la consulta anterior en lugar de los signos de interrogacin? As:
Select ciudad from oficinas where objetivo > (Select sum(cuota) from repventas where oficinarep=oficina)
Para cada oficina, la consulta interna (la subconsulta) calcula la suma de las cuotas de los representantes que trabajan en esa oficina. La consulta externa (la consulta principal) compara el objetivo de la oficina con el total calculado y decide si aade la oficina a los resultados de la consulta principal. Al trabajar juntas, la consulta principal y la subconsulta expresan la solicitud original y recuperan los datos solicitados de la base de datos. CONCEPTO DE SUBCONSULTA La subconsulta se encierra entre parntesis; sin embargo tiene la forma familiar de una instruccin SELECT, con una clausula FROM y clausulas opcionales WHERE, GROUP BY y HAVING . EJEMPLOS DE COMPARACIN EN SUBCONSULTAS
1.- LISTAR LOS REPRESENTANTES CUYAS CUOTAS SON IGUALES O SUPERIORES AL OBJETIVO DE LA OFICINA DE VENTAS DE ALICANTE
Select nombre from repventas where cuota >= (select objetivo from oficinas where ciudad= alicante and oficinarep=oficina);
Pgina 37
3.- LISTAR TODOS LOS PRODUCTOS DEL FABRICANTE ACI PARA LOS QUE SU STOCK EST POR ENCIMA DEL STOCK DEL PRODUCTO ACI-41004
Select descripcin, stock from productos where id_fab = ACI and stock > (select stock from productos where id_fab=ACI and id_producto= 41004)
Pertenencias a conjuntos (IN) El test de pertenencia a conjuntos (IN) en subconsultas es una forma modificada del test de pertenencia a conjuntos simples. Compara un nico valor de datos con una columna de valores de datos producidos por una subconsulta y devuelve un resultado TRUE si el valor de los datos coincide con uno de los valores de la columna. Este test se usa cuando es necesario comparar un valor de la fila que se est comprobando con un conjunto de valores producido por una subconsulta.
EJEMPLO:
ISC
4.- LISTAR TODOS LOS REPRESENTANTES QUE TRABAJAN EN OFICINAS QUE ESTN POR ENCIMA DE
SUS OBJETIVOS Select nombre from representantes where oficina_rep in (select oficina from oficinas where ventas > objetivo);
La subconsulta produce un conjunto de nmeros de oficina donde las ventas son superiores a sus objetivos. La consulta principal comprueba a continuacin cada fila de la tabla representantes para determinar si un representante en concreto trabaja en una oficina con uno de estos nmeros .
ANA
Select nombre from representantes where oficina_rep not in (select oficina from oficinas where jefe = 108);
Un JOIN de dos tablas es una combinacin entre las mismas basada en la coincidencia exacta(u otro tipo de comparacin) de dos columnas, una de cada tabla. El JOIN forma parejas de filas haciendo coincidir los contenidos de las columnas relacionadas. Se denomina composiciones internas porque en la salida no aparece ninguna tupla que no est presente en el producto cartesiano, es decir, la composicin se hace en el interior del producto cartesiano de las tablas. Para consultar la sintaxis de las composiciones ver JOIN. Las composiciones internas usan estas sintaxis:
referencia_tabla, referencia_tabla referencia_tabla [INNER | CROSS] [condicin] JOIN referencia_tabla
La coma y JOIN son equivalentes, y las palabras INNER y CROSS son opcionales. La condicin en la clusula ON puede ser cualquier expresin vlida para una clusula WHERE, de hecho, en la mayora de los casos, son equivalentes. La clusula USING nos permite usar una lista de atributos que deben ser iguales en las dos tablas a componer.
Pgina 38
EJEMPLO:
SELECT * FROM pedidos INNER JOIN clientes ON pedidos.clie = clientes.numclie; SELECT * FROM pedidos INNER JOIN productos ON (pedidos.fab = productos.idfab) AND (pedidos.producto = productos.idproducto);
El LEFT JOIN y RIGHT JOIN son otro tipo de composicin de tablas, tambin denominada composicin externa. Son una extensin del INNER JOIN. Las sintaxis para composiciones externas son: referencia_tabla LEFT [OUTER] JOIN referencia_tabla [join_condition] referencia_tabla NATURAL LEFT [OUTER] JOIN referencia_tabla referencia_tabla RIGHT [OUTER] JOIN referencia_tabla [condicin] referencia_tabla NATURAL RIGHT [OUTER] JOIN referencia_tabla La condicin puede ser: ON expresin_condicional | USING (lista_columnas) La palabra OUTER es opcional. Existen dos grupos de composiciones externas: izquierda y derecha, dependiendo de cul de las tablas se lea en primer lugar.
Con una composicin interna slo se obtienen las filas que tienen al menos una fila de la otra tabla que cumpla la condicin, veamos un ejemplo: Queremos combinar los empleados con las oficinas para saber la ciudad de la oficina donde trabaja cada empleado, si utilizamos un producto cartesiano tenemos:
SELECT empleados.*,ciudad FROM empleados, oficina WHERE empleados.oficina = oficinas.oficina;
Observar que hemos cualificado el nombre de columna oficina ya que ese nombre aparece en las dos tablas de la FROM.
Con esta sentencia los empleados que no tienen una oficina asignada (un valor nulo en el campo oficina de la tabla empleados) no aparecen en el resultado ya que la condicin empleados.oficina = oficinas.oficina ser siempre nula para esos empleados. Si utilizamos el INNER JOIN:
SELECT empleados.*, ciudad FROM empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina
Nos pasa lo mismo, el empleado 110 tiene un valor nulo en el campo oficina y no aparecer en el resultado. Pues en los casos en que no se quiera que aparezcan las filas que no tienen una fila coincidente en la otra tabla, utilizaremos el LEFT o RIGHT JOIN.
EJEMPLO:
SELECT * FROM empleados LEFT JOIN oficinas ON empleados.oficina = oficinas.oficina
Pgina 39
Con el ejemplo anterior obtenemos una lista de los empleados con los datos de su oficina, y el empleado 110 que no tiene oficina aparece con sus datos normales y los datos de su oficina a nulos.
EJERCICIO No.2
Las condiciones para que se pueda crear una unin son las mismas que vimos al estudiar el lgebra relacional: las relaciones a unir deben tener el mismo nmero de atributos, y adems deben ser de dominios compatibles.
mysql> CREATE TABLE stock1 ( -> id INT NOT NULL, -> nombre VARCHAR(30), -> cantidad INT, -> PRIMARY KEY (id)); Query OK, 0 rows affected (0.08 sec) mysql> CREATE TABLE stock2 ( -> id INT NOT NULL, -> nombre VARCHAR(40), -> cantidad SMALLINT, -> PRIMARY KEY (id)); Query OK, 0 rows affected (0.16 sec) mysql> CREATE TABLE stock3 ( -> id INT NOT NULL, -> nombre VARCHAR(35), -> numero MEDIUMINT, -> PRIMARY KEY (id)); Query OK, 0 rows affected (0.08 sec) mysql> INSERT INTO stock1 VALUES -> (1, "tornillo M3x12", 100), -> (2, "tornillo M3x15", 120), -> (3, "tornillo M4x25", 120), -> (4, "tornillo M5x30", 200); Query OK, 4 rows affected (0.03 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> INSERT INTO stock2 VALUES -> (10, "tuerca M4", 120), -> (11, "tuerca M3", 100), -> (12, "tuerca M5", 87); Query OK, 3 rows affected (0.05 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> INSERT INTO stock3 VALUES -> (20, "varilla 10", 23), -> (1, "tornillo M3x12", 22), -> (21, "varilla 12", 32), -> (11, "tuerca M3", 22); Query OK, 4 rows affected (0.03 sec) Records: 4 Duplicates: 0 Warnings: 0
Podemos crear una unin de las tres tablas, a pesar de que los nombres y tamaos de algunas columnas sean diferentes:
Pgina 40
mysql> SELECT * FROM stock1 UNION -> SELECT * FROM stock2 UNION -> SELECT * FROM stock3; +----+----------------+----------+ | id | nombre | cantidad | +----+----------------+----------+ | 1 | tornillo M3x12 | 100 | | 2 | tornillo M3x15 | 120 | | 3 | tornillo M4x25 | 120 | | 4 | tornillo M5x30 | 200 | | 10 | tuerca M4 | 120 | | 11 | tuerca M3 | 100 | | 12 | tuerca M5 | 87 | | 1 | tornillo M3x12 | 22 | | 11 | tuerca M3 | 22 | | 20 | varilla 10 | 23 | | 21 | varilla 12 | 32 | +----+----------------+----------+ 11 rows in set (0.00 sec)
El resultado se puede ordenar usando ORDER BY y tambin podemos seleccionar un nmero limitado de filas mediante LIMIT:
mysql> (SELECT * FROM stock1) UNION -> (SELECT * FROM stock2) UNION -> (SELECT * FROM stock3) ORDER BY id LIMIT 6; +----+----------------+----------+ | id | nombre | cantidad | +----+----------------+----------+ | 1 | tornillo M3x12 | 100 | | 1 | tornillo M3x12 | 22 | | 2 | tornillo M3x15 | 120 | | 3 | tornillo M4x25 | 120 | | 4 | tornillo M5x30 | 200 | | 10 | tuerca M4 | 120 | +----+----------------+----------+ 6 rows in set (0.00 sec)
Con ALL se muestran todas las filas, aunque estn repetidas, con DISTINCT slo se muestra una copia de cada fila:
mysql> SELECT id,nombre FROM stock1 UNION -> SELECT id,nombre FROM stock2 UNION -> SELECT id,nombre FROM stock3; +----+----------------+ | id | nombre | +----+----------------+ | 1 | tornillo M3x12 | | 2 | tornillo M3x15 | | 3 | tornillo M4x25 | | 4 | tornillo M5x30 | | 10 | tuerca M4 | 11 | tuerca M3 | | 12 | tuerca M5 | | 20 | varilla 10 | | 21 | varilla 12 | +----+----------------+ 9 rows in set (0.00 sec) mysql> SELECT id,nombre FROM stock1 UNION ALL -> SELECT id,nombre FROM stock2 UNION ALL
Pgina 41
-> SELECT id,nombre FROM stock3; +----+----------------+ | id | nombre | +----+----------------+ | 1 | tornillo M3x12 | | 2 | tornillo M3x15 | | 3 | tornillo M4x25 | | 4 | tornillo M5x30 | | 10 | tuerca M4 | | 11 | tuerca M3 | | 12 | tuerca M5 | | 1 | tornillo M3x12 | | 11 | tuerca M3 | | 20 | varilla 10 | | 21 | varilla 12 | +----+----------------+ 11 rows in set (0.00 sec)
3.4 Agregacin GROUP BY, HAVING. GROUP BY Permite combinar en un nico registro los registros con valores idnticos en la lista de campos especificada Es posible agrupar filas en la salida de una sentencia SELECT segn los distintos valores de una columna, usando la clusula GROUP BY. Esto, en principio, puede parecer redundante, ya que podamos hacer lo mismo usando la opcin DISTINCT. Sin embargo, la clusula GROUP BY es ms potente:
mysql> SELECT fecha FROM gente GROUP BY fecha; +------------+ | fecha | +------------+ | 1978-06-15 | | 1985-04-12 | | 1993-02-10 | | 2001-12-02 | +------------+ 4 rows in set (0.00 sec)
Pero la diferencia principal es que el uso de la clusula GROUP BY permite usar funciones de resumen o reunin. Por ejemplo, la funcin COUNT(), que sirve para contar las filas de cada grupo:
mysql> SELECT fecha, COUNT(*) AS cuenta FROM gente GROUP BY fecha; +------------+--------+ | fecha | cuenta | +------------+--------+ | 1978-06-15 | 2 | | 1985-04-12 | 2 | | 1993-02-10 | 1 | | 2001-12-02 | 1 | +------------+--------+ 4 rows in set (0.00 sec)
Pgina 42
HAVING Es similar al where. La clusula where determina que registros se seleccionan. De forma parecida, una vez que los registros se agrupan con la clusula group by, la clusula having determina que registros se van a mostrar. Utilice la clusula where para eliminar registros que no desea que se agrupen mediante la clusula group by. La clusula HAVING permite hacer selecciones en situaciones en las que no es posible usar WHERE. EJEMPLO:
mysql> CREATE TABLE muestras ( -> ciudad VARCHAR(40), -> fecha DATE, -> temperatura TINYINT); Query OK, 0 rows affected (0.25 sec) mysql> INSERT INTO muestras (ciudad,fecha,temperatura) VALUES -> ('Madrid', '2005-03-17', 23), -> ('Pars', '2005-03-17', 16), -> ('Berln', '2005-03-17', 15), -> ('Madrid', '2005-03-18', 25), -> ('Madrid', '2005-03-19', 24), -> ('Berln', '2005-03-19', 18); Query OK, 6 rows affected (0.03 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> SELECT ciudad, MAX(temperatura) FROM muestras -> GROUP BY ciudad HAVING MAX(temperatura)>16; +--------+------------------+ | ciudad | MAX(temperatura) | +--------+------------------+ | Berln | 18 | | Madrid | 25 | +--------+------------------+ 2 rows in set (0.00 sec)
ISC
o bien
SELECT COUNT(*) FROM empleados ;
Pgina 43
ISC
4.- SE QUIERE SABER LAS OFICINAS CON UN PROMEDIO DE VENTAS DE SUS EMPLEADOS MAYOR QUE 500.000 PTAS.
SELECT oficina FROM empleados GROUP BY oficina HAVING AVG(ventas) > 500000;
NOTA: Para obtener lo que se pide hay que calcular el promedio de ventas de los empleados de cada oficina, por lo que hay que utilizar la tabla empleados. Se tiene que agrupar los empleados por oficina y calcular el promedio para cada oficina, por ltimo se seleccionar el resultado las filas que tengan un promedio superior a 500.000 ptas.
5.- LISTADO
EL NMERO Y NOMBRE DE LOS EMPLEADOS CUYA FECHA DE CONTRATO SEA IGUAL A LA PRIMERA FECHA DE TODOS LOS PEDIDOS DE LA EMPRESA
SELECT numemp, nombre FROM empleados WHERE contrato = (SELECT MIN(fechapedido) FROM pedidos);
6.- LISTA LAS OFICINAS CUYO OBJETIVO SEA SUPERIOR A LA SUMA DE LAS VENTAS DE SUS EMPLEADOS. EN ESTE CASO LA SUBCONSULTA DEVUELVE UNA NICA COLUMNA Y UNA NICA FILA (ES UN CONSULTA DE RESUMEN SIN GROUP BY)
SELECT oficina, ciudad FROM oficinas WHERE objetivo > (SELECT SUM(ventas) FROM empleados WHERE empleados.oficina = oficinas.oficina);
7.- OBTENER LA LISTA DE LOS NMEROS DE OFICINA DEL ESTE Y LA CONSULTA PRINCIPAL OBTIENE LOS EMPLEADOS CUYO NMERO DE OFICINA SEA UNO DE LOS NMEROS DE OFICINA DEL ESTE. POR LO TANTO LISTA LOS EMPLEADOS DE LAS OFICINAS DEL ESTE.
SELECT numemp, nombre, oficina FROM empleados WHERE oficina IN (SELECT oficina FROM oficinas WHERE region = 'este');
Pgina 44