![]() ![]() ![]() ![]() |
|
Escriba consultas con Structure Query Lenguaje
El lenguaje de consulta estructurado (SQL) es un lenguaje de base de datos estándar utilizado por el motor de base de datos Microsoft Jet. SQL se utiliza para crear objetos QueryDef, como el argumento de origen del método OpenRecordset y como la propiedad RecordSource del control de datos. También se puede utilizar con el método Execute para crear y manipular directamente las bases de datos Jet y crear consultas SQL de paso a través para manipular bases de datos remotas cliente-servidor.
Este capítulo explica la estructura básica de SQL y la forma en que se utiliza para crear, mantener y modificar bases de datos. También cubre la generación y el uso de consultas SQL para crear objetos Recordset y para seleccionar, ordenar, filtrar y actualizar datos en las tablas subyacentes de bases de datos. Además, este capítulo examina formas de optimizar consultas SQL para lograr mayor velocidad y rendimiento. Finalmente, se presentan con detalle las diferencias entre SQL de Microsoft Jet y SQL de ANSI.
SQL es un lenguaje de programación de bases de datos cuyos orígenes están estrechamente relacionados con la invención de las bases de datos relacionales por E. F. Codd a principios de los 70. Un antecedente del actual SQL fue el lenguaje Sequel, razón por la cual SQL todavía se pronuncia en inglés como "sequel" en vez de "letra a letra", aunque las dos pronunciaciones son aceptables.
El SQL moderno ha evolucionado hasta ser un estándar utilizado ampliamente en bases de datos relacionales y se define por la norma ANSI. La mayoría de las implementaciones de SQL tienen pocas variaciones respecto al estándar, incluyendo la versión admitida por el motor de base de datos Jet. Estas diferencias se contemplan más adelante en este capítulo, pero la estructura y el funcionamiento generales del lenguaje son muy coherentes entre los distintos fabricantes. Si ha utilizado alguna implementación de SQL, no tendrá dificultad en realizar la transición a la versión de Microsoft Jet.
Como se describió antes en este manual, el motor de base de datos Microsoft Jet proporciona dos métodos para la mayoría de las tareas con bases de datos:
El modelo de desplazamiento consta de las propiedades y métodos que se describen en el capítulo 2, "Creación y modificación de bases de datos", y el capítulo 3, "Trabajo con registros y campos". En este capítulo se describe el modelo relacional.
Los programadores que estén familiarizados con sistemas de bases de datos orientados a archivos, como dBASE, FoxPro y Paradox, se sentirán más cómodos con los modelos de desplazamiento descritos en los capítulos 3 y 4. No obstante, en la mayoría de los casos, el método equivalente de SQL es más eficiente y debe usarse cuando sea importante el rendimiento. Además, SQL tiene la ventaja de ser una interfaz de bases de datos estándar, por lo que conocer los comandos de SQL permite tener acceso y manipular una gran variedad de productos de bases de datos procedentes de distintos fabricantes.
En la práctica, a menudo se encontrará utilizando los dos modelos simultáneamente. Por ejemplo, podría utilizar la instrucción SQL SELECT para crear un pequeño Recordset de elementos seleccionados de una tabla grande y a continuación emplear los métodos de desplazamiento Move para avanzar por el Recordset y examinar determinados registros de uno en uno.
Nota Los términos relacionales fila y columna equivalen a los conocidos términos de bases de datos registro y campo. Puesto que SQL es un lenguaje de base de datos relacional puro, los términos fila y columna se utilizan con más frecuencia para describir el funcionamiento de los comandos SQL. Para evitar confusiones, ambos conjuntos de términos se usan indistintamente en este capítulo. Recuerde simplemente que una fila es un registro y una columna un campo.
El lenguaje SQL está compuesto por comandos, cláusulas, operadores y funciones agregadas. Estos elementos se combinan en las instrucciones empleadas para crear, actualizar y manipular bases de datos. Las siguientes secciones describen brevemente estos elementos del lenguaje SQL y el resto del capítulo presenta ejemplos específicos de su uso.
Nota Las secciones siguientes presentan muchos de los comandos y palabras clave habitualmente utilizados en SQL, pero no todos. Para ver una lista completa de referencia de palabras clave SQL, busque "SQL" en los Libros en pantalla.
Al igual que los métodos de desplazamiento de DAO, SQL proporciona comandos del lenguaje de definición de datos (DDL) y del lenguaje de manipulación de datos (DML). Aunque existen algunas áreas solapadas, los comandos DDL permiten crear y definir nuevas bases de datos, campos e índices, mientras que los comandos DML le permiten generar consultas para ordenar, filtrar y extraer datos de la base de datos.
Las instrucciones DDL en SQL son expresiones generadas en torno a los siguientes comandos.
Comando Descripción
CREATE Utilizado para crear nuevas tablas, campos e índices.
DROP Utilizado para eliminar tablas e índices de la base de datos.
ALTER Utilizado para modificar tablas agregando campos o cambiando la definición de los campos.
Las instrucciones DML son expresiones generadas en torno a los comandos siguientes.
Comando Descripción
SELECT Utilizado para consultar registros de la base de datos que satisfagan un criterio determinado.
INSERT Utilizado para cargar lotes de datos en la base de datos en una única operación.
UPDATE Utilizado para modificar los valores de determinados campos y registros.
DELETE Utilizado para quitar registros de una tabla de base de datos.
Las cláusulas son condiciones de modificación utilizadas para definir los datos que desea seleccionar o manipular. La siguiente tabla muestra las cláusulas que puede utilizar.
Cláusula Descripción
FROM Utilizada para especificar la tabla de la cual se van a seleccionar los registros.
WHERE Utilizada para especificar las condiciones que deben cumplir los registros que se van a seleccionar.
GROUP BY Utilizada para separar los registros seleccionados en grupos específicos.
HAVING Utilizada para expresar la condición que debe satisfacer cada grupo.
ORDER BY Utilizada para ordenar los registros seleccionados de acuerdo con un orden especificado.
Existen dos tipos de operadores en SQL: operadores lógicos y operadores de comparación.
Los operadores lógicos se usan para conectar expresiones, normalmente dentro de una cláusula WHERE. Por ejemplo:
SELECT * from Mitabla WHERE condición1 AND condición2
Aquí el operador AND conecta las expresiones condición1 y condición2 para especificar que se deben cumplir las dos condiciones para satisfacer el criterio de selección. Los operadores lógicos son:
Los operadores de comparación se usan para comparar valores relativos de dos expresiones con el fin de determinar la acción que debe ejecutarse. Por ejemplo:
SELECT * from Editores WHERE Id_de_editor = 5
Aquí el operador = especifica que sólo se seleccionarán los registros que tengan un campo Id_de_editor con un valor de 5.
Los operadores de comparación se enumeran en la siguiente tabla.
< Menor que
<= Menor o igual que
> Mayor que
>= Mayor o igual que
= Igual que
<> Distinto de
BETWEEN Utilizado para especificar un intervalo de valores
LIKE Utilizado en la comparación de modelos
IN Utilizado para especificar registros de una base de datos
Las funciones agregadas se usan dentro de una cláusula SELECT en grupos de registros para devolver un único valor que se aplica a un grupo de registros. Por ejemplo, la función agregada AVG devuelve el promedio de todos los valores de un determinado campo de un objeto Recordset. La siguiente tabla enumera las funciones agregadas.
AVG Utilizada para calcular el promedio de los valores de un determinado campo.
COUNT Utilizada para devolver el número de registros de la selección.
SUM Utilizada para devolver la suma de todos los valores de un determinado campo.
MAX Utilizada para devolver el valor más alto de un campo especificado.
MIN Utilizada para devolver el valor más bajo de un campo especificado.
El lenguaje de definición de datos (DDL) de SQL incluye una serie de comandos que puede utilizar para crear tablas e índices y para modificar tablas agregando o quitando columnas o índices. Estas instrucciones de definición de datos solamente se pueden utilizar con las bases de datos Jet. Ninguno de los formatos de bases de datos externos los admiten.
Nota Para utilizar los comandos DDL o cualquier consulta que no devuelva filas de registros, incluya toda la instrucción entre comillas dobles y utilícela como argumento del método Execute de un objeto Database o QueryDef, como en:
MiDB.Execute "CREATE TABLE Empleados _
([Nombre] TEXT, [Apellido] TEXT)"
Para utilizar los comandos que devuelven filas (como SELECT), use la instrucción como argumento de origen para el método OpenRecordset, como en:
MiDB.OpenRecordset("SELECT * FROM Títulos WHERE _
Id_de_autor = 5",dbOpenDynaset)
Para crear nuevas tablas en una base de datos, utilice la instrucción CREATE TABLE. La instrucción completa acepta argumentos para el nombre de la tabla; por cada columna (campo) puede agregar un conjunto de argumentos para el nombre del campo, el tipo de dato y, en caso de columnas de texto, el tamaño en caracteres.
El siguiente ejemplo crea una tabla llamada "Empleados" que tiene dos columnas de texto de 25 caracteres cada una:
CREATE TABLE Empleados ([Nombre] TEXT (25), _
[Apellido] TEXT (25))
Puede agregar, modificar o quitar columnas de una tabla mediante la instrucción ALTER TABLE. Por ejemplo, la siguiente instrucción agrega una columna de texto de 25 caracteres llamada "Notas" a la tabla Empleados:
ALTER TABLE Empleados ADD COLUMN Notas TEXT(25)
Para quitar una columna, utilice la palabra clave DROP. Este ejemplo elimina la columna "Notas" que se agregó en el ejemplo anterior:
ALTER TABLE Empleados DROP COLUMN Notas
Para modificar una columna, primero debe eliminarla y después agregar una nueva columna con el mismo nombre. El siguiente ejemplo incrementa el tamaño de Notas eliminándolo de la tabla y agregando un nuevo campo Notas mayor:
ALTER TABLE Empleados DROP COLUMN Notas;
ALTER TABLE Empleados ADD COLUMN Notas TEXT(30);
Nota Si utiliza ALTER TABLE, sólo puede agregar o eliminar una columna cada vez.
Existen tres formas distintas de crear un índice:
Aunque las tres formas se pueden utilizar para crear índices similares, existen algunas diferencias. Si desea agregar una clave externa y exigir la integridad referencial, debe utilizar una cláusula CONSTRAINT en la instrucción CREATE TABLE o ALTER TABLE.
Algunas veces es preferible crear primero una tabla sin índice y diseñar los parámetros del índice después de utilizar la tabla prototipo. De esta manera, se usaría CREATE TABLE para crear la tabla prototipo sin índices y más tarde se agregaría el índice con CREATE INDEX o ALTER TABLE.
Al crear una tabla, puede crear un índice sobre columnas individuales o a través de dos o más columnas mediante la cláusula SQL CONSTRAINT (la palabra clave CONSTRAINT va al principio de la definición de un índice). El siguiente ejemplo muestra un método para crear una tabla con un índice de 3 columnas:
CREATE TABLE Empleados ([Nombre] TEXT (25), _
[Apellido] TEXT (25), [Fecha de nacimiento] DATETIME, _
CONSTRAINT EmpleadosIndice UNIQUE _
([Nombre], [Apellido], [Fecha de nacimiento]));
Para indizar sólo una columna, incluya la cláusula CONSTRAINT en una de las definiciones de columna. Por ejemplo, para indizar sólo la columna Fecha de nacimiento se utiliza la siguiente instrucción CREATE TABLE:
CREATE TABLE Empleados ([Nombre] TEXT (25), _
[Apellido] TEXT (25), [Fecha de nacimiento] DATETIME _
CONSTRAINT EmpleadosIndice PRIMARY);
La diferencia entre un índice de múltiples columnas y un índice de una única columna es que, para el de una columna, la palabra clave CONSTRAINT que encabeza la definición de índice no está separada de la última columna por una coma, sino que se sitúa inmediatamente después del tipo de datos de la columna indizada.
Puede utilizar también la instrucción CREATE INDEX para agregar un índice. Este ejemplo produce el mismo resultado que el ejemplo anterior, excepto en que utiliza CREATE INDEX en lugar de ALTER TABLE:
CREATE UNIQUE INDEX MiIndice ON Empleados _
([Fecha de nacimiento])
En la cláusula opcional WITH, puede hacer que se cumplan las reglas de validación de datos: PRIMARY significa que es la columna del índice primario, DISALLOW NULL significa que esta columna no se puede dejar en blanco e IGNORE NULL significa que el registro no se indizará si la columna está en blanco.
El siguiente ejemplo agrega una cláusula WITH al ejemplo anterior, de modo que no se puede agregar a la tabla ningún registro cuya columna de número de seguro sanitario (SSN) esté vacía:
CREATE UNIQUE INDEX MiIndice ON Empleados (SSN) _
WITH DISALLOW NULL
Nota No utilice la palabra clave PRIMARY al crear un nuevo índice en una tabla que ya tiene un índice primario, ya que se producirá un error.
Puede utilizar CREATE INDEX para crear una especificación de índice en una tabla adjunta que aún no tiene índice. Para crear este índice no necesita permiso ni acceso a un servidor remoto, y la base de datos remota no se da cuenta de la existencia del índice y no se ve afectada por él. Utilice la misma sintaxis para tablas adjuntas y nativas. Esto puede ser especialmente útil para crear un índice en una tabla que en condiciones normales sería de sólo lectura al carecer de índice.
También puede agregar un índice a una tabla existente mediante la instrucción ALTER TABLE con la instrucción ADD CONSTRAINT. Por ejemplo, esta instrucción agrega un índice a la columna "SSN" de la tabla:
ALTER TABLE Empleados ADD CONSTRAINT MiIndice _
PRIMARY (SSN)
También puede agregar un índice de múltiples columnas a una tabla mediante la instrucción ALTER TABLE, como:
ALTER TABLE Empleados ADD CONSTRAINT NombreIndice _
UNIQUE ([Apellido], [Nombre], SSN)
Una restricción CONSTRAINT es un índice. Puede utilizar la cláusula CONSTRAINT para crear o eliminar índices con las instrucciones CREATE TABLE y ALTER TABLE, como se mostró en la sección anterior.
La cláusula CONSTRAINT también permite definir claves principales y externas con el fin de definir relaciones y hacer que se cumpla la integridad referencial.
Existen dos tipos de cláusulas CONSTRAINT: una para crear un índice de un único campo y otra para crear un índice de varios campos.
La sintaxis para un índice de un único campo es:
tablaExterna [(campoExterno1, campoExterno2)]}
La sintaxis para un índice de varios campos es:
|UNIQUE (único1[, único2 [, ...]]) |FOREIGN KEY (ref1[, ref2 [, ...]])
REFERENCES tablaExterna [(campoExterno1 [, campoExterno2 [, ...]])]}
Los siguientes argumentos se aplican a las dos versiones.
Argumento Descripción
nombre El nombre del índice que se va a crear.
principal1, principal2 El nombre del campo o campos designados como clave principal.
único1, único2 El nombre del campo o campos designados como una clave única.
ref1, ref2 El nombre de un campo o campos clave externos que hacen referencia a campos de otra tabla.
tablaExterna El nombre de la tabla externa que contiene el campo o los campos especificados por campoExterno.
campoExterno1, campoExterno2 El nombre del campo o campos de tablaExterna especificados por ref1, ref2.
Mediante CONSTRAINT puede designar un campo como uno de los siguientes tipos de índices:
Por ejemplo, para agregar el índice Id_de_autor a la tabla Títulos de la base de datos de ejemplo Biblio.mdb, podría utilizar la siguiente instrucción:
ALTER TABLE Títulos ADD CONSTRAINT MiIndice _
FOREIGN KEY (Id_de_autor) REFERENCES Editores (Id_de_autor}
Tenga en cuenta que al usar la palabra clave FOREIGN KEY está creando una relación entre el campo Id_de_autor de la tabla Títulos (clave externa) y el campo Id_de_autor de la tabla Editores (clave principal). El motor Jet exigirá esta relación como si hubiera utilizado el método CreateRelation descrito en el capítulo 2, "Creación y modificación de bases de datos".
Las instrucciones del lenguaje de manipulación de datos (o DML) SQL se utilizan para recuperar, actualizar, agregar o eliminar registros de tablas. Para estas tareas se admiten diversas instrucciones, pero la mayoría de ellas utilizan la estructura general de la consulta SELECT.
Utilice la instrucción SELECT para recuperar registros de una base de datos en forma de un conjunto de registros, almacenándolos en un nuevo objeto Recordset. Posteriormente, su aplicación puede manipular este Recordset presentando, agregando, cambiando o eliminando registros según sea necesario. Su aplicación también puede presentar y crear informes a partir de los datos.
SELECT suele ser la primera palabra de una instrucción SQL. La mayoría de las instrucciones SQL son SELECT o SELECT...INTO. Puede utilizar una instrucción SELECT en la propiedad SQL de un objeto QueryDef, en la propiedad RecordSource de un control de datos o como argumento para el método OpenRecordset. Las instrucciones SELECT no modifican los datos de la base de datos; sólo los recuperan.
La estructura general de la consulta SELECT es la siguiente:
FROM nombres_tablas IN nombre_base_datos
WHERE condiciones_búsqueda
GROUP BY lista_campos
HAVING criterios grupo
ORDER BY lista_campos
WITH OWNERACCESS OPTION
Cada una de estas instrucciones y cláusulas se describen en las próximas secciones.
La consulta SELECT más simple es:
Por ejemplo, la siguiente consulta SELECT devolverá todas las columnas de todos los registros de la tabla Empleados:
SELECT * FROM Empleados
El asterisco indica que se van a recuperar todas las columnas de la tabla o tablas deseadas. Podría especificar sólo algunas columnas. Cuando muestre los datos de cada columna, aparecerán en el orden que se indica, por lo que puede reordenar las columnas para aumentar su legibilidad:
SELECT [Nombre], [Apellidos] FROM Empleados
Una instrucción SELECT siempre tendrá una cláusula FROM, que indicará la tabla o tablas cuyos registros se extraerán.
Si el nombre del campo está incluido en dos o más tablas en la cláusula FROM, debe precederlo con el nombre de la tabla y el operador . (punto). En el ejemplo siguiente, el campo Departamento está en las tablas Empleados y Supervisores. La instrucción SQL selecciona Departamento de la tabla Empleados y NombreSuperv de la tabla Supervisores:
SELECT Empleados.Departamento NombreSuperv _
FROM Supervisores, Empleados _
WHERE Empleados.Departamento= Supervisores.Departamento
Cuando la cláusula FROM incluye más de una tabla, no es importante el orden en el que aparecen.
Algunas veces necesitará hacer referencia a una tabla de una base de datos externa a la que pueda conectarse el motor de base de datos Microsoft Jet, como una base de datos de dBASE o Paradox, o una base de datos externa de Jet. Esto se consigue con la cláusula opcional IN. La cláusula IN aparece generalmente a continuación del nombre de una tabla en una cláusula FROM, pero también puede utilizarse en una cláusula SELECT INTO o INSERT INTO, donde la tabla de destino está en una base de datos externa.
Nota Puede utilizar IN para conectarse a una única base de datos externa a la vez.
En algunos casos, el argumento ruta_acceso se refiere al directorio que contiene los archivos de base de datos. Por ejemplo, cuando trabaja con tablas de bases de datos de dBASE, FoxPro o Paradox, el argumento ruta_acceso especifica el directorio que contiene los archivos .DBF o .DB. El nombre de archivo de la tabla deriva de los argumentos destino o expresión_tabla.
Para especificar una base de datos que no sea de Jet, anexe un punto y coma (;) al nombre e inclúyalo entre comillas simples (' ') o dobles (" "). Por ejemplo:
'dBASE IV;'
También puede utilizar la palabra clave DATABASE para especificar la base de datos externa. Por ejemplo, las dos líneas siguientes especifican la misma tabla:
SELECT * FROM Table IN "" [dBASE IV; _
DATABASE=C:\DBASE\DATOS\VENTAS;];
SELECT * FROM Table IN "C:\DBASE\DATOS\VENTAS" _
"dBASE IV;"
Nota Para mejorar el rendimiento y facilitar su uso, casi siempre es mejor utilizar una tabla adjunta en lugar de una cláusula IN.
Cuando se crea un objeto Recordset mediante una instrucción SELECT, los nombres de las columnas de la tabla se transforman en los nombres de objetos Field del Recordset. Si quiere tener nombres de columnas diferentes, utilice la cláusula AS. El siguiente ejemplo utiliza el título "FDN" para asignar nombre a la columna de fecha de nacimiento extraída de la tabla Empleados:
SELECT [Fecha de nacimiento] AS FDN FROM Empleados;
Cada vez que utilice consultas que devuelvan nombres de objeto Field ambiguos o duplicados, debe utilizar la cláusula AS para proporcionar un nombre alternativo para el objeto Field. El siguiente ejemplo utiliza el título "Cuenta principal" para asignar nombre al objeto Field devuelto en el Recordset resultante:
SELECT COUNT(Id. de empleado) AS [Cuenta principal] _
FROM Empleados;
En un programa de Visual Basic puede crear una instrucción SELECT en su aplicación si concatena variables locales dentro de la instrucción, según se necesite para seleccionar, ordenar o filtrar los datos en su aplicación. Por ejemplo, si tiene un control TextBox (TituloDeseado) que contiene el nombre de un Titulo y desea seleccionar todos los libros de la tabla Titulos que tienen este título, puede crear una instrucción SQL que incluya el valor actual del TextBox. Observe que la consulta SQL incluye entre comillas simples (' ') el valor de TituloDeseado:
Set Rst = Db.OpenRecordset("SELECT * FROM Titulos " _
& " WHERE Titulo = '" & TituloDeseado.Text & "'" )
SQL proporciona varios predicados de palabras clave y cláusulas opcionales que le ayudan a depurar aún más la consulta y a ordenar el conjunto de resultados. Los más útiles se describen en las siguientes secciones.
Para omitir registros que contengan datos duplicados en las columnas seleccionadas, utilice la palabra clave DISTINCT. Para que se incluyan en los resultados de la consulta, los valores de cada columna o combinación de columnas que aparecen en la instrucción SELECT debe ser únicos. Por ejemplo, varios empleados incluidos en una tabla Empleados pueden tener el mismo apellido. Si dos registros contienen Soto en el campo Apellido, la siguiente instrucción SQL devuelve sólo uno de ellos:
SELECT DISTINCT _
FROM Empleados;
Si omite DISTINCT, esta consulta devuelve ambos registros Soto.
El Recordset resultante de una consulta DISTINCT no es actualizable y no refleja cambios posteriores realizados por otros usuarios.
Para devolver únicamente un cierto número de registros que figuran en la parte superior o inferior de un intervalo especificado por una cláusula ORDER BY, utilice el predicado TOP. Suponga que desea obtener los nombres de los 25 mejores estudiantes de la promoción de 1994:
SELECT TOP 25 [Nombre], [Apellido] FROM Alumnos _
WHERE [Año de graduación] = 1994 _
ORDER BY [Nota media] DESC;
Si no incluye la cláusula ORDER BY, la consulta devolverá un conjunto arbitrario de 25 registros de la tabla Alumnos que satisfacen la cláusula WHERE.
El predicado TOP no selecciona entre valores iguales. En el ejemplo anterior, si los alumnos número 25 y 26 tienen la misma media de puntuación, la consulta devolverá 26 registros.
Puede usar la palabra clave PERCENT para devolver un porcentaje determinado de registros que figuran en la parte superior o inferior de un intervalo especificado por una cláusula ORDER BY. Suponga que, en lugar de los 25 mejores alumnos, desea ver el 10 por ciento de los alumnos de la clase que han obtenido las mejores notas:
SELECT TOP 10 PERCENT [Nombre], [Apellido] _
FROM Alumnos _
WHERE [Año de graduación] = 1994 _
ORDER BY [Nota media] DESC;
La cláusula WHERE especifica qué registros de las tablas indicadas en la cláusula FROM se incluyen en los resultados de la instrucción SELECT.
El motor de base de datos Microsoft Jet selecciona los registros que cumplen las condiciones enumeradas en la cláusula WHERE. Si no especifica una cláusula WHERE, la consulta devolverá todas las filas de la tabla. Si especifica dos o más tablas en su consulta y no ha incluido una cláusula WHERE o JOIN, la consulta generará un producto cartesiano de las tablas.
Nota Aunque una cláusula WHERE pueda realizar tareas similares, debe utilizar una cláusula JOIN para realizar operaciones de combinación SQL en múltiples tablas si quiere que el Recordset resultante sea actualizable.
WHERE es opcional pero, cuando aparece, lo hace después de FROM. Por ejemplo, puede seleccionar todos los empleados del departamento de Ventas:
WHERE Departamento = 'Ventas'
o todos los clientes con edades comprendidas entre 18 y 30 años:
WHERE Edad Between 18 AND 30
WHERE es similar a HAVING. WHERE determina qué registros se seleccionan. Igualmente, una vez que los registros se agrupan con GROUP BY, HAVING determina los registros que se muestran.
Utilice la cláusula WHERE para eliminar los registros que no desea agrupar con la cláusula GROUP BY.
Utilice varias expresiones para determinar los registros que devuelven las instrucciones SQL. Por ejemplo, la siguiente instrucción SQL selecciona todos los empleados cuyos salarios superan la cifra de 21000 $:
SELECT [Apellido], Salario _
FROM Empleados _
WHERE Salario > 21000;
Una cláusula WHERE puede contener hasta 40 expresiones vinculadas por operadores lógicos, como AND y OR.
Cuando especifica un nombre de campo que contiene un espacio en blanco o un signo de puntuación, debe incluirlo entre corchetes ([ ]):
SELECT [Id. de producto], [Unidades en existencia]
FROM Productos _
WHERE [Unidades en existencia] <= [Nivel de nuevo pedido];
Cuando especifique el argumento criterio, los literales de fecha deben estar en formato EE.UU., aunque no esté utilizando la versión norteamericana del motor de base de datos Jet. Por ejemplo, 10 de mayo de 1994, se escribe 10/5/94 en el Reino Unido y 5/10/94 en Estados Unidos. Asegúrese de incluir los literales de fecha con el signo de número (#), como muestran los siguientes ejemplos.
Para encontrar los registros con fecha del 10 de mayo de 1994 en una base de datos del Reino Unido, debe utilizar la siguiente instrucción SQL:
SELECT * FROM Pedidos _
WHERE [Fecha de envío] = #5/10/94#;
También puede utilizar la función DateValue, que tiene en cuenta la configuración internacional establecida por Microsoft Windows. Por ejemplo, el código para Estados Unidos es:
SELECT * FROM Pedidos _
WHERE [Fecha de envío] = DateValue('5/10/94');
El código en el Reino Unido es:
SELECT * FROM Pedidos _
WHERE [Fecha de envío] = DateValue('10/5/94');
GROUP BY es una cláusula opcional que combina, en un único registro, registros con valores idénticos en la lista de campos especificada. Se crea un valor resumen para cada registro al incluir en la instrucción SELECT una función agregada de SQL, como Sum o Count.
Los valores resumen se omiten si no existen funciones agregadas de SQL en la instrucción SELECT.
Los valores NULL en los campos GROUP BY se agrupan y no se omiten. Sin embargo, los valores NULL no se evalúan en ninguna función agregada de SQL.
Utilice la cláusula WHERE para excluir filas que no desee agrupar y utilice la cláusula HAVING para filtrar registros una vez que se hayan agrupado.
A menos que contenga datos Memo o de objetos de Automatización, un campo de la lista de campos GROUP BY puede hacer referencia a cualquier campo especificado en la cláusula FROM, aunque el campo no esté incluido en la instrucción SELECT, siempre y cuando la instrucción SELECT incluya al menos una función agregada de SQL. El motor de base de datos Jet no puede agrupar campos Memo o de objetos de Automatización.
Todos los campos de la lista SELECT deben incluirse en la cláusula GROUP BY o como argumentos para una función agregada de SQL.
Cuando especifique un nombre de campo que contenga un espacio en blanco o un signo de puntuación, inclúyalo entre corchetes ([ ]):
SELECT [Nombre de producto], Sum([Unidades en existencia]) _
FROM Productos _
GROUP BY [Nombre de producto];
Especifica qué registros agrupados se muestran en una instrucción SELECT con una cláusula GROUP BY. Cuando GROUP BY ya ha combinado registros, HAVING muestra cualquier registro agrupado por la cláusula GROUP BY que satisfaga las condiciones de la cláusula HAVING.
HAVING es parecido a WHERE, que determina los registros que se seleccionan. Una vez que los registros se agrupan con GROUP BY, HAVING determina los que se muestran.
HAVING es opcional. Una cláusula HAVING puede contener hasta 40 expresiones vinculadas por operadores lógicos, como AND y OR.
La cláusula ORDER BY determina el orden de los registros recuperados en la consulta. En la cláusula ORDER BY se especifica la columna o columnas utilizadas como clave de ordenación, especificando a continuación si los registros se ordenarán de forma ascendente o descendente. El siguiente ejemplo devuelve todos los registros de la tabla Empleados, ordenados alfabéticamente por apellido:
SELECT * FROM Empleados _
ORDER BY [Apellido] ASC;
En este ejemplo, la palabra clave ASC (de "orden ascendente") es opcional, ya que el orden predeterminado es ascendente (A - Z, 0 - 9). Sin embargo, puede incluir la palabra clave ASC al final de cada campo que desee ordenar en sentido ascendente para documentar claramente la cláusula ORDER BY.
Los dos ejemplos siguientes ordenan los nombres de empleados por apellidos:
SELECT [Apellido], [Nombre] FROM Empleados _
ORDER BY [Apellido];
SELECT [Apellido], [Nombre] FROM Empleados _
ORDER BY [Apellido] ASC;
Para obtener un orden descendente (Z - A, 9 - 0), agregue la palabra clave DESC al final de cada campo que desee ordenar de esta forma.
También puede utilizar el número ordinal de la columna de orden como aparece en la lista de SELECT, en lugar de volver a escribir su nombre:
SELECT [Nombre], [Apellido] FROM Empleados _
ORDER BY 2 ASC;
Puede incluir campos adicionales en la cláusula ORDER BY. Los registros se ordenan por el primer campo indicado después de ORDER BY. Los registros que tienen el mismo valor en ese campo se ordenan después por el valor del segundo campo y así sucesivamente. El siguiente ejemplo selecciona los salarios y los ordena de forma descendente; todos los empleados que tengan el mismo salario se muestran en orden alfabético ascendente:
SELECT [Apellido], Salario FROM Empleados _
ORDER BY Salario DESC, [Apellido];
ORDER BY suele ser el último elemento en una instrucción SQL. Es opcional (a menos que utilice los predicados TOP o TOP n PERCENT en la cláusula SELECT.) Si no incluye ORDER BY, los datos se presentan sin ordenar.
En un entorno multiusuario con un grupo de trabajo seguro, utilice WITH OWNERACCESS OPTION al final de una consulta para otorgar al usuario que ejecuta la consulta permiso para ver los datos, aunque se haya restringido de otra manera el permiso del usuario para ver las tablas base de la consulta.
El siguiente ejemplo permite al usuario devolver la información del salario, aunque no tiene permiso para ver la tabla Salario, siempre y cuando la consulta la haya creado alguien que sí tiene ese permiso:
SELECT [Apellido], [Nombre], Salario FROM Empleados _
ORDER BY [Apellido] _
WITH OWNERACCESS OPTION;
Si un usuario no puede crear o agregar datos a tablas, puede utilizar WITH OWNERACCESS OPTION para permitirle ejecutar una consulta de creación de tabla o de datos anexados.
Esta opción requiere acceso al archivo System.mds asociado a la base de datos. Sólo es realmente útil en implementaciones multiusuario protegidas.
Una variación de la instrucción SELECT permite crear una nueva tabla, en lugar de un objeto Recordset, con los registros devueltos. Para ello, agregue la cláusula INTO. El siguiente ejemplo crea una nueva tabla llamada Nuevos empleados consultando la tabla Empleados:
SELECT * INTO [Nuevos empleados] FROM Empleados
Puede utilizar las consultas de creación de tabla para archivar registros, hacer copias de seguridad de sus tablas o hacer copias para exportarlas a otra base de datos o para utilizarlas como base para informes que muestren datos de periodos de tiempo específicos. Por ejemplo, puede generar un informe de ventas mensuales por región ejecutando la misma consulta de creación de tabla cada mes.
Quizá desee definir una clave principal para la nueva tabla. Al crear la tabla, los campos de la nueva tabla heredan el tipo de datos y el tamaño de los campos de las tablas base de la consulta, pero no se transfieren otras propiedades de campos o tabla.
Crea una consulta de eliminación que elimina registros de una o más tablas incluidas en la cláusula FROM que satisfagan la cláusula WHERE, como se muestra en la siguiente sintaxis:
FROM expresión_tabla
WHERE criterios
DELETE es especialmente útil cuando desee eliminar numerosos registros.
En una instrucción DELETE multitabla, debe incluir el argumento tabla. Si especifica más de una tabla de las que desea eliminar registros, ninguna de ellas puede contener la clave principal de una relación uno a varios.
Si desea eliminar todos los registros de una tabla, puede ser más eficaz eliminar la propia tabla que ejecutar la consulta de eliminación. Puede utilizar el método Execute con una instrucción DROP TABLE para eliminar una tabla de la base de datos. Sin embargo, si elimina la tabla la estructura se pierde. Por el contrario, al utilizar DELETE sólo se eliminan los datos, permaneciendo intactas la estructura de la tabla y todas sus propiedades, como los atributos de campos e índices.
Puede utilizar DELETE para quitar registros de una única tabla o de la parte varios de una relación uno a varios. Las operaciones de eliminación en cascada de una consulta únicamente eliminan datos de la parte varios de la relación. Por ejemplo, en la relación entre las tablas Clientes y Pedidos, la tabla Pedidos es la parte varios, por lo que la operación de eliminación en cascada afecta únicamente a la tabla Pedidos.
Una consulta de eliminación elimina registros enteros, no sólo datos de campos determinados. Si desea eliminar valores de un campo específico, cree una consulta de actualización que cambie dichos valores a Null.
Cuando haya quitado los registros mediante una consulta de eliminación, no podrá deshacer la operación. Si desea saber qué registros se han eliminado, examine primero los resultados de una consulta de selección que utilice los mismos criterios y después ejecute la consulta de eliminación.
Debe conservar siempre copias de seguridad de sus datos. Si elimina accidentalmente los registros equivocados, puede recuperarlos a partir de la copia de seguridad.
Puede utilizar la instrucción INSERT INTO para agregar registros a una tabla o crear una consulta de datos anexados.
Puede utilizar la siguiente sintaxis para ejecutar una consulta de datos anexados con múltiples registros:
SELECT [origen.]campo1[, campo2[, ...]
FROM expresión_tabla
Por el contrario, utilice esta sintaxis para ejecutar una consulta de datos anexados sobre un único registro:
VALUES (valor1[, valor2[, ...])
Puede utilizar la instrucción INSERT INTO para agregar un único registro a una tabla mediante la sintaxis de consulta de datos anexados de registros únicos. En este caso, su código especifica el nombre y el valor para cada campo del registro. Debe especificar los campos del registro a los que se asignará un valor, así como el valor que desea asignarle. Cuando no especifica cada campo, el valor predeterminado o Null se inserta en las columnas que faltan. Los registros se agregan al final de la tabla.
También puede utilizar INSERT INTO para anexar un conjunto de registros de otra tabla o consulta mediante la cláusula SELECT...FROM, como se muestra en la sintaxis de consulta de datos anexados de múltiples registros. En este caso, la cláusula SELECT especifica los campos que se agregan a la tabla de destino especificada.
La tabla de origen o de destino puede especificar una tabla o una consulta. Si se especifica una consulta, el motor de base de datos Microsoft Jet anexa un conjunto de registros a todas y cada una de las tablas especificadas en la consulta.
INSERT INTO se utiliza a menudo para anexar una nueva tabla de registros de clientes a la tabla Clientes activa.
INSERT INTO es opcional, pero cuando se incluye, precede a la instrucción SELECT.
Si la tabla de destino contiene una clave principal, asegúrese de que anexa valores únicos y que no sean Null al campo o campos de la clave principal; si no lo hace, el motor Jet no anexará los registros.
Si anexa registros a una tabla con un campo contador, no incluya el campo contador en su consulta si quiere que el motor Jet vuelva a numerar los registros anexados. Incluya el campo contador en la consulta si desea conservar los valores originales del campo. No obstante, el motor Jet no anexará los registros si hay valores duplicados.
Utilice la cláusula IN para anexar registros a una tabla de otra base de datos.
Para crear una tabla nueva, utilice la instrucción SELECT...INTO en lugar de crear una consulta de creación de tabla.
Para averiguar qué registros se anexarán antes de ejecutar la consulta de datos anexados, ejecute y vea primero los resultados de una consulta de selección que utilice los mismos criterios de selección.
Una consulta de datos anexados copia registros de una o más tablas a otra. Las tablas que contienen los registros anexados no quedan afectadas por la consulta.
En lugar de anexar registros de otra tabla, puede especificar el valor para cada campo en un único registro nuevo mediante la cláusula VALUES. Si omite la lista de campos, la cláusula VALUES debe incluir un valor para cada campo de la tabla; si no se hace así, INSERT fallará. Utilice una instrucción INSERT INTO adicional con una cláusula VALUES para cada registro adicional que desee crear.
UPDATE crea una consulta de actualización que cambia valores de campos en una tabla especificada según determinados criterios.
UPDATE tablaSET nuevo_valor
WHERE criterio;
UPDATE es especialmente útil cuando desea cambiar numerosos registros o cuando los registros que quiere cambiar están en múltiples tablas. Generalmente, la instrucción UPDATE se usa con el método Execute.
Puede cambiar varios campos simultáneamente. El siguiente ejemplo incrementa los valores de Cantidad de pedido en un 10 por ciento y los de Gastos de envío en un 3 por ciento para envíos del Reino Unido:
UPDATE Pedidos _
SET [Cantidad de pedido] = [Cantidad de pedido] * 1.1, _
[Gastos de envío] = [Gastos de envío] * 1.03 _
WHERE [País de envío] = 'RU';
UPDATE no genera ningún conjunto de resultados. Si desea saber los registros que se cambiarán, examine primero los resultados de una consulta de selección que utilice los mismos criterios y ejecute después la consulta de actualización.
Las consultas complejas combinan una o más instrucciones SELECT, o múltiples cláusulas FROM dentro de la instrucción SELECT, para ejecutar consultas que no se pueden realizar con una única consulta para un único conjunto de tablas.
Subconsultas
Una subconsulta es una instrucción SELECT anidada dentro de otra instrucción SELECT, SELECT...INTO, INSERT...INTO, DELETE o UPDATE, o bien dentro de otra subconsulta.
Puede utilizar tres tipos de sintaxis para crear una subconsulta:
expresión [NOT] IN (instrucción_sql)
[NOT] EXISTS (instrucción_sql)
Puede utilizar una subconsulta en lugar de una expresión en la lista de campos de una instrucción SELECT o en una cláusula WHERE o HAVING. En una subconsulta, utilice una instrucción SELECT para suministrar un conjunto de uno o varios valores específicos para evaluarlos en la expresión de las cláusulas WHERE o HAVING.
Utilice los predicados ANY o SOME, que son sinónimos, para recuperar los registros de la consulta principal que satisfacen la comparación con cualquier registro recuperado en la subconsulta. El siguiente ejemplo devuelve todos los productos cuyo precio unitario es mayor que el de los vendidos con un descuento del 25 por ciento o superior:
SELECT * FROM Productos _
WHERE [Precio unitario] > ANY _
(SELECT [Precio unitario] FROM [Detalles de pedido] _
WHERE [Descuento] >= 25);
Utilice el predicado ALL para recuperar únicamente los registros de la consulta principal que satisfacen la comparación con todos los registros recuperados en la subconsulta. Si cambia ANY por ALL en el ejemplo anterior, la consulta devolverá únicamente aquellos productos cuyo precio unitario sea mayor que el de todos los productos vendidos con un descuento del 25 por ciento o superior. Esto es mucho más restrictivo.
Utilice el predicado IN para recuperar únicamente los registros de la consulta principal para los cuales algunos registros de la subconsulta contienen un valor igual. El siguiente ejemplo devuelve todos los productos vendidos con un descuento del 25 por ciento o superior:
SELECT * FROM Productos _
WHERE [Id. de producto] IN _
(SELECT [Id. de producto] FROM [Detalles de pedido] _
WHERE [Descuento] >= 25);
Por el contrario, puede utilizar NOT IN para recuperar únicamente aquellos registros de la consulta principal para los que en la subconsulta no haya ninguno que contenga un valor igual.
Utilice el predicado EXISTS (con la palabra clave opcional NOT) en comparaciones de tipo verdadero o falso para determinar si la subconsulta devuelve algún registro.
Puede utilizar también un alias de nombre de tabla en una subconsulta para hacer referencia a las tablas incluidas en una cláusula FROM fuera de la subconsulta. En el ejemplo siguiente se asigna el alias "T1" a la tabla Empleados:
SELECT [Apellido], [Nombre], Cargo, Salario _
FROM Empleados AS T1 _
WHERE Salario >= _
(SELECT Avg(Salario) _
FROM Empleados _
WHERE T1.Cargo = Empleados.Cargo) Order by Cargo;
Consultas de referencias cruzadas
Las consultas de referencias cruzadas le permiten seleccionar valores de campos o expresiones especificados como encabezados de columnas, de forma que pueda ver sus datos con un formato más compacto que con la consulta normal SELECT. Utilice la instrucción TRANSFORM para crear consultas de referencias cruzadas:
instrucción_select
PIVOT campo_dinámico [IN (valor1[, valor2[, ...]])]
La instrucción TRANSFORM utiliza los argumentos siguientes.
Argumento Descripción
función_agr Una función agregada de SQL que opera sobre los datos seleccionados.
instrucción_select Una instrucción SELECT.
campo_dinámico El campo o la expresión que desea utilizar para crear encabezados de columna en el conjunto de resultados de la consulta.
valor1, valor2 Valores fijos utilizados para crear encabezados de columna. Al resumir datos utilizando una consulta de tabla de referencias cruzadas, selecciona valores de campos o expresiones especificados como encabezados de columna, por lo que puede ver los datos en un formato más compacto que con una consulta de selección.
TRANSFORM precede a la instrucción SELECT que especifica los campos utilizados como encabezados de fila y a una cláusula GROUP BY que especifica la agrupación de filas. Opcionalmente puede incluir otras cláusulas como WHERE, que especifican criterios adicionales de selección o de ordenación.
Los valores devueltos en campo_dinámico se utilizan como encabezados de columna en el conjunto de resultados de la consulta. Por ejemplo, ordenando las cifras de ventas por el mes de la venta en una consulta de tabla de referencias cruzadas crearía 12 columnas. Puede restringir campo_dinámico para crear encabezados de valores fijos (valor1, valor2) indicados en la cláusula opcional IN. También puede incluir valores fijos para los que no existen datos con el fin de crear columnas adicionales.
El siguiente ejemplo crea una consulta de tabla de referencias cruzadas que muestra las ventas mensuales de productos durante un año especificado por el usuario. Los meses se devuelven de izquierda a derecha (ordenados) como columnas y los nombres de los productos se devuelven de arriba a abajo como filas.
PARAMETERS [¿Ventas de qué año?] LONG; TRANSFORM _
Sum([Detalles de pedido].Cantidad * ([Detalles de pedido]. _
[Precio unitario] - ([Detalles de pedido].Descuento / 100)) _
* [Detalles de pedido].[ Precio unitario])) AS Ventas SELECT _
[Nombre de producto] FROM Pedidos INNER _
JOIN(Productos INNER JOIN [Detalles de pedido] ON _
Productos.[Id. de producto] = [Detalles de pedido]._
[Id. de producto]) ON Pedidos.[Id. de pedido] = _
[Detalles _ Pedido].[Id. de pedido] WHERE DatePart_
("yyyy", [Fecha de pedido]) = [¿Ventas de qué año?] _
GROUP BY [Nombre de producto] ORDER BY [Nombre de producto] _
PIVOT DatePart("m", [Fecha de pedido])
- Combinaciones
Una de las características más poderosas de las bases de datos relacionales es la capacidad de combinar dos o más tablas para crear una tabla nueva (o Recordset) que contiene información de las dos tablas iniciales.
Las tablas se combinan de acuerdo con las relaciones existentes entre ellas, generalmente entre la clave principal de una tabla y la clave externa correspondiente de otra. Dependiendo de cómo estén combinadas las tablas, puede crear los siguientes tipos de combinaciones.
Combinación Descripción
INNER JOIN Los registros de las dos tablas se incluyen en la combinación sólo cuando un campo especificado de la primera tabla coincide con el campo especificado de la segunda.
LEFT OUTER JOIN Todos los registros de la primera tabla se incluyen en la combinación, junto con los registros de la segunda tabla en los que coinciden los campos especificados.
RIGHT OUTER JOIN Todos los registros de la segunda tabla se incluyen en la combinación, junto con los registros de la primera tabla en los que coinciden los campos especificados.
Combinaciones internas
Para crear una consulta que incluya únicamente registros en los que coinciden los datos de los campos combinados, utilice la operación INNER JOIN.
INNER JOIN combina registros de dos tablas siempre que existan valores coincidentes en un campo común. Utilice la siguiente sintaxis:
Puede utilizar una operación INNER JOIN en cualquier cláusula FROM. Esto crea una combinación por equivalencia, también denominada combinación interna. Las combinaciones por equivalencia son el tipo de combinaciones más común. Combinan registros de dos tablas siempre que hay valores coincidentes en un campo común a ambas tablas.
Puede utilizar INNER JOIN con las tablas Departamentos y Empleados para seleccionar todos los empleados de cada departamento. Por el contrario, para seleccionar todos los departamentos (aunque algunos no tienen empleados asignados) o todos los empleados (aunque algunos no están asignados a departamentos), puede utilizar una operación LEFT JOIN o RIGHT JOIN para crear una combinación externa.
Puede combinar dos campos numéricos cualesquiera, aunque tengan diferentes tipos de datos. Por ejemplo, puede combinar un campo Number, para el cual la propiedad Size de su objeto Field es Integer (entero), y un campo contador.
El siguiente ejemplo muestra un posible método para combinar las tablas Categorías y Productos por el campo Id. de categoría:
SELECT [Nombre de categoría], [Nombre de producto] _
FROM Categorías INNER JOIN Productos _
ON Categorías.[Id. de categoría] = Productos.[Id. de categoría];
En el ejemplo anterior, Id. de categoría es el campo combinado, pero no se incluye en el resultado de la consulta porque no está incluido en la instrucción SELECT. Para incluir el campo combinado, incluya el nombre del campo en la instrucción SELECT; en este caso, Categorías.[Id. de categoría].
El siguiente ejemplo crea dos combinaciones por equivalencia: una entre las tablas Detalles de pedido y Pedidos y otra entre las tablas Pedidos y Empleados. Esto es necesario porque la tabla Empleados no contiene datos de ventas y la tabla Detalles de pedido no contiene datos de empleados. La consulta produce una lista de empleados y sus ventas totales.
Dim MiQRY As QueryDef
MiQRY.SQL = "SELECT DISTINCTROW Sum([Precio unitario] _
[Cantidad]) AS [Ventas], [Nombre] & " " & _
[Apellido] AS Name FROM Empleados _
INNER JOIN (Pedidos INNER JOIN [Detalles de pedido] _
ON Pedidos.[Id. de pedido] = [Detalles de pedido].[Id. de pedido]) _
ON Empleados.[Id. de empleado] = Pedidos.[Id. de empleado] _
GROUP BY [Nombre] & " " & [Apellido];"
Esta instrucción debe utilizarse como la propiedad SQL de un objeto QueryDef o en una expresión SQL con el método OpenRecordset.
Omisión de filas duplicadas
El ejemplo anterior utiliza el predicado DISTINCTROW en la cláusula SELECT para omitir los datos de registros enteros duplicados, no sólo campos duplicados. Por ejemplo, podría crear una consulta para combinar las tablas Clientes y Pedidos mediante el campo Id. de cliente. La tabla Clientes no contiene campos Id. de cliente duplicados, pero la tabla Pedidos sí, ya que cada cliente puede tener varios pedidos. La siguiente instrucción SQL muestra cómo utilizar DISTINCTROW para crear una lista de compañías que tengan al menos un pedido pero sin detalles sobre tales pedidos:
SELECT DISTINCTROW [Nombre de compañía] _
FROM Clientes INNER JOIN Pedidos _
ON Clientes.[Id. de cliente] = Pedidos.[Id. de cliente] _
ORDER BY [Nombre de compañia];
Si omite DISTINCTROW, esta consulta produce múltiples filas para cada compañía que tiene más de un pedido.
DISTINCTROW tiene efecto sólo cuando selecciona campos de algunas, pero no todas, las tablas utilizadas en la consulta. DISTINCTROW se pasa por alto si su consulta incluye únicamente una tabla.
Combinaciones izquierda y derecha (externas)
Las combinaciones externas combinan registros de tablas de origen, cuando se utilizan en cualquier cláusula FROM, con la siguiente sintaxis:
Utilice una operación LEFT JOIN para crear una combinación externa izquierda. Las combinaciones externas izquierdas incluyen todos los registros de la primera de dos tablas (la de la izquierda), aunque no haya valores coincidentes para los registros de la segunda tabla (a la derecha).
Utilice una operación RIGHT JOIN para crear un combinación externa derecha. Las combinaciones externas derechas incluyen todos los registros de la segunda de dos tablas (la de la derecha), incluso aunque no haya valores coincidentes para los registros de la primera tabla (la de la izquierda).
Por ejemplo, podría utilizar LEFT JOIN con las tablas Departamentos (izquierda) y Empleados (derecha) para seleccionar todos los departamentos, incluyendo aquellos que no tengan empleados asignados. Para seleccionar todos los empleados, incluidos aquellos que no están asignados a ningún departamento, utilice RIGHT JOIN.
El siguiente ejemplo muestra un posible método para combinar las tablas Categorías y Productos mediante el campo Id. de categoría. La consulta produce una lista de todas las categorías, incluyendo las que no contienen productos:
SELECT [Nombre de categoría], _
[Nombre de producto] _
FROM Categorías LEFT JOIN Productos _
ON Categorías.[Id. de categoría] = Productos.[Id. de categoría];
En el siguiente ejemplo, Id. de categoría es el campo de combinación, pero no se incluye en el resultado de la consulta porque no está incluido en la instrucción SELECT. Para incluir el campo combinado, escriba el nombre del campo en la instrucción SELECT; en este caso, Categorías.[Id. de categoría].
Combinaciones anidadas
También puede anidar instrucciones JOIN mediante la siguiente sintaxis:
FROM tabla1 INNER JOIN
(tabla2 INNER JOIN [( ]tabla3
[INNER JOIN [( ]tablax [INNER JOIN ...)]
ON tabla3.campo3 = tablax.campox)]
ON tabla2.campo2 = tabla3.campo3)
ON tabla1.campo1 = tabla2.campo2;
Utilice la operación UNION para crear una consulta de unión, combinando los resultados de dos o más consultas o tablas independientes.
El marcador de posición consulta representa una expresión de cadena que identifica el campo que contiene los datos numéricos cuya media desea calcular o una expresión que ejecuta un cálculo mediante los datos del campo. Los operandos de una expresión pueden incluir el nombre del campo de una tabla, una constante o una función (que puede ser intrínseca o definida por el usuario pero no una de las otras funciones agregadas de SQL o agregadas de dominio).
Puede combinar los resultados de una consulta y una instrucción SQL en una única operación UNION. El siguiente ejemplo combina los resultados de una consulta existente llamada Nuevas cuentas y una instrucción SELECT:
TABLE [Nuevas cuentas] UNION ALL _
SELECT * _
FROM Clientes _
WHERE [Cantidad de pedido] > 1000;
De manera predeterminada no se devuelven registros duplicados al utilizar una operación UNION; sin embargo, puede incluir el predicado ALL para asegurarse de que se devuelven todos los registros. Esto también hace que la consulta sea más rápida.
Todas las consultas de una operación UNION deben solicitar el mismo número de campos; no obstante, los campos no tienen por qué ser del mismo tipo o tamaño.
Puede utilizar una cláusula GROUP BY o HAVING en cada argumento consulta para agrupar los datos que se devuelven. Puede utilizar la cláusula ORDER BY al final del último argumento consulta para mostrar los datos que se devuelven en un orden específico.
El tema de la optimización de bases de datos es muy extenso y completo. Algunos factores, como la configuración de hardware y software, la instalación de Windows y el tamaño de memoria caché de disco, no tienen nada que ver con las consultas, pero pueden afectar al rendimiento de la base de datos.
Otro factor importante es la utilización de tablas adjuntas en lugar de conexiones directas a bases de datos remotas. Esto se explica detalladamente en el capítulo 7, "Acceso a datos externos". Otra consideración es elegir el tipo apropiado de objeto Recordset para su uso particular. Los Recordset de tipo table, dynaset y snapshot tienen consideraciones de rendimiento particulares, descritas en el capítulo 3, "Trabajo con registros y campos".
Esta sección presentará brevemente varias sugerencias de optimización específicas para la generación de consultas y el aprovechamiento de la optimización de consultas Rushmore™ de Jet en la generación de consultas SQL.
Estrategias generales de optimización
Optimización de consultas con la tecnología Rushmore
Rushmore es una tecnología de acceso a datos utilizada en el motor de base de datos Jet que permite la consulta de conjuntos de registros de una forma muy eficiente. Con Rushmore, al usar determinados tipos de expresiones en un criterio de consulta, ésta funcionará de forma mucho más rápida.
Expresiones simples optimizables
El motor de base de datos Jet puede optimizar expresiones simples en una cláusula WHERE de una instrucción SQL SELECT. Una expresión simple optimizable puede formar una expresión entera o aparecer como parte de una expresión.
Una expresión simple optimizable tiene uno de los siguientes formatos:
- o bien -
expresión operador_comparación campo_indexado
En una expresión simple optimizable:
Nota Para obtener los mejores resultados, el valor de comparación de una expresión que usa el operador LIKE debe comenzar con un carácter distinto del carácter comodín. Por ejemplo, puede optimizar LIKE "m*" pero no LIKE "*m*".
Expresiones complejas optimizables
Microsoft Jet utiliza Rushmore para optimizar expresiones complejas creadas mediante la combinación de expresiones simples optimizables con los operadores AND y OR. Una expresión compleja optimizable tiene uno de los siguientes formatos:
- o bien -
expresión_simple OR expresión_simple
Tenga en cuenta lo siguiente cuando utilice expresiones optimizables Rushmore:
6. Diferencias entre SQL de Jet y ANSI
El lenguaje SQL del motor de base de datos Microsoft Jet generalmente se ajusta a ANSI-89 Nivel 1. Sin embargo, algunas características del lenguaje SQL de ANSI no están implementadas en SQL de Jet. Por el contrario, SQL de Jet incluye palabras clave y características no admitidas en SQL de ANSI.
Principales diferencias
A continuación se incluye una lista de las principales diferencias entre SQL de Jet y de ANSI:
Carácter coincidente Jet SQL ANSI SQL
Cualquier carácter simple ? _ (subrayado)
Cero o más caracteres * %
Características mejoradas en SQL de Jet
SQL de Jet proporciona las siguientes características mejoradas:
Copyrigth © Javier Jiménez Muñoz, Colombia, 1.999. Aportes de información, manuales o comentarios de mi Web, envia un email a valeth33@yahoo.es. |
![]() ![]() ![]() |