SQL PARA
PRINCIPIANTES
INSTRUCCIONES DEL LENGUAJE SQL PARA EL
MANEJO DE BASES DE DATOS |
 |
Sentencias SQL en Visual Basic
I n
d i c
e :
1. Introducción
2.
¿Qué es SQL?
3. La sentencia select y la cláusula from
4.
Programación SQL desde el control data
5. Eliminación Dinámica De Registros
6.
Contar Registros
7. Grupos De Registros
8.
Combinación De Datos
1. Introducción
Visual Basic es un
lenguaje de programación de propósito general, con una gran potencia en toda su
estructura. Su implementación en el sistema operativo Windows y sus herramientas
visuales, han hecho de este lenguaje un líder indiscutible en lo que a
desarrollo de aplicaciones se refiere. Con la versión 3.0. se implementó la
gestión de bases de datos a muy alto nivel, pudiendo gestionar bases de datos de
tipo Access, Paradox, dBASE, FoxPro, etc.
Este paso de
gigante ha hecho de Visual Basic uno de los lenguajes favoritos por los
desarrolladores de aplicaciones de bases de datos, en especial el hecho de que
Visual Basic implemente el lenguaje SQL, uno de los más potentes y sencillos
lenguajes de bases de datos.
ARRIBA
2. ¿Qué es sql?
SQL
(Structured Query Language ó Lenguaje Estructurado de Consulta), es un lenguaje
bastante sencillo, principalmente orientado a bases de datos y, sobre todo, al
manejo de consultas. Visual Basic incorpora esta extensión junto a nuestras
bases de datos, obteniendo potentes resultados. De hecho, las consultas que se
realizan en Access, están desarrolladas o basadas en este lenguaje, por lo que
su implementación en Visual Basic no es complicada.
El objetivo
principal de SQL es la realización de consultas y cálculos con los datos de una
o varias tablas.
Consejos Para
Escribir Mandatos En SQL
He aquí una serie de consejos (a veces normas), que hay que tener en cuenta a la
hora de escribir mandatos SQL en nuestras aplicaciones en Visual Basic:
1. Un mandato en SQL se expresa en una cadena de caracteres o String.
2. Dicho mandato se puede escribir en la propiedad RecordSource de un control
Data (más adelante, podremos prescindir del control Data para realizar nuestras
consultas), con el fin de crear una consulta en la interfaz.
3. Los nombres de los campos especificados (y de las tablas), que contengan más
de una palabra, han de encerrarse entre corchetes ([nombre]). Como norma
general, se suelen escribir siempre entre corchetes.
4. Para especificar un determinado campo de una determinada tabla, se ha de
escribir primero el nombre de la tabla, un punto y, a continuación, el nombre
del campo
(nombre_tabla.nombre_campo).
5. Al especificar una expresión de búsqueda, si ésta se refiere a una expresión
de caracteres, éstos han de encerrarse entre comillas simples
('expresión_a_buscar').
6. Para especificar una fecha en una búsqueda, ésta debe encerrarse entre signos
numeral
(#fecha#) en Access, Dbase X, etc., y entre comillas simples ('fecha') para
bases Sql Server, Informix, etc.
7. Si se utiliza la propiedad RecordSource del control Data, para crear nuestras
consultas en SQL, tras introducir el mandato SQL (siempre como una expresión de
cadena) es necesario refrescar el control Data (control_data.Refresh).
Mandato Sql
Estándar
El lenguaje SQL está compuesto por una serie de sentencias y de cláusulas muy
reducidas en número, pero muy potentes en efectividad. De entre todas las
palabras, existen cuatro que son las más utilizadas, estando compuestas por una
sentencia y por tres cláusulas:
SELECT lista_campos FROM lista_tablas [WHERE criterios [ORDER BY lista_campos]]
ARRIBA
3. La sentencia select y la
cláusula from
La sentencia
SELECT "selecciona" los campos que conformarán la consulta, es decir, que
establece los campos que se visualizarán o compondrán la consulta. El parámetro
'lista_campo' está compuesto por uno o más nombres de campos, separados por
comas, pudiéndose especificar también el nombre de la tabla a la cual
pertenecen, seguido de un punto y del nombre del campo correspondiente. Si el
nombre del campo o de la tabla está compuesto de más de una palabra, este nombre
ha de escribirse entre corchetes ([nombre]). Si se desea seleccionar todos los
campos de una tabla, se puede utilizar el asterisco (*) para indicarlo.
Una sentencia
SELECT no puede escribirse sin la cláusula FROM. Una cláusula es una extensión
de un mandato que complementa a una sentencia o instrucción, pudiendo
complementar también a otras sentencias. Es, por decirlo así, un accesorio
imprescindible en una determinada máquina, que puede también acoplarse a otras
máquinas. En este caso, la cláusula FROM permite indicar en qué tablas o en qué
consultas (queries) se encuentran los campos especificados en la sentencias
SELECT. Estas tablas o consultas se separan por medio de comas (,), y, si sus
nombres están compuestos por más de una palabra, éstos se escriben entre
corchetes ([nombre]).
He aquí
algunos ejemplos de mandatos SQL en la estructura SELECT...FROM...:
SELECT nombre,apellidos FROM clientes;
Selecciona los campos 'nombre' y 'apellidos' de la tabla 'clientes'.
SELECT clientes.nombre, producto FROM clientes, productos;
Selecciona el campo 'nombre' de la tabla 'clientes', y el campo 'producto' de la
tabla productos.
Hay que tener en cuenta que si dos tablas poseen el mismo nombre de campo (un
'nombre' de cliente y un 'nombre' de producto, hay que especificar también la
tabla a la cual pertenece dicho campo, ya, que de lo contrario, seleccionaría
ambos nombres).
SELECT pedidos.* FROM pedidos;
Selecciona todos los campos de la tabla 'pedidos'.
SELECT * FROM pedidos;
Selecciona todos los campos de la tabla 'pedidos'.
SELECT nombre, apellidos, telefono FROM clientes;
Selecciona los campos 'nombre', 'apellidos' y 'telefono' de la tabla 'clientes'.
De esta manera obtenemos una agenda telefónica de nuestros clientes.
SELECT [codigo postal] FROM [tabla morosos];
Selecciona el campo 'codigo postal' de la tabla 'tabla morosos'.
Claúsula
Where
La claúsula
WHERE es opcional, y permite seleccionar qué registros aparecerán en la consulta
(si no se especifica aparecerán todos los registros). Para indicar este conjunto
de registros se hace uso de criterios o condiciones, que no es más que una
comparación del contenido de un campo con un determinado valor (este valor puede
ser constante (valor predeterminado), el contenido de un campo, una variable, un
control, etc.).
He aquí
algunos ejemplos que ilustran el uso de esta cláusula:
SELECT * FROM clientes WHERE nombre='ALFREDO';
Selecciona todos los campos de la tabla 'clientes', pero los registros de todos
aquellos clientes que se llamen 'ALFREDO'.
SELECT * FROM abonados WHERE provincia='MADRID' OR provincia='VALENCIA OR
provincia='BARCELONA';
Selecciona todos los campos de la tabla 'abonados', pero los registros de todos
los abonados de las provincias de 'MADRID', 'VALENCIA' o 'BARCELONA'.
SELECT nombre, apellidos FROM abonados WHERE edad>=18;
Selecciona los campos 'nombre' y 'apellidos' de la tabla abonados, escogiendo a
aquellos abonados que sean mayor de edad (a partir de 18 años).
SELECT * FROM abonados WHERE edad>=18 AND edad<=45;
Selecciona todos los abonados con edades comprendidas entre los 18 y los 45
años.
SELECT * FROM abonados WHERE edad BETWEEN 18 AND 45;
Selecciona todos los abonados con edades comprendidas entre los 18 y los 45
años.
SELECT * FROM diario WHERE fecha=#7/1/97#;
Selecciona los apuntes de 'diario' realizados el 1 de Julio de 1.997 (la fecha
ha de indicarse en inglés (mes/día/año)).
SELECT * FROM diario WHERE fecha<=#12/31/96#;
Selecciona los apuntes de 'diario' realizados antes del 1 de Enero de 1.997.
SELECT * FROM diario WHERE fecha BETWEEN #7/1/97# AND #7/31/97#;
Selecciona los apuntes de 'diario' realizados en Julio de 1.997.
SELECT * FROM clientes WHERE nombre LIKE 'AL*';
Selecciona los clientes cuyo nombre comience con los caracteres 'AL'.
SELECT * FROM clientes WHERE apellidos LIKE '*EZ';
Selecciona los clientes cuyos apellidos terminen con los caracteres 'EZ'.
SELECT * FROM clientes WHERE apellidos LIKE '*ZAMO*'
Selecciona los clientes cuyos apellidos contengan, en cualquier posición, los
caracteres 'ZAMO'.
SELECT * FROM clientes WHERE provincia IN ('MADRID', 'BARCELONA',
'VALENCIA','TOLEDO', 'AVILA');
Selecciona todos los clientes de las provincias de MADRID, BARCELONA, VALENCIA,
TOLEDO o AVILA.
Cláusula
Order By
La cláusula
ORDER BY suele escribirse al final de un mandato en SQL. Dicha cláusula
establece un criterio de ordenación de los datos de la consulta, por los campos
que se especifican en dicha cláusula. La potencia de ordenación de dicha
cláusula radica en la especificación de los campos por los que se ordena, ya que
el programador puede indicar cuál será el primer criterio de ordenación, el
segundo, etc., así como el tipo de ordenación por ese criterio: ascendiente o
descendiente.
(...) ORDER BY campo1 [ASC/DESC][,campo2 [ASC/DESC]...]
La palabra reservada ASC es opcional e indica que el orden del campo será de
tipo ascendiente (0-9 A-Z), mientras que, si se especifica la palabra reservada
DESC, se indica que el orden del campo es descendiente (9-0 Z-A). Si no se
especifica ninguna de estas palabras reservadas, la cláusula ORDER BY toma, por
defecto, el tipo ascendiente [ASC].
He aquí
algunos ejemplos:
SELECT nombre, apellidos, telefono FROM clientes ORDER BY apellidos, nombre;
Crea una agenda telefónica de 'clientes' ordenada por 'apellidos' y 'nombre'.
SELECT * FROM pedidos ORDER BY fecha DESC;
Relación de 'pedidos' ordenados desde el más antiguo hasta el más moderno.
SELECT * FROM abonados ORDER BY apellidos, nombre, fecha_nacimiento DESC;
Relación de 'abonados' por 'apellidos' y 'nombre' ascendiente, y por
'fecha_nacimiento' en orden descendiente (del más viejo al más joven).
ARRIBA
4. Programación SQL desde el
control data
Gracias al
control 'Data' podremos hacer nuestros primeros pinitos en SQL. Lo primero que
hay que tener en cuenta es que la consulta realizada en SQL posea los mismos
campos que la interfaz diseñada, y que los controles encargados de mostrar o
modificar la base de datos, estén perfectamente vinculados al control Data. Por
ejemplo: realizamos una ficha de 'clientes', por lo que diseñamos una interfaz
con diversas Text Box vinculadas a un control Data que contendrá los datos.
Estas Text Box se vinculan gracias a las propiedades 'DataSource' y 'DataField'.
La propiedad 'DataSource' corresponde a la fuente de los datos, en este caso, el
nombre del control 'Data'. En la propiedad 'DataField' se especifica el nombre
del campo a tratar por cada Text Box ('nombre', 'direccion', 'nif', 'telefono',
etc.). Por otro lado, en la propiedad 'DatabaseName' del control 'Data', se ha
de especificar la ruta completa de la base de datos (fichero .MDB), y la
propiedad 'RecordSource' se reservará para indicar, en una cadena o String, el
mandato en SQL correspondiente cuando sea necesario.
Siguiendo con
este ejemplo, esta ficha se reservará para consultas determinadas, y la Form
será mostrada desde una Form anterior, desde la que se establece las condiciones
de la consulta ('que sean de Madrid', 'que hayan nacido antes de 1960', 'que
habiten en Peñaranda de Bracamonte', etc.). Se podría crear una variable de tipo
String en un módulo, e insertar el mandato en SQL correspondiente antes de
llamar a la ficha. Al llamar a la ficha, la Form correspondiente tendrá un
evento Load, donde se insertará un código parecido a éste:
control_data.RecordSource = variable_SQL
control_data.Refresh
Obviamente,
dependiendo del caso, la programación se hará diferente. Pero la norma común es
crear una interfaz en concreto, con unos campos concretos y, cuando sea
necesario, establecer como valor de la propiedad 'RecordSource' el mandato en
SQL, y refrescar el control Data correspondiente. De esta manera, el control
Data contendrá el resultado de la consulta.
ARRIBA
5. Eliminación Dinámica De
Registros
¿Quién no ha
sentido la necesidad de eliminar de un golpe un grupo de registros en común, en
lugar de hacerlo uno por uno?. Esta operación puede ser mucho más habitual de lo
que parece en un principio y, por ello, el lenguaje SQL nos permitirá eliminar
registros que cumplan las condiciones o criterios que nosotros le indiquemos a
través de la sentencia DELETE, cuya sintaxis es la siguiente:
DELETE FROM
tablas WHERE criterios
Donde el parámetro 'tablas' indica el nombre de las tablas de las cuales se
desea eliminar los registros, y, el parámetro 'criterios', representa las
comparaciones o criterios que deben cumplir los registros a eliminar, respetando
a aquellos registros que no los cumplan. Si - por ejemplo - quisiéramos eliminar
todos los pedidos realizados por el cliente cuyo código sea 4 en el día de hoy,
utilizaríamos la siguiente sentencia:
DELETE FROM pedidos WHERE [codigo cliente]=4 AND fecha=Now();
Aritmética
Con Sql
¿Quién no ha echado en falta el saber el total de ingresos o de gastos de esta
fecha a esta otra?.
¿Quién no ha deseado saber la media de ventas de los comerciales en este mes?.
¡Tranquilos!: el lenguaje SQL nos permitirá resolver estas y otras cuestiones de
forma muy sencilla, ya que posee una serie de funciones de carácter aritmético:
Sumas O
Totales
Para sumar las cantidades numéticas contenidas en un determinado campo, hemos de
utilizar la función SUM, cuya sintaxis es la siguiente:
SUM(expresión)
Donde 'expresión' puede representar un campo o una operación con algún campo.
La función SUM retorna el resultado de la suma de la expresión indicada en todos
los registros que son afectados por la consulta. Veamos algunos ejemplos:
SELECT SUM(unidades) FROM pedidos;
Retorna el total de unidades pedidas (la suma de todos los valores almacenados
en el campo 'unidades' de la tabla 'pedidos'). Este resultado se toma como un
nuevo campo en el RecordSet.
SELECT SUM(ingresos-gastos) AS saldo FROM diario;
Retorna el saldo final de una tabla llamada 'diario'. Este resultado se toma
como un nuevo campo en el RecordSet y se le llama 'saldo'.
SELECT SUM(unidades) AS total FROM pedidos WHERE fecha=Now();
Retorna el total de unidades pedidas hoy. Este resultado se toma como un nuevo
campo en el RecordSet y se le llama 'total'.
Promedios O
Medias Aritméticas
Para averiguar el promedio de unas cantidades utilizaremos la función AVG, cuya
sintaxis es la siguiente:
AVG(expresión)
La función AVG retorna el promedio o media aritmética de la expresión
especificada, en todos los registros afectados por la consulta. Esto es lo mismo
que realizar una suma (SUM) y, después, dividir el resultado entre el número de
registros implicados.
He aquí
algunos ejemplos:
SELECT AVG(unidades) FROM PEDIDOS;
Retorna el promedio de unidades pedidas (la media de todos los valores
almacenados en el campo 'unidades' de la tabla 'pedidos'). Este resultado se
toma como un nuevo campo en el RecordSet.
SELECT AVG(ingresos-gastos) AS saldo_medio FROM diario;
Retorna el saldo medio de una tabla llamada 'diario'. Este resultado se toma
como un nuevo campo en el RecordSet y se le llama 'saldo_medio'.
SELECT AVG(unidades) AS media FROM pedidos WHERE fecha=Now();
Retorna el promedio de unidades pedidas hoy. Este resultado se toma como un
nuevo campo en el RecordSet y se le llama
'media'.
Valores
Mínimos Y Máximos
También es posible conocer el valor mínimo o máximo de un campo, mediante las
funciones MIN y MAX, cuyas sintaxis son las siguientes:
MIN(expresión)
MAX(expresión)
He aquí algunos ejemplos:
SELECT MIN(unidades) AS minimo FROM pedidos;
Retorna el pedido más pequeño y lo refleja en el campo 'minimo'.
SELECT MAX(unidades) AS maximo FROM pedidos WHERE fecha=Now();
Retorna el pedido más grande de hoy y lo refleja en el campo 'maximo'.
SELECT MAX(gastos) AS maximo FROM diario;
Retorna el gasto más costoso reflejado en el diario contable, y lo representa en
el campo 'maximo'.
ARRIBA
6. Contar Registros
Otra
operación muy común es realizar un recuento de registros. Aunque a primera vista
pueda parecer poco práctico, la realidad es bien distinta. ¿Q quién no le
gustaría conocer cuántos pedidos se han realizado hoy?. ¿O comprobar cuántos
pagos se han realizado por una determinada cantidad?. ¿O saber cuántos clientes
cumplen hoy años, se jubilan, son menores o mayores de edad, tienen alguna
deuda, viven en esta ciudad o en tal otra, tienen teléfono móvil, están casados
o solteros, etc.?. Para conocer cuántos registros hay utilizaremos la función
COUNT, cuya sintaxis es la siguiente:
COUNT(expresión)
La función COUNT retorna el número de registros indicados en la expresión.
He aquí
algunos ejemplos:
SELECT COUNT(*) AS num_pedidos FROM pedidos WHERE fecha=Now();
Retorna el número de pedidos realizados hoy. Este resultado se toma como un
nuevo campo en el RecordSet y se le llama 'num_pedidos'.
SELECT COUNT(*) AS casados FROM clientes WHERE casado=True;
Retorna el número de clientes casados. Este resultado se toma como un nuevo
campo y se le llama 'casados'.
SELECT COUNT(*) AS num_pagos FROM diario WHERE gastos=25594;
Retorna el número de pagos por un importe equivalente a 25594. Este resultado se
toma como un nuevo campo en el RecordSet, y se le llama 'num_pagos'.
SELECT SUM(unidades) AS total, AVG(unidades) AS media, COUNT(*) AS registros,
MAX(unidades) AS maximo, MIN(unidades) AS minimo FROM pedidos WHERE fecha
BETWEEN #1/1/97# AND #6/30/97#;
Retorna el total, la media, el máximo y el mínimo de unidades pedidas, y el
número de pedidos realizados, durante el primer semestre de 1.997.
Omisión De
Registros Duplicados
En una consulta podría ser útil omitir registros que estén duplicados. Por
ejemplo, en nuestros pedidos hay duplicación, puesto que un cliente realiza
varios pedidos en el mismo día. Quizá necesitemos una historia para conocer los
días y los clientes que realizaron algún pedido, pero no necesitaremos toda la
lista, si no que nos diga, únicamente, mediante una línea, qué cliente realizó
algún pedido y en qué día. Para ello, utilizaremos el predicado DISTINCT, cuya
sintaxis es la siguiente:
SELECT
DISTINCT lista_campos ...
El predicado DISTINCT omite aquellos registros duplicados en los campos
especificados. En el problema expuesto, utilizaremos la siguiente sentencia:
SELECT DISTINCT [codigo cliente],fecha FROM pedidos;
Si deseamos que la consulta sea más completa y nos visualice también el nombre y
los apellidos correspondientes del cliente en cuestión (estos datos están en la
tabla 'clientes' y no en 'pedidos'), escribiríamos este mandato:
SELECT DISTINCT pedidos.fecha, pedidos.[codigo cliente], clientes.nombre,
clientes.apellidos
FROM pedidos, clientes WHERE clientes.[codigo cliente] = pedidos.[codigo
cliente];
Reemplazar
Datos
Imaginemos por un momento que el precio de los productos ha subido un 10%, y que
tenemos que actualizar nuestra tabla de productos con el nuevo importe. La
solución más primitiva sería acceder a la tabla y, el precio de cada producto
multiplicarlo por 1.1 y reemplazarlo a mano. Con diez productos, la inversión de
tiempo podría llegar al cuarto de hora, y no estaremos exentos de fallos al
tipear el importe o al realizar el cálculo en la calculadora. Si la tabla de
productos superase la cantidad de 100 productos (algo muy probable y fácil de
cumplir), la cosa ya no es una pequeña molestia y un poco de tiempo perdido.
El lenguaje
SQL nos permite solucionar este problema en cuestión de pocos segundos, ya que
posee una sentencia llamada Update, que se ocupa de los cálculos y reemplazos.
Su sintaxis es la siguiente:
UPDATE lista_tablas SET campo=nuevo_valor [,campo=nuevo_valor] [WHERE...]
Donde lista_tablas representa el nombre de las tablas donde se realizarán las
sustituciones o reemplazos. El parámetro campo indica el campo que se va a
modificar, y el parámetro nuevo_valor representa una expresión (constante, valor
directo, un cálculo, etc.) cuyo resultado o valor será el nuevo valor del campo.
En el
problema expuesto anteriormente escribiríamos la siguiente sentencia:
UPDATE productos SET pvc=pvc*1.1;
Si este incremento de precio de costo debe afectar al precio de venta al público
un 30% de beneficio, podríamos escribir la siguiente línea para ahorrar trabajo
y tiempo:
UPDATE productos SET pvc=pvc*1.1, pvp=pvp*1.3;
La sentencia UPDATE es muy versátil y potente, por lo que podemos realizar
reemplazos condicionantes, ya que permite la cláusula WHERE. De ello se deduce
que - por ejemplo -, si se desea bajar un 10% el importe del seguro a aquellos
asegurados que cumplan más de dos años de carnet de conducir, y que tengan más
de 22 años de edad, tendríamos que escribir la siguiente sentencia:
UPDATE asegurados SET importe=importe/1.1 WHERE edad>22 AND
YEAR(Now)-YEAR(expedicion)>2;
Pero ahí no queda la cosa, porque es posible utilizar varias tablas y sustituir
el valor de un campo de una de las tablas con el valor del campo de otra tabla,
o bien reemplazar el valor de unos campos de alguna tabla si el valor de los
campos de otras tablas cumple una serie de requisitos. Estos casos no son tan
frecuentes, pero en el caso de haberlos se agradecerá un buen planteamiento en
el diseño inicial de la base de datos.
ARRIBA
7. Grupos De Registros
A veces,
puede ser necesario mostrar un resumen de los datos que tenemos, especificando
el total - por ejemplo -, de los ingresos y de los gastos de cada día, en lugar
de visualizar todos los ingresos y gastos realizados al detalle. Para llevar a
cabo esta tarea hemos de tener en cuenta, en primer lugar, bajo qué campo se van
a agrupar los datos (en lo expuesto, sería el campo fecha), y, a continuación,
realizar la consulta mediante la cláusula GROUP BY, cuya sintaxis es la
siguiente:
SELECT ... FROM ... [WHERE ...] GROUP BY lista_campos
Básicamente, la cláusula GROUP BY agrupa o combina registros con idéntico valor
en los campos especificados, en un único registro. Esto significa que en un sólo
registro se mostrará la información común a muchos registros, como si dijésemos,
al terminar las cuentas: "hoy se ha ingresado tanto y se ha gastado tanto, con
lo que hay un beneficio de tanto", sin necesidad de especificar cada movimiento
(cada ingreso, cada cobro, cada pago, cada factura, cada transferencia bancaria,
etc.).
Imaginemos
que queremos hacer un resumen de nuestros pedidos, y queremos saber cuántos
pedidos y unidades han realizado cada uno de nuestros clientes. Para ello, se
escribiría una sentencia como ésta:
SELECT codigo_cliente, count(codigo_cliente) AS num_pedidos, SUM(unidades) AS
cantidad FROM pedidos GROUP BY codigo_cliente;
Para saber
cuántos pedidos se realizaron cada día, escribiríamos esta línea:
SELECT fecha, count(fecha) AS num_pedidos FROM pedidos GROUP BY fecha;
Para conocer cuántas unidades se pidieron cada día, tipearíamos esta sentencia:
SELECT fecha, SUM(unidades) AS cantidad FROM pedidos GROUP BY fecha;
En la siguiente sentencia se muestra para cada cliente aquellos días en que se
realizó un pedido, resumiéndose el número de pedidos realizados así como el
total de unidades pedidas:
SELECT fecha, codigo_cliente, COUNT(codigo_cliente) AS num_pedidos,
SUM(unidades) AS cantidad FROM pedidos GROUP BY fecha, codigo_cliente HAVING
fecha<#1/6/97#;
Como se puede apreciar, se ha especificado una condición a través de la cláusula
HAVING, que indica los criterios o condiciones a cumplir por los registros a
visualizar en un agrupamiento. En esta ocasión, la condición era de aquellos
pedidos realizados antes del seis de Enero de 1.997.
Para conocer
una estadítica de pedidos diaria, utilizaremos la siguiente sentencia:
SELECT fecha, COUNT(fecha) AS pedidos, SUM(unidades) AS subtotal, MIN(unidades)
AS minimo, MAX(unidades) AS maximo, AVG(unidades) AS promedio FROM pedidos GROUP
BY fecha;
Un resultado
de ejemplo sería el siguiente:
FECHA PEDIDOS UNIDADES MINIMO MAXIMO PROMEDIO
----- ------- -------- ------ ------ --------
2/01/97 9 1599 2 1500 177,6
3/01/97 5 113 1 100 22,6
4/01/97 3 33 3 25 11,0
6/01/97 6 90 5 50 15,0
7/01/97 1 1 1 1 1,0
ARRIBA
8. Combinación De Datos
Las consultas
realizadas hasta ahora requerían de una dosis de habilidad para conseguir crear
un conjunto de datos que tuviese información combinada de dos tablas. Pero,
podemos combinar datos de una manera mucho más sencilla y eficaz: mediante las
operaciones JOIN, las cuales permiten combinar datos de dos tablas. La operación
JOIN más común es INNER JOIN, cuya sintaxis es:
tabla1 INNER JOIN tabla2 ON tabla1.campo_común=tabla2.campo_común
Donde tabla1 y tabla2 representan el nombre de las tablas a combinar. Ambas
tablas han de tener un campo común o igual para poder realizar correctamente la
combinación de los datos. Pero veamos un ejemplo para entenderlo mejor:
SELECT * FROM pedidos INNER JOIN clientes ON pedidos.codigo_cliente
=clientes.codigo_cliente;
El resultado será un conjunto de registros con los datos de las dos tablas. Este
conjunto poseerá el nombre de todos los campos de la tabla pedidos y de todos
los campos de la tabla clientes. En cada registro aparecerán los datos
relacionados, es decir, que en un pedido aparecerán los datos del mismo y los
datos personales del cliente que realizó el pedido.
La operación INNER JOIN combina los datos de las dos tablas siempre que haya
valores coincidentes en los campos comunes o enlazados.
Existen
también otras dos formas de combinar: LEFT JOIN y RIGHT JOIN. Ambas tienen la
misma sintaxis que INNER JOIN, pero estas operaciones incluyen todos los
registros de una tabla y aquellos registros de la otra en que los campos comunes
sean iguales. En la operación LEFT JOIN, incluye todos los registros de la
primera tabla (parámetro tabla1) y aquellos registros de la segunda tabla
(parámetro tabla2) en que los campos comunes sean iguales. En la operación RIGHT
JOIN ocurre lo contrario: incluye todos los registros de la segunda tabla y
aquellos registros de la primera tabla en que los campos comunes sean iguales.
Aunque la
diferencia entre las tres operaciones parezca inexistente, en realidad sí
existe. La operación INNER JOIN realiza una combinación con todos aquellos
registros de las dos tablas en que el campo común de ambas tenga el mismo valor,
mientras que las operaciones LEFT JOIN y RIGHT JOIN realizan la combinación de
todos los registros de la tabla que combinan (ya sea la primera para LEFT JOIN o
la segunda para RIGHT JOIN), aunque en la otra tabla, en el campo común no haya
coincidencia. La prueba se ve rápidamente si se introduce un código de cliente
en el campo campo_cliente de la tabla pedidos que no exista:
SELECT * FROM pedidos INNER JOIN clientes ON pedidos.codigo_cliente
=clientes.codigo_cliente;
El registro que contiene el pedido del cliente que no existe no aparece, puesto
que no hay coincidencia. Si escribimos:
SELECT * FROM pedidos LEFT JOIN clientes ON pedidos.codigo_cliente
=clientes.codigo_cliente;
Observaremos que aparecen todos los registros de la tabla pedidos, incluido
aquel donde indicamos que el pedido fue solicitado por el cliente inexistente,
pero en los campos relacionados (campos de la tabla clientes) no habrá ningún
dato relacionado o combinado. Si ahora escribimos lo siguiente:
SELECT * FROM pedidos LEFT JOIN clientes ON pedidos.codigo_cliente
=clientes.codigo_cliente; obtendremos el mismo resultado que con la operación
INNER JOIN, puesto que se visualizan todos aquellos registros que existen en
clientes y aquellos que coincidan con el campo clave en la tabla pedidos. Como
el código inexistente no existe en la tabla clientes, este registro no aparece.
Para comprobar el efecto aún mejor, modificar el código inexistente en el
registro de la tabla pedidos por uno que sí exista. Tras ello, volver a
introducir las sentencias SQL para comprobar la diferencia.
Lo más normal
es utilizar la operación INNER JOIN para omitir aquellos registros no
coincidentes, aunque las operaciones LEFT JOIN y RIGHT JOIN nos pueden servir
para descubrir entradas erróneas en códigos.
Veamos
algunos ejemplos más:
SELECT fecha, codigo_producto, unidades, apellidos, nombre FROM pedidos INNER
JOIN clientes ON pedidos.codigo_cliente = clientes.codigo_cliente WHERE
fecha<#1/6/97#;
Combina pedidos y clientes, visualizando aquellos pedidos realizados antes del 6
de Enero de 1997 por los campos fecha, codigo_producto, unidades, apellidos y
nombre.
SELECT fecha, unidades, productos.* FROM pedidos INNER JOIN productos ON
pedidos.codigo_producto = productos.codigo_producto;
Combina pedidos y productos, visualizando los pedidos por los campos fecha y
unidades, y por todos los campos de la tabla productos.
SELECT fecha, unidades, productos.* FROM pedidos INNER JOIN productos ON
pedidos.codigo_producto = productos.codigo_producto ORDER BY fecha, producto;
El resultado
será el mismo que con el anterior ejemplo, salvo que la presentación de los
registros se realizará ordenada por la fecha y el nombre del producto
VOLVER ARRIBA
|