Sunteți pe pagina 1din 52

Taller de Base de datos

SQL: Lenguaje de manipulación de datos (DML)

OBJETIVOS
• Conocer las sentencias disponibles en SQL para manipulación de datos, es decir,
insertar, modificar o eliminar filas de una tabla.
1. Inserción de filas en una tabla
Consiste en añadir una o varias filas a una tabla. La sentencia es la siguiente:

INSERT INTO <nombre tabla> [(<lista-de columnas>)]


{VALUES (<lista-de valores>)
<sentencia SELECT> }

Se puede emplear para dos objetivos distintos:


a) Insertar una fila en una tabla

INSERT INTO <nombre tabla> [(<lista-de columnas>)]


VALUES (<lista-de valores>)

b) Insertar en una tabla el resultado de una consulta (inserción multifila)

INSERT INTO <nombre tabla> [(<lista-de columnas>)]


<sentencia SELECT>

Los valores de tipo DATE o CHAR se deben encerrar entre comillas simples.
Si no se indica la lista de columnas, se consideran todas las de la tabla.
En la opción b) la tabla donde se inserta se puede utilizar en la consulta SELECT.
En la opción b) la consulta no puede obtener una cláusula ORDER BY.
Los valores insertados deben ser de un tipo compatible con el de las columnas de la
tabla.

2. Eliminación de filas de una tabla


Permite eliminar filas de una tabla. La sentencia es:
DELETE FROM <nombre tabla> [WHERE <condición>]
Si no se pone condición, se borran todas las filas de la tabla.

3. Modificación de los datos de una tabla


Se emplea para modificar los datos de las filas existentes en una tabla:

UPDATE <nombre tabla> SET


{ <columna> = <expresión> [, ...]
| {(<lista-de columnas>) | *} = (<lista-de expresiones>) }
[WHERE <condición>]

Una expresión puede estar formada por una subconsulta SELECT entre paréntesis cuyo
resultado es una única fila de una sola columna (un único valor simple).
La lista de columnas está formada por aquellas columnas a las cuales se les modificará
su valor. Si se omite la cláusula WHERE entonces se actualizan todas las filas de la
tabla.

SQL II (Lenguaje de Manipulación de


Datos)
• Introducción de información (INSERT)
• Consulta de información (SELECT)
o Consulta condicional (WHERE)
o Ordenación de la salida (ORDER BY)
o Evitar repetición en la salida (DISTINCT)
o Funciones de agregación (AVG, MAX, MIN, SUM, COUNT)
o Cuantificadores (SOME, ANY, ALL)
o Patrones en cadenas (LIKE)
o Renombramiento (AS)
o Combinación de consultas
o Operaciones sobre conjuntos (UNION, INTERSECT, EXCEPT)
o Consultas agrupadas (GROUP BY)
• Modificación de información (UPDATE)
• Borrado de información (DELETE)

Introducción o inserción de tuplas


INSERT INTO provincia VALUES (41,'SEVILLA');
INSERT INTO provincia VALUES (21,'HUELVA');
INSERT INTO provincia VALUES (28,'MADRID');
INSERT INTO provincia VALUES (8,'BARCELONA');
INSERT INTO provincia VALUES (23,'JAEN');

INSERT INTO alumno VALUES (4,'ANTONIO','PEREZ LOPEZ',22,41,6.5);


INSERT INTO alumno VALUES (3,'PABLO','SUAREZ GUERRA',25,21,7.8);
INSERT INTO alumno VALUES (82,'RAFAELA','PEREZ LOPEZ',19,8,4.3);
INSERT INTO alumno VALUES (9,'MARIO','BEATO SOLIS',22,28,5.1);
INSERT INTO alumno VALUES (2,'ANGELA','RODRIGUEZ JODAR',27,41,6.9);
INSERT INTO alumno VALUES (1,'JULIAN','BARCO SANDOVAL',26,41,6.5);
INSERT INTO alumno VALUES (8,'FRANCISCA','RAMIREZ MARTIN',25,41,3.5);
INSERT INTO alumno VALUES (12,'BENITO','GOTERA OTILIO',28,21,9.3);
Para que la inserción de una tupla sea válida deben satisfacerse las restricciones de
clave, integridad y de otro tipo que pudieran existir. Obsérvese que en el ejemplo los
valores del atributo añadido a los de la definición original de la tabla ocupan el último
lugar en la lista de valores y que los valores de los atributos se especifican en el mismo
orden en que fueron declarados los atributos. Si no se recuerda el orden de los atributos
entonces se puede especificar en cualquier orden el nombre de cada atributo dentro de la
sentencia INSERT de la siguiente manera:
INSERT INTO alumno (num,codprov,apellidos,nombre,nota,edad)
VALUES (12,21,'GOTERA OTILIO','BENITO',9.3,28);
No es necesario insertar tuplas individualmente de una en una sino que también pueden
insertarse varias tuplas resultantes de una consulta.

Consulta
1. Listar todo el contenido de una tabla
SELECT * FROM provincia;

CODPROV NOMPROV
---------- --------------------
41 SEVILLA
21 HUELVA
28 MADRID
8 BARCELONA
23 JAEN

SELECT * FROM alumno;


NUM NOMBRE APELLIDOS EDAD CODPROV NOTA
------ ---------- -------------------- ------ -------- ------
4 ANTONIO PEREZ LOPEZ 22 41 6.5
3 PABLO SUAREZ GUERRA 25 21 7.8
82 RAFAELA PEREZ LOPEZ 19 8 4.3
9 MARIO BEATO SOLIS 22 28 5.1
2 ANGELA RODRIGUEZ JODAR 27 41 6.9
1 JULIAN BARCO SANDOVAL 26 41 6.5
8 FRANCISCA RAMIREZ MARTIN 25 41 3.5
12 BENITO GOTERA OTILIO 28 21 9.3
Observar que las tuplas se listan en la salida en el orden en que se hubieran introducido.

2. Selección de atributos concretos:

SELECT apellidos, nombre, edad FROM alumno;

APELLIDOS NOMBRE EDAD


-------------------- ---------- ----------
PEREZ LOPEZ ANTONIO 22
SUAREZ GUERRA PABLO 25
PEREZ LOPEZ RAFAELA 19
BEATO SOLIS MARIO 22
RODRIGUEZ JODAR ANGELA 27
BARCO SANDOVAL JULIAN 26
RAMIREZ MARTIN FRANCISCA 25
GOTERA OTILIO BENITO 28

3. Ordenación de la salida

SELECT * FROM provincia ORDER BY nomprov;

CODPROV NOMPROV
---------- --------------------
8 BARCELONA
21 HUELVA
23 JAEN
28 MADRID
41 SEVILLA

SELECT apellidos, nombre, edad FROM alumno ORDER BY edad;


APELLIDOS NOMBRE EDAD
-------------------- ---------- ----------
PEREZ LOPEZ RAFAELA 19
PEREZ LOPEZ ANTONIO 22
BEATO SOLIS MARIO 22
SUAREZ GUERRA PABLO 25
RAMIREZ MARTIN FRANCISCA 25
BARCO SANDOVAL JULIAN 26
RODRIGUEZ JODAR ANGELA 27
GOTERA OTILIO BENITO 28

Puede ordenarse tanto por valores alfabeticos como numéricos. Puede ordenarse de
menor a mayor (orden ascendente, o ASC) o de mayor a menor (orden descendente, o
DESC). Por defecto el orden considerado es de menor a mayor. La ordenación tiene
asociado un cierto coste computacional por lo que solo debe realizarse cuando sea
necesario.

4. Ordenación múltiple

SELECT apellidos, nombre FROM alumno ORDER BY edad DESC,


apellidos ASC, nombre ASC;

APELLIDOS NOMBRE
-------------------- ----------
GOTERA OTILIO BENITO
RODRIGUEZ JODAR ANGELA
BARCO SANDOVAL JULIAN
RAMIREZ MARTIN FRANCISCA
SUAREZ GUERRA PABLO
BEATO SOLIS MARIO
PEREZ LOPEZ ANTONIO
PEREZ LOPEZ RAFAELA

5. Condición simple

SELECT apellidos FROM alumno WHERE edad = 23;


SELECT apellidos FROM alumno WHERE edad != 23;
SELECT * FROM alumno WHERE edad BETWEEN 19 AND 25;
SELECT num FROM alumno WHERE nota IS NOT null;
SELECT num FROM alumno WHERE codprov IN (21, 41);

6. Condición compuesta

SELECT nota FROM alumno WHERE edad > 20 AND codprov = 41;
SELECT num FROM alumno WHERE edad < 20 OR edad > 30;
SELECT edad FROM alumno WHERE edad < 20 OR codprov NOT IN (41,21);

7. Combinación de condición y ordenación

SELECT nota FROM alumno WHERE nota>=5 AND edad>20 ORDER BY nota;

(Nombre y apellidos de los alumnos aprobados (nota>=5) y con edad mayor de 20


años, ordenados según la nota).
NOTA
----------
5.1
6.5
6.5
6.9
7.8
9.3

Obsérvese que en la salida puede aparecer un mismo valor repetidas veces.

SELECT nombre, ape FROM alumno WHERE edad>20 ORDER BY edad, nota DESC;

(Nombre y apellidos de los alumnos con edades mayores de 20 años, ordenados por
edad y nota).

8. Evitar repetición en la salida

SELECT DISTINCT apellidos FROM alumno WHERE edad=23;


SELECT UNIQUE edad FROM alumno;

La salida de una consulta de este tipo suele (dependiendo de la implementación concreta


en cada caso) estar ordenada por defecto.

9. Función media aritmética

Las funciones de agregación toman como entrada una colección de valores o tuplas de
salida producidas por una consulta y producen un único valor como salida.

SELECT AVG(edad) FROM alumno;


SELECT AVG(nota) FROM alumno WHERE nota>=5;

10. Función de cuenta

SELECT COUNT(*) FROM alumno WHERE nota>=5;

11. Cardinalidad de una tabla (número de filas o tuplas)

SELECT COUNT(*) FROM alumno;

12. Función de suma

SELECT SUM(edad) FROM alumno;

13. Función de máximo

SELECT MAX(nota) FROM alumno;


SELECT MAX(nombre) FROM alumno;

14. Función de mínimo

SELECT MIN(nota), MIN(edad) FROM alumno;


SELECT MIN(nota) FROM alumno WHERE nota>7;
15. Nombres de alumnos que empiezan por 'A'

SELECT nombre FROM alumno WHERE nombre LIKE 'A%';

Esta comparación es sensible a minúsculas y mayúsculas. El carácter '%' equivale al


comodín asterisco '*' del DOS: se ignora un número variable de caracteres. El carácter
'_' equivale al comodín '?' del DOS: se ignora un carácter. Para testear la no
presencia de patrones en cadenas se puede utilizar NOT LIKE.

16. Nombres de provincias cuya segunda y tercera letras son 'EV'

SELECT nomprov FROM provincia WHERE nomprov LIKE '_EV%';

Existen muchas más funciones definidas sobre cadenas de caracteres: concatenación de


cadenas, extracción de subcadenas, cálculo de la longitud de una cadena, etc.

17. Copia de tablas

CREATE TABLE alumno2 AS SELECT * FROM alumno;

La tabla final posee la misma estructura lógica, restricciones y contenido.

18. Enlace de tablas

El enlace de la información contenida en dos tablas se realiza a través del mecanismo de


clave ajena. Ejemplo: numero de alumno y nombre de su provincia:

SELECT num, nomprov FROM alumno, provincia WHERE


alumno.codprov = provincia.codprov;

La clausula FROM define por sí misma un producto cartesiano de las tablas que se
especifican detrás de ella. La posterios clásula WHERE se aplica a las filas del producto
cartesiano resultado. Como ejemplo véase el resultado del producto cartesiano de la
primera fila de la tabla de alumnos por todas las filas de la tabla de provincias:

NUM NOMBRE APELLIDOS EDAD ALUMNO.CODPROV NOTA PROVINCIA.CODPROV NOM


PEREZ
4 ANTONIO 22 41 6.5 41 SEVIL
LOPEZ
PEREZ
4 ANTONIO 22 41 6.5 21 HUEL
LOPEZ
PEREZ
4 ANTONIO 22 41 6.5 28 MAD
LOPEZ
PEREZ
4 ANTONIO 22 41 6.5 8 BARC
LOPEZ
PEREZ
4 ANTONIO 22 41 6.5 23 JAEN
LOPEZ

19. Renombramiento
Puede cambiarse el nombre de una columna en la salida de una consulta de la siguiente
manera:

SELECT nombre_columna_1 AS nombre_salida_1,


nombre_columna_2 AS nombre_salida_2, ... FROM ...;

SELECT AVG(nota) AS nota_media FROM alumno;

Combinación de consultas
1. Número de alumnos que han obtenido la máxima nota
SELECT COUNT(*) FROM alumno WHERE nota=(SELECT MAX(nota) FROM alumno);

2. Número de edades distintas para las que existe al menos 1 alumno con dicha
edad

SELECT COUNT(*) FROM (SELECT UNIQUE(edad) FROM alumno);

3. Nombres de provincias para las cuales existen alumnos

SELECT nomprov FROM provincia WHERE codprov IN


(SELECT codprov FROM alumno);

SELECT nomprov FROM provincia WHERE EXISTS


(SELECT * FROM alumno WHERE alumno.codprov = provincia.codprov);

Estas dos sentencias producen el mismo resultado aunque dependiendo de la


implementación quizás no en el mismo orden.

4. Alumnos cuya nota sea menor que todas las notas obtenidas por los alumnos de
20 años

SELECT apellidos, nombre FROM alumno WHERE nota < ALL


(SELECT nota FROM alumno WHERE edad=20);

Hay que tener cuidado con el corportamiento de este tipo de sentencias pues no está
claro qué salida debería obtenerse si, en el ejemplo anterior, no existiera ningún alumno
con 20 años de edad.

El predicado ALL es del tipo conocido como cuantificador y tiene el significado de


"todos". Otros predicados cuantificadores son SOME y ANY, ambos con el significado de
"al menos 1". Estos predicados cuantificadores pueden utilizarse con los comparadores
<, <=, >, >=, etc.

5. Nombre de los alumnos cuya nota sea igual a alguna de las obtenidas por algún
alumno de más de 20 años

SELECT nombre FROM alumno WHERE nota = ANY


(SELECT nota FROM alumno WHERE edad>20);
SELECT nombre FROM alumno WHERE nota IN
(SELECT nota FROM alumno WHERE edad>20);

6. Nombres de provincias para las que existen alumnos con más de 25 años de edad

SELECT nomprov FROM provincia WHERE codprov IN


(SELECT codprov FROM alumno WHERE edad>25);

SELECT nomprov FROM provincia WHERE EXISTS


(SELECT * FROM alumno WHERE alumno.codprov=provincia.codprov AND
edad>25);

Nuevamente puede darse el caso de que la salida producida, aún contenido las mismas
tuplas, estén dispuestas en diferente orden. Es importante observar cómo se realiza el
enlace de información entre las dos tablas a través de su atributo común clave ajena.

7. Operaciones sobre conjuntos

Operación Descripción
UNION Unión de conjuntos (usualmente resultados de salida).
INTERSECT Intersección de conjuntos.
EXCEPT
MINUS Diferencia de conjuntos.

Los conjuntos que participen en este tipo de operaciones han de ser compatibles, esto
es, deben tener el mismo conjunto de atributos o resultados de salida. Estas tres
operaciones eliminan automáticamente los duplicados (se supone que un elemento solo
puede estar una vez en un conjunto). Si se quiere conservar los duplicados debe usarse
el operador ALL. Ejemplos:

SELECT codprov FROM provincia UNION SELECT codprov FROM alumno;


SELECT codprov FROM provincia UNION ALL SELECT CODPROV FROM alumno;
SELECT codprov FROM provincia MINUS SELECT codprov FROM alumno;

Modificación de información (valores de


atributos)
UPDATE alumno SET nota=NULL;
UPDATE alumno SET nombre='BENITA' WHERE nombre='BENITO';
UPDATE alumno SET nota=1+nota WHERE nota <=9;
UPDATE alumno SET nota=5.0 WHERE nota BETWEEN 4.5 AND 5.0;

Borrado de tuplas
DELETE alumno;
DELETE alumno WHERE nota < 5.0;
Una sentencia DELETE solo puede operar sobre una tabla. Si se borran todas las tuplas de
una tabla como resultado de un borrado, ya sea absoluto o condicional, la tabla sigue
definida y existiendo aunque sin contenido.

Consultas agrupadas
1. Nota media de los alumnos de cada provincia
SELECT codprov, AVG(nota) FROM alumno GROUP BY codprov;

CODPROV AVG(NOTA)
---------- ----------
8 4.3
21 8.55
28 5.1
41 5.85

La salida de una consulta se ordena en general por el campo por el que se agrupa, por
defecto. Observar que en el ejemplo no aparecen las provincias para las cuales no hay
alumnos.

2. Nota media de las provincias cuya nota media sea mayor de 5

SELECT codprov, AVG(nota) FROM alumno


GROUP BY codprov HAVING (AVG(nota) > 5);

3. Nota media de las provincias para las que haya más de 1 alumno

SELECT codprov, AVG(nota) FROM alumno


GROUP BY codprov HAVING (COUNT(*) > 1);

4. Nota media, agrupada por edades, de los alumnos de Sevilla

SELECT edad, AVG(nota) FROM alumno WHERE codprov IN


(SELECT codprov FROM provincia WHERE nomprov='SEVILLA')
GROUP BY edad;

Existen importantes diferencias entre las clausulas WHERE y HAVING a pesar de que
ambas permiten especificar condiciones sobre la consulta. La clausula WHERE especifica
una condición que es aplicable a una sola tupla mientras que HAVING indica una
condición que no se aplica a una única tupla sino a cada grupo de tuplas construido por
la clausula GROUP BY. El predicado lógico de HAVING se aplica después de la formación
de grupos mientras que el de WHERE se aplica antes.

Si en una misma consulta aparece una clausula WHERE y otra HAVING se aplica primero el
predicado de la clausula WHERE. Las tuplas que satisfagan dicho predicado lógico se
colocan en grupos según venga indicado por la clausula GROUP BY. Entonces los grupos
que no satisfagan el predicado lógico de HAVING se eliminan. Por último la clausula
SELECT utiliza los grupos resultantes para generar los resultados de salida.

5. Número de alumnos por cada nota


SELECT nota, COUNT(*) FROM alumno GROUP BY nota;

6. Notas medias por provincia con ordenación según la nota

SELECT codprov, AVG(nota) FROM alumno GROUP BY codprov ORDER BY 2;

Donde el '2' referencia al segundo elemento de la lista de selección (en este caso, la
media de las notas).

7. Edad máxima de los alumnos de cada provincia

SELECT codprov, MAX(edad) FROM alumno GROUP BY codprov;

DML.- El Lenguaje de Manipulación de Datos (Data Manipulation Languaje) es o consiste en la forma de recuperar datos
almacenados en una BD. el DML tiene dos perspectivas:

1.- Proposiciones integradas.- Son una serie de instrucciones contenidas en un programa.


2.- Consulta (Query).- Son consultas rápidas a una BD.

Para ambas se requiere un lenguaje de programación. Entonces, el DBMS se convierte en un intermediario entre el
usuario y la BD almacenada, entonces, a través de un programa o una consulta podemos extraer información.

Siendo formales, el DBMS es un elemento de software que espeficica la forma en que los datos pueden estructurarse.
Controla todos los accesos a dichos datos y proporciona algunos otros servicios aplicados a las BD, como seguridad, sistema
de respaldos, etc.

2.4.3. Lenguaje de manipulación de datos (DML – Data


Manipulation Language)
Un D.M.L. es un sublenguaje de consulta y manipulación de datos.

Se entenderá por manipulación de datos la :

• Recuperación de Información.
• Inserción de nueva Información.
• Eliminación (Borrado) de información existente.
• Modificación de Información Almacenada.

2.4.4. Otras características de SQL.


Además de los dos tipos de sublenguajes mencionados anteriormente, SQL
puede ser utilizado para otras características propias que no poseen los
lenguajes formales de consultas, estas son:

• Definición de vistas. El DDL de SQL incluye instrucciones para la


definición de vistas.
• Autorización. El DDL de SQL incluye instrucciones para la
especificación de los derechos de acceso a los objetos de la base de
datos.
• Integridad. El DDL de SQL también incluye un conjunto de sentencias
para la especificación de restricciones de integridad.
• Control de transacciones. SQL incluye ordenes para la especificación
de los estados de una transacción, algunas implementaciones permiten
además el bloqueo explicito de objetos de datos con el fin de manejar
control de concurrencia.

Para los efectos de este trabajo se anexa en el apéndice A una breve


descripción de los sublenguajes de Definición y manipulación de datos.

1. Introducción

SQL (Standar Query Lenguaje) es un lenguaje estandarizado de base de datos, el cual nos
permite realizar tablas y obtener datos de ella de manera muy sencilla. Para exponer mas
claramente los conceptos se realizaran ejemplo sobre relaciones que se crearan aquí para
entender mejor como funciona SQL.
Cuando aquí nos refiramos a relación estamos hablando mas concretamente a la tabla de
datos en si, y sus atributos serán los campos de la tabla. Como ejemplo la siguiente relación
( tabla ) la llamaremos persona y sus atributos ( campos ) son nombre, apellido Y DNI

PERSONA NOMBRE APELLIDO DNI

1 MARTIN MARQUESI 26125988

2 PABLO MARQUESI 25485699

3 ROBERTO SANCHEZ 20566401

4 ESTEFANIA GUISSINI 27128064

5 RUBEN ALEGRATO 24238975

6 SANDRA BRITTE 25483669

7 MELISA ARDUL 27456224

8 SOLEDAD MICHELLI 29889656

9 BETANIA MUSACHEGUI 27128765

10 JUAN SERRAT 28978845

SQL es un lenguaje que consta de varias partes

• Lenguaje de definición de datos ( DDL): Proporciona ordenes para definir esquemas de


relación, eliminar relaciones, crear índices y modificar esquemas de relación.
• Lenguaje de manipulación de datos interactivos (DML): incluye un leguaje de consultas
que permite rescatar datos de las relaciones. También incluye ordenes para insertar,
suprimir y modificar tuplas.
• Lenguaje de manipulación de datos inmerso (DML): La forma inmersa de SQL esta
diseñada para usar dentro de los lenguajes de programación de lenguaje general.
• Definición de vistas (DDL): incluye ordenes para definir vistas.

2. Estructura básica
La estructura básica de una expresión para consulta SQL consta de tres cláusulas:

• SELECT
• FROM
• WHERE

La cláusula SELECT se usa para listar los atributos que se desean en el resultado de una
consulta.
La cláusula FROM lista las relaciones que se van a examinar en la evaluación de la expresión
La cláusula WHERE costa de un predicado que implica atributos de las relaciones que
aparecen en la cláusula FROM.
Una consulta básica en SQL tiene la forma:
SELECT A1,A2,...,An
FROM r1,r2,...,rn
WHERE P
Donde Ai = atributo ( Campo de la tabla )
ri = relación ( Tabla )
P = predicado ( condición )

Ejemplo 2.1 : Seleccionar todos los nombres de las personas que tengan el apellido
MARQUESI de la tabla persona
SELECT nombre
FROM persona
WHERE apellido = " MARQUESI"

ANSWER NOMBRE

1 MARTIN

2 PABLO

El resultado de una consulta es por supuesto otra relación. Si se omite la cláusula WHERE, el
predicado P es verdadero. La lista A1, A2,..., An puede sustituirse por un asterisco (*) para
seleccionar todos los atributos de todas las relaciones que aparecen en la cláusula FROM,
aunque no es conveniente elegir esta ultima opción salvo que sea necesario pues
desperdiciamos mucho tiempo en obtenerlo

Alias
Es posible renombrar los atributos y las relaciones, a veces por conveniencia y otras veces por
ser necesario, para esto usamos la clausula AS como en el siguiente ejemplo.

Ejemplo 2.2
SELECT P.nombre AS [PRIMER NOMBRE]
FROM persona P
WHERE apellido = "MARQUESI"

ANSWER PRIMER NOMBRE

1 MARTIN

2 PABLO

En este ejemplo cabe destacar un par de cosas. Cuando nos referimos a un atributo como es el
caso de nombre, podemos referirnos a este usando la relación ( o el alias en este ejemplo ) a la
que pertenece el atributo seguido de un punto seguido del atributo <P.nombre>, a veces esta
notación será necesaria para eliminar ambigüedades. Los corchetes los usamos cuando
usamos espacios en blancos o el caratér (–) en el nombre de atributo o alias.
Usar alias en los atributos nos permite cambiar el nombre de los atributos de la respuesta a la
consulta.
Cuando asociamos un alias con una relación decimos que creamos una variable de tupla.
Estas variables de tuplas se definen en la cláusula FROM después del nombre de la relación.
En las consultas que contienen subconsultas, se aplica una regla de ámbito a las variables de
tupla. En una subconsulta esta permitido usar solo variables de tupla definidas en la misma
subconsulta o en cualquier consulta que tenga la subconsulta.

3. Predicados y conectores

Los conectores lógicos en SQL son:

• AND
• OR
• NOT

La lógica de estos conectores es igual que en cualquier lenguaje de programación y sirven para
unir predicados.
Las operaciones aritméticas en SQL son:

• + ( Suma )
• - ( Resta )
• * ( Multiplicación )
• / ( División )

También incluye el operador de comparación BETWEEN, que se utiliza para valores


comprendidos
Ejemplo 3.1 : Encontrar todos los nombres y dni de las personas cuyos dni sea mayor que 26
millones y menor a 28 millones
SELECT nombre, dni
FROM persona
WHERE dni BETWEEN 26000000 and 28000000

ANSWER NOMBRE DNI

1 MARTIN 26125988

2 ESTEFANIA 27128064

3 MELISA 27456224

4 BETANIA 27128765

Análogamente podemos usar el operador de comparación NOT BETWEEN.


SQL también incluye un operador de selección para comparaciones de cadena de caracteres.
Los modelos se describen usando los caracteres especiales:

• El carácter ( % ) es igual a cualquier subcadena


• El operador ( _ ) es igual a cualquier carácter

Estos modelos se expresan usando el operador de comparación LIKE. Un error muy frecuente
es tratar de utilizar los modelos mediante el operador de igualdad ( = ) lo cual es un error de
sintaxis.
Ejemplo 3.2 : encontrar los nombres que comiencen con la letra p o el nombre tenga
exactamente 6 caracteres de la relación persona
SELECT nombre
FROM persona
WHERE (nombre LIKE "P%") OR (nombre LIKE "_ _ _ _ _ _")

ANSWER NOMBRE

1 MARTIN

2 PABLO

3 MELISA

4 SANDRA

Análogamente podemos buscar desigualdades usando el operador de comparación NOT LIKE.

4. Tuplas duplicadas

Los lenguajes de consulta formales se basan en la noción matemática de relación como un


conjunto. Por ello nunca aparecen tuplas duplicadas en las relaciones. En la practica la
eliminación de duplicados lleva bastante tiempo. Por lo tanto SQL permite duplicados en las
relaciones. Así pues en las consultas se listaran todas las tuplas inclusive las repetidas.
En aquellos casos en los que queremos forzar la eliminación de duplicados insertamos la
palabra clave DISTINCT después de la cláusula SELECT
Ejemplo 4.1: Listar todos los apellidos no repetidos de la relación persona
SELECT DISTINCT apellido
FROM persona

ASWER APELLIDO

1 MARQUESI

2 SANCHEZ

3 GUISSINI

4 ALEGRATO

5 BRITTE

6 ARDUL

7 MICHELLI

8 MUSACHEGUI

9 SERRAT

Si observamos la tabla original de la relación persona veremos que el apellido marquesi


aparecía dos veces, pero debido al uso de DISTINCT en la consulta la relación respuesta solo
lista un solo marquesi.

Operaciones de conjunto.
SQL incluye las operaciones de conjuntos UNION, INTERSECT, MINUS, que operan sobre
relaciones y corresponden a las operaciones del álgebra unión, intersección y resta de
conjuntos respectivamente. Para realizar esta operación de conjuntos debemos tener sumo
cuidado que las relaciones tengan las mismas estructuras.
Incorporemos ahora una nueva relación, llamada jugadores que representa las personas que
juegan al fútbol, sus atributos serán DNI, puesto y nro_camiseta. Supongamos que esta nueva
tabla esta conformada de la siguiente manera

JUGADORES DNI PUESTO NRO_CAMISETA

1 26125988 DELANTERO 9

2 25485699 MEDIO 5

3 28978845 ARQUERO 1

4 29789854 DEFENSOR 3

Ejemplo 4.2 : Obtener todos los nombres de la relación persona cuyos apellidos sean Marquesi
o Serrat
SELECT nombre
FROM PERSONA
WHERE apellido = "MARQUESI"
UNION
SELECT nombre
FROM PERSONA
WHERE apellido = "SERRAT"

ANSWER PRIMER NOMBRE

1 MARTIN

2 PABLO

3 JUAN

Ejemplo 4.3 : Obtener todos los DNI de los que juegan al fútbol y, además, están en la lista de
la relación persona
SELECT dni
FROM persona
INTERSECT
SELECT dni
FROM jugadores

ANSWER DNI

1 26125988

2 25485699

3 28978845

Por omisión, la operación de union elimina las tuplas duplicadas. Para retener duplicados se
debe escribir UNION ALL en lugar de UNION.

Pertenencia a un conjunto
El conector IN prueba si se es miembro de un conjunto, donde el conjunto es una colección de
valores producidos en lo general por una cláusula SELECT. Análogamente el conector NOT IN
prueba la no pertenencia al conjunto
Ejemplo 4.4 : Encontrar los nombres de las personas que juegan al fútbol y, además, se
encuentran en la relación persona
SELECT nombre, apellido
FROM persona
WHERE dni IN
(SELECT dni
FROM jugadores)

ANSWER NOMBRE APELLIDO

s MARTIN MARQUESI

2 PABLO MARQUESI

3 JUAN SERRAT

Es posible probar la pertenencia de una relación arbitraria SQL usa la notación de elementos
<v1,v2,...,vn> para representar una tupla de elementos de n que contiene los valores
v1,v2,...,vn.

Comparación de conjuntos
En conjuntos la frase << mayor que algún >> se representa en SQL por ( >SOME ), también
podría entenderse esto como << mayor que el menor de >>, su sintaxis es igual que la del
conector IN. SQL también permite las comparaciones ( >SOME ),( =SOME ) ( >=SOME ),
( <=SOME ) y ( <>SOME ).
También existe la construcción ( >ALL ), que corresponde a la frase << mayor que todos >>. Al
igual que el operador SOME, puede escribirse ( >ALL ),( =ALL ) ( >=ALL ), ( <=ALL ) y
( <>ALL ).
En ocasiones podríamos querer comparar conjuntos para determinar si un conjunto contiene
los miembros de algún otro
conjunto. Tales comparaciones se hacen usando las construcciones CONTAINS y NOT
CONTAINS

5. Pruebas para relaciones vacías

La construcción EXISTS devuelve el valor TRUE si la subconsulta del argumento no esta vacía,
y la construcción NOT EXISTS devuelve TRUE si la consulta es vacía.
Ejemplo 5.1 : encontrar todos los nombre y apellidos de la relación persona si es que en la
relación jugadores existe un jugador con el numero de dni 27128055
SELECT nombre, apellido
FROM persona
WHERE EXISTS
(SELECT dni
FROM jugadores
WHERE dni = 27128055 )

ANSWER NOMBRE APELLIDO

Como el dni = 27128055 no existe en la relación jugadores, la condición es FALSE y por lo


tanto la respuesta es vacía

6. Ordenación de la presentación de tuplas

SQL ofrece al usuario cierto control sobre el orden en el que se va a presentar las tuplas en
una relación. La cláusula ORDER BY hace que las tupla en el resultado dé una consulta en un
orden especifico.
Por omisión SQL lista los elementos en orden ascendente. Para especificar el tipo de
ordenación, podemos especificar DESC para orden descendente o ASC para orden
ascendente.
También es posible ordenar los resultados por mas de una atributo
Ejemplo 6.1 : encontrar todos los nombres y apellido de la relación persona y ordenar los
resultados por apellido y nombre en forma descendente
SELECT apellido, nombre
FROM persona
ORDER BY apellido DESC, nombre DESC

ANSWER APELLIDO NOMBRE

1 SERRAT JUAN

2 SANCHEZ ROBERTO

3 MUSACHEGUI BETANIA

4 MICHELLI SOLEDAD

5 MARQUESI PABLO

6 MARQUESI MARTIN

7 GUISSINI ESTEFANIA

8 BRITTE SANDRA

9 ARDUL MELISA

10 ALEGRATO RUBEN

Funciones de agregación
SQL ofrece la posibilidad de calcular funciones en grupos de tuplas usando la cláusula GROUP
BY, también incluye funciones para calcular

• Promedios AVG
• Mínimo MIN
• Máximo MAX
• Total SUM
• Contar COUNT

Para los próximos ejemplos incorporamos una nueva relación llamada PRO que representara
los jugadores profesionales de fútbol, sus atributos serán dni, años_pro, club, valor_actual. Y
los valores son los siguientes:

PRO DNI AÑOS_PRO CLUB VALOR_ACTUAL

1 26125988 5 ALL BOY'S 1000

2 25485699 2 ALL BOY'S 2500

3 27126045 3 LANUS 12000

4 26958644 4 LANUS 6500

5 29120791 1 LANUS 450


Ejemplo 6.2: determinar el valor total en jugadores así como también la cantidad de jugadores
de cada club en la relación pro
SELECT club, SUM(valor_actual) AS VALOR_TOTAL,
COUNT(club) AS NRO_JUGADORES
FROM pro
GROUP BY CLUB

ANSWER CLUB VALOR_TOTAL NRO_JUGADORES

1 ALL BOY'S 3.500,00 2

2 LANUS 18.950,00 3

Ejemplo 6.3: Determinar por cada club cual es el valor_actual del jugador mas caro de la
relación pro

SELECT club, MAX(valor_actual) AS JUG_MAS_CARO


FROM pro
GROUP BY CLUB

ANSWER CLUB JUG_MAS_CARO

1 ALL BOY'S 2500

2 LANUS 12000

Hay ocasiones en la que los duplicados deben eliminarse antes de calcular una agregación.
Cuando queremos eliminar los duplicados del calculo usamos la palabra clave DISTINCT
antepuesto al atributo de agregación que queremos calcular, como por ejemplo
COUNT(DISTINCT club).
Hay ocasiones en las que es útil declara condiciones que se aplican a los grupos mas que a las
tuplas. Para esto usamos la cláusula HAVING de SQL.
Ejemplo 6.4: Determinar por cada club cual es el valor_actual del jugador mas caro, pero con la
condición de que este sea mayor a 10000 de la relación pro
SELECT club, MAX(valor_actual) AS JUG_MAS_CARO
FROM pro
GROUP BY CLUB
HAVING MAX(valor_actual) > 10000

ANSWER CLUB JUG_MAS_CARO

1 LANUS 12000

Si en la misma consulta aparece una cláusula WHERE y una cláusula HAVING, primero se
aplica el predicado de la cláusula WHERE, las tupla que satisfacen el predicado WHERE son
colocadas en grupos por la cláusula GROUP BY. Después se aplica la cláusula HAVING a
cada grupo.

7. Modificación de la base de datos

Eliminación
Una solicitud de eliminación se expresa casi de igual forma que una consulta. Podemos
suprimir solamente tuplas completas, no podemos suprimir valores solo de atributos.
DELETE FROM r
WHERE P
Donde P presenta un predicado y r representa una relación. Las tuplas t en r para las cuales
P(t) es verdadero, son eliminadas
de r.
Si omitimos la cláusula WHERE se eliminan todas las tuplas de la relación r ( un buen sistema
debería buscar confirmación del usuario antes de ejecutar una acción tan devastadora )
Ejemplo 7.1 : Eliminar todas las tuplas de la relación persona en donde apellido sea igual a
"BRITTE"
DELETE FROM persona
WHERE apellido = "BRITTE"

deleted NOMBRE APELLIDO DNI

1 SANDRA BRITTE 25483669

Inserción
Para insertar datos en una relación, especificamos una tupla que se va a insertar o escribimos
una consulta cuyo resultado es un conjunto de tuplas que se van a insertar. La inserción de
tuplas la realizamos mediante las sentencias
INSERT INTO r1
VALUES (v1,v2,...,v)
Ejemplo 7.2 : Insertar una tupla con los mismos valores de la tupla eliminada en el ejemplo
anterior en la relación persona.
INSERT INTO persona
VALUES ("SANDRA","BRITTE",25483669)

inserted NOMBRE APELLIDO DNI

1 SANDRA BRITTE 25483669

En este ejemplo, los valores se especifican en el orden en que se listan los atributos
correspondientes en el esquema de relación. Para poder ingresar los datos en un orden
diferente podríamos haber escrito
INSERT INTO persona(DNI, NOMBRE, APELLIDO)
VALUES (25483669,"SANDRA","BRITTE")

Actualizaciones
En ciertas ocasiones podemos desear cambiar los valores de una tupla sin cambiar todos los
valores en dicha tupla. Para este propósito usamos la sentencia
UPDATE r1
SET A1 = V1, A2 = V2,...,An = Vn
WHERE P
Donde r1 es la relación Ai el atributo a modificar Vi el valor que se le asignara a Ai y P es el
predicado.
Ejemplo 7.3 : En la relación jugadores actualizar la posición de los jugadores que posean la
camiseta numero 5 y asignarles la camiseta numero 7.
UPDATE jugadores
SET nro_camiseta = 7
WHERE nro_camiseta = 5

updated DNI PUESTO NRO_CAMISETA

1 25485699 MEDIO 5

8. Valores nulos
Es posible que para las tuplas insertadas se den valores únicamente a algunos atributos del
esquema. El resto de los atributos son asignados a valores nulos representados por NULL.
Para esto colocamos la palabra reservada NULL como valor del atributo.
Ejemplo 7.4 : Insertar en la relación jugadores un jugador con dni = 26356312, puesto =
defensor, y al cual aun no le han asignado un nro_camiseta.
INSERT INTO jugadores
VALUES(26356312,"DEFENSOR", NULL)

inserted DNI PUESTO NRO_CAMISETA

1 26356312 DEFENSOR

9. Definición de datos

Creación
Una relación en SQL se define usando la orden
CREATE TABLE r(A1 D1, A2 D3,...,An Dn)
Donde r es el nombre de la relación, cada Ai es el nombre de un atributo del esquema de la
relación r y Di es el tipo de dato de Ai. Una relación recién creada esta vacía. La orden INSERT
puede usarse para cargar la relación
Ejemplo 9.1 : crear la relación lesionado con los atributos nombre, apellido ambos de tipo char
y tiempo_inhabilit de tipo entero
CREATE TABLE "lesionado.db" (
NOMBRE CHAR(20),
APELLIDO CHAR(20),
TIEMPO_INHABILT INTEGER)

lesionado NOMBRE APELLIDO TIEMPO_INHABILT

Eliminación
Para eliminar una relación usamos la orden DROP TABLE r, esta orden elimina toda la
información sobre la relación sacada de la base de datos, esta orden es mas fuerte que DELET
FROM r ya que esta ultima elimina todas las tuplas pero no destruye la relación, mientras que
la primera si.
Ejemplo 9.2 : eliminar la relación persona
DROP TABLE persona

Actualizacion
La orden ALTER TABLE se usa para añadir atributos a una relación existente. A todas las
tuplas en la relación se les asigna NULL como valor de atributo. La sintaxis de ALTER TABLE
es la siguiente:
ALTER TABLE r1 ADD A1 D1
Ejemplo 9.3 : agregar los atributos de tipo char nombre y apellido a la relación jugadores
ALTER TABLE jugadores ADD NOMBRE CHAR(20)
ALTER TABLE jugadores ADD APELLIDO CHAR(20)

Lenguajes de cuarta generación

No existe consenso sobre lo que es un lenguaje de cuarta generación (4GL). Lo que en


un lenguaje de tercera generación (3GL) como COBOL requiere cientos de líneas de
código, tan solo necesita diez o veinte líneas en un 4GL. Comparado con un 3GL, que
es procedural, un 4GL es un lenguaje no procedural: el usuario define qué se debe
hacer, no cómo debe hacerse. Los 4GL se apoyan en unas herramientas de mucho más
alto nivel denominadas herramientas de cuarta generación. El usuario no debe definir
los pasos a seguir en un programa para realizar una determinada tarea, tan sólo debe
definir una serie de parámetros que estas herramientas utilizarán para generar un
programa de aplicación. Se dice que los 4GL pueden mejorar la productividad de los
programadores en un factor de 10, aunque se limita el tipo de problemas que pueden
resolver. Los 4GL abarcan:

• Lenguajes de presentación, como lenguajes de consultas y generadores de


informes.
• Lenguajes especializados, como hojas de cálculo y lenguajes de bases de datos.
• Generadores de aplicaciones que definen, insertan, actualizan y obtienen datos
de la base de datos.
• Lenguajes de muy alto nivel que se utilizan para generar el código de la
aplicación.

Los lenguajes SQL y QBE son ejemplos de 4GL. Hay otros tipos de 4GL:

• Un generador de formularios es una herramienta interactiva que permite crear


rápidamente formularios de pantalla para introducir o visualizar datos. Los
generadores de formularios permiten que el usuario defina el aspecto de la
pantalla, qué información se debe visualizar y en qué lugar de la pantalla debe
visualizarse. Algunos generadores de formularios permiten la creación de
atributos derivados utilizando operadores aritméticos y también permiten
especificar controles para la validación de los datos de entrada.
• Un generador de informes es una herramienta para crear informes a partir de los
datos almacenados en la base de datos. Se parece a un lenguaje de consultas en
que permite al usuario hacer preguntas sobre la base de datos y obtener
información de ella para un informe. Sin embargo, en el generador de informes
se tiene un mayor control sobre el aspecto de la salida. Se puede dejar que el
generador determine automáticamente el aspecto de la salida o se puede diseñar
ésta para que tenga el aspecto que desee el usuario final.
• Un generador de gráficos es una herramienta para obtener datos de la base de
datos y visualizarlos en un gráfico mostrando tendencias y relaciones entre
datos. Normalmente se pueden diseñar distintos tipos de gráficos: barras, líneas,
etc.
• Un generador de aplicaciones es una herramienta para crear programas que
hagan de interface entre el usuario y la base de datos. El uso de un generador de
aplicaciones puede reducir el tiempo que se necesita para diseñar un programa
de aplicación. Los generadores de aplicaciones constan de procedimientos que
realizan las funciones fundamentales que se utilizan en la mayoría de los
programas. Estos procedimientos están escritos en un lenguaje de programación
de alto nivel y forman una librería de funciones entre las que escoger. El usuario
especifica qué debe hacer el programa y el generador de aplicaciones es quien
determina cómo realizar la tarea.
Lenguaje de manejo de datos

Una vez creados los esquemas de la base de datos, los usuarios necesitan un lenguaje
que les permita manipular los datos de la base de datos: realizar consultas, inserciones,
eliminaciones y modificaciones. Este lenguaje es el que se denomina lenguaje de
manejo de datos (LMD).

Hay dos tipos de LMD: los procedurales y los no procedurales. Con un LMD
procedural el usuario (normalmente será un programador) especifica qué datos se
necesitan y cómo hay que obtenerlos. Esto quiere decir que el usuario debe especificar
todas las operaciones de acceso a datos llamando a los procedimientos necesarios para
obtener la información requerida. Estos lenguajes acceden a un registro, lo procesan y
basándose en los resultados obtenidos, acceden a otro registro, que también deben
procesar. Así se va accediendo a registros y se van procesando hasta que se obtienen los
datos deseados. Las sentencias de un LMD procedural deben estar embebidas en un
lenguaje de alto nivel, ya que se necesitan sus estructuras (bucles, condicionales, etc.)
para obtener y procesar cada registro individual. A este lenguaje se le denomina
lenguaje anfitrión. Las bases de datos jerárquicas y de red utilizan LMD procedurales.

Un LMD no procedural se puede utilizar de manera independiente para especificar


operaciones complejas sobre la base de datos de forma concisa. En muchos SGBD se
pueden introducir interactivamente instrucciones del LMD desde un terminal o bien
embeberlas en un lenguaje de programación de alto nivel. Los LMD no procedurales
permiten especificar los datos a obtener en una consulta o los datos que se deben
actualizar, mediante una sola y sencilla sentencia. El usuario o programador especifica
qué datos quiere obtener sin decir cómo se debe acceder a ellos. El SGBD traduce las
sentencias del LMD en uno o varios procedimientos que manipulan los conjuntos de
registros necesarios. Esto libera al usuario de tener que conocer cuál es la estructura
física de los datos y qué algoritmos se deben utilizar para acceder a ellos. A los LMD no
procedurales también se les denomina declarativos. Las bases de datos relacionales
utilizan LMD no procedurales, como SQL (Structured Query Language) o QBE (Query-
By-Example). Los lenguajes no procedurales son más fáciles de aprender y de usar que
los procedurales, y el usuario debe realizar menos trabajo, siendo el SGBD quien hace
la mayor parte.

La parte de los LMD no procedurales que realiza la obtención de datos es lo que se


denomina un lenguaje de consultas. En general, las órdenes tanto de obtención como de
actualización de datos de un LMD no procedural se pueden utilizar interactivamente,
por lo que al conjunto completo de sentencias del LMD se le denomina lenguaje de
consultas, aunque es técnicamente incorrecto.

Introducción a SQL
Definición
SQL es un descendiente de SEQUEL (o Structured English QUEry Language), que fue
originalmente diseñado por IBM. SQL fue creado como un lenguaje para construir sistemas
de administración de base de datos relacionales (RDBMS: Relational DataBase Management
System) sobre cualquier plataforma de hardware. El primer RDBMS comercial usando el SQL
que apareció en 1981, y SQL es ahora el lenguaje estandar para consultas de red a través de
plataformas de software y hardware diferentes. SQL es realmente un sublenguaje diseñado
para estar embebido en un lenguaje de programación de una aplicación. Es tan flexible que
puede ser usado tanto para manipulación de datos como para definición de datos.

Los servidores de bases de datos SQL manejan peticiones en unidades lógicas de trabajo
llamadas transacciones. Una transacción es un grupo de operaciones relacionados que deben
todas ser realizadas con éxito antes de que el RDBMS finalice cualquier cambio en la base de
datos. En SQL, todas las transacciones pueden ser terminadas explícitamente con un
comando (instrucción) ya sea aceptar o descartar los cambios. Una vez usted esté satisfecho
de que no hay errores ocurridos durante la transacción, puede terminar esa transacción con
una instrucción de COMMIT. La base de datos entonces cambia para reflejar las operaciones
que usted ha realizado. Si ocurre un error, usted puede abandonar los cambios con una
intrucción de ROLLBACK.

El servidor de base de datos


Una red de área local (LAN: local area network) permite que los usuarios de estaciones de
trabajo compartan archivos, software, y recursos de impresora guardado en el máquinas
dedicadas llamadas servidores. Si su estación de trabajo necesita acceso a datos guardados
en el disco duro del servidor hace una petición de esos datos del servidor. El servidor envía
los datos solicitados a través de la red de vuelta a su estación de trabajo donde son
procesados localmente. Sin embargo, una gran diferencia del servidor de red con la estación
de trabajo es que los datos del servidor pueden ser accesados por más de un usuario al
mismo tiempo.

Pruesto que el procesamiento es realizado en el servidor y no en la estación de trabajo que


originó la petición, la estación de trabajo se vuelve un cliente del servidor de base de datos.
En un sistema Cliente/Servidor, múltiples clientes (usuarios) hacen peticiones de servicios
del servidor de bases de datos a través del uso de aplicaciones clientes creadas con Paradox
para Windows, Visual dBASE, Delphi, o Borland C++.

El modelo relacional
El modelo relacional de datos está basado en una colección de tablas. El usuario del sistema
de base de datos puede consultar estas tablas, insertar nuevas tuplas, eliminar tuplas y
actualizar tuplas. Existen varios lenguajes para expresar estas operaciones. El álgebra
relacional es un lenguaje procedimental que es equivalente en capacidad a las dos formas
del cálculo relacional cuando están restringidas a expresiones seguras.

Convenciones de nombre (Naming conventions)


Esta sección describe las convenciones de nombre para tablas y columnas, mejoras de
sintaxis, y limitaciones de sintaxis para SQL.

El SQL estandar de ANSI (ANSI-standard SQL) confina cada nombre de tabla o columna a
una palabra simple formada de caracteres alfanuméricos y el símbolo de underscore (_).

El SQL tiene varias partes:

+ Lenguaje de definición de datos. (DDL) El SQL DDL o de definición de datos


proporciona órdenes para definir esquemas de relación, eliminar relaciones, crear
índices y modificar esquemas de relación, se pueden crear y alterar tablas.

+ Lenguaje de manipulación de datos interactivo. El SQL DML o de


Manipulación de datos incluye un lenguaje de consultas basado en el álgebra
relacional y el cálculo relacional de tuplas. Permite seleccionar, insertar, actualizar o
borrar datos.
+ Lenguaje de manipulación de datos inmerso (DML) La forma inmersa de SQL
está diseñada para usar dentro de los lenguajes de programación.

+ Definición de vista. El SQL DDL incluye órdenes para definir vistas.

+ Control de transacciones. SQL incluye órdenes para especificar el comienzo y


final de las transacciones. Varias implementaciones, incluyendo IBM SAA-SQL,
permiten el bloque explícito de los datos para control de concurrencia.

Estructura básica
La estructura básica de una expresión en SQL consta de tres cláusulas: SELECT, FROM y
WHERE.

SELECT
SELECT es usado para recuperar filas de una o más tablas. lista_columnas indica cuales
columnas quiere recuperar.

SELECT [DISTINCT] lista_columnas

FROM referencias_tablas

[WHERE condicion_búsqueda]

[GROUP BY group_list]

[HAVING having_condition]

[ORDER BY order_list]

[LIMIT [offset,] rows ]

[PROCEDURE procedure_name]

[UNION select_expr]

Todas las palabras usadas deben ser dadas en el orden mostrado abajo, por ejemplo una
clausula HAVING debe venir luego de una GROUP BY y antes de una ORDER BY.

• A una expresión SELECT se le puede pasar un alias usando AS. El alias es usado
como el nombre de la columna y puede ser usado con ORDER BY y HAVING. Por
ejemplo:
o select concat(last_name,', ',first_name) AS full_name from mytable
ORDER BY full_name;
• La cláusula FROM referencias_tablas indica las tablas de las cuales recuperar filas. Si
hay más de una tabla usted está realizando un "join".
• Usted se puede referir al nombre de una columna como

+ La cláusula SELECT corresponde a la operación de proyección del álgebra


relacional. Se usa para listar los valores guardados en la base de datos señalados por
la consulta.

+ La cláusula FROM corresponde a la operación de producto cartesiano de álgebra


relacional. Dice de cual tabla de la base de datos se va a tomar registros en la
consulta.
+ La cláusula WHERE corresponde al predicado de selección del álgebra relacional.
Permite definir condiciones que limitan aún más la consulta.

La instrucción SELECT es usada para recuperar datos de una o más tablas.

Para recuperar todos los datos de una tabla (tabla1) usaríamos la siguiente sentencia:

SELECT * FROM tabla1

Esta sentencia usa * para denotar que se incluyan todos los campos. Select indica la acción,
y FROM de cual tabla se van a tomar los datos.

Ahora si yo quisiera que el resultado solo trajera algunos campos (no todos) debería crear la
sentencia de la siguiente forma:

SELECT nombre, apellido FROM tabla1

Así solo los campos nombre y apellido vendrán incluidos en el resultado.

Existen otros parámetros que son opcionales y dependen de cada caso: WHERE, que
establece una condición; ORDER BY que permite hacer una ordenacion del resultado; GROUP
BY que permite hacer una agrupación de los resultados; HAVING que permite incluir otra
condición; y UNION que permite hacer uniones con otros resultados.

Un SELECT que recupera datos de múltiples tablas es llamado un "join." La plantilla para el
comando SELECT es la siguiente:

Una consulta típica en SQL tiene la forma:

SELECT A1, A2, A3,... An FROM r1, r2, .... rm WHERE P


Donde A1, A2, A3... son atributos, r1, r2,.. son relaciones, y P es un predicado.

Si se omite la cláusula WHERE el predicado P es verdadero. La lista de atributos puede


sustituirse por un asterisco para seleccionar todos los atributos de todas las relaciones que
aparecen la cláusula FROM.

SQL forma el producto cartesiano de las relaciones nombradas en la cláusula FROM, realiza
una selección del álgebra relacional usando el predicado de la cláusula WHERE y después
proyecta el resultado a los atributos de la cláusula SELECT.

El resultado de una consulta SQL es, por supuesto, una relación. Consideremos una consulta
sencilla usando el ejemplo bancario. "Encontrar los nombres de las sucursales en la relación
depósito".:

SELECT nombre_sucursal FROM depósito


SQL soporta especificaciones de path y archivo totales para los nombres de las tablas. Los
nombres de las tablas con path o extensiones de nombre de archivo deben ser encerradas en
comillas simples o dobles. Por ejemplo,
SELECT * FROM 'PARTS.DBF'

SELECT * FROM "C:\SAMPLE\PARTS.DBF"

SQL también soporta los alias de BDE para nombres de Tabla. Por ejemplo,
SELECT * FROM ":PDOX:TABLE1"
Si usted omite la extensión de archivo para un nombre de una tabla local, se asume que la
tabla es del tipo especificado por la Utilidad de Configuración BDE, ya sea en la configuración
del Defadirt Driver en la página del sistema o en tipo de drive por defecto para los alias
estandar asociados con la consulta o con la tabla.
Finalmente, el SQL permite que los nombres de las tablas dupliquen las palabras clave de
SQL siempre que esos nombres de tablas estén encerrados por comillas sencillas o dobles.
Por ejemplo,

SELECT PASSID FROM "PASSWORD"

Operaciones de conjuntos y tuplas duplicadas


Los lenguajes de consulta formales se basan en la noción matemática de relación como un
conjunto. Por ello nunca aparecen tuplas duplicadas en las relaciones. En la práctica, la
eliminación de duplicados lleva bastante tiempo. Por tanto, SQL ( y casi todos los demás
lenguajes de consulta comerciales) permiten duplicados en las relaciones. Así pues la
consulta que veíamos con SELECT Y FROM muestra el nombre de sucursal por cada vez que
aparezca en depósito.

En aquellos casos en los que queremos forzar la eliminación de duplicados, insertamos la


palabra clave DISTINCT después de SELECT. Un ejemplo de una consulta así sería:

SELECT DISTINCT nombre-sucursal FROM depósito

Columnas
El SQL soporta nombres de columnas multi-palabra de Paradox y nombres de columna con
las palabras clave de SQL duplicadas siempre que se encierren en comillas simples o dobles.

Por ejemplo, el siguiente nombre de la columna son dos palabras:

SELECT E."Emp Id" FROM EMPLOYEE E

En el siguiente ejemplo, el nombre de la columna DATE coincide con una palabra clave del
SQL, por ello se especifica el nombre de la relación:

SELECT DATELOG."DATE" FROM DATELOG

Cuando son dos columnas:

SELECT PART_NO, PART_NAME FROM PARTS


Con los siguientes tópicos obtendrá más información acerca del uso de SELECT:
Cláusula FROM

La cláusula FROM especifica la tabla o tablas de las cuales se van a recuperar datos.
Table_reference puede ser una tabla simple, una lista de tablas delimitada por
comas, o puede ser un join interno o externo como se especifica en el estandar SQL-
92. Por ejemplo, la siguiente instrucción especifica una tabla simple:

SELECT PART_NO

FROM "PARTS.DBF"

La siguiente instrucción especifica un join externo para table_reference:

SELECT * FROM PARTS LEFT OUTER JOIN INVENTORY

ON PARTS.PART_NO = INVENTORY.PART_NO
Operaciones de conjuntos
SQL incluye las operacines UNION, INTERSECT, y MINUS, que operan sobre relaciones y
corresponden a las operaciones del álgebra de conjuntos.

Vamos a demostrar cómo se pueden escribir en SQL las consultas de los siguientes
ejemplos:

"Encontrar todos los clientes que tienen una cuenta en la sucursal Perryridge:

SELECT DISTINCT nombre-cliente

FROM depósito

WHERE nombre-sucursal = "Perryridge"

"Encontrar todos los clientes que tiene un préstamos en la sucursal Perryridge":


SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge"

"Encontrar todos los clientes que tiene un préstamo, una cuenta o las dos en la sucursal de
Perryridge":
(SELECT nombre-cliente

FROM depósito

WHERE nombre-sucursal = "Perryridge")

UNION

(SELECT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge")

"Encontrar todos los clientes que tienen un préstamo y una cuenta en la sucursal
Perryridge":
(SELECT DISTINCT nombre-cliente

FROM depósito

WHERE nombre-sucursal = "Perryridge")

INTERSECT

(SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge")

Por omisión, la operación unión elimina todas las tuplas duplicadas.


"Encontrar los clientes de la sucursal Perryridge que tienen una cuenta allí pero no un
préstamo"

(SELECT DISTINCT nombre-cliente

FROM depósito

WHERE nombre-sucursal = "Perryridge")

MINUS

(SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge")

Cláusula WHERE
La cláusula WHERE opcional reduce el número de filas devuelto por una consulta a
aquellos que cumplen con el criterio especificado en search_condition. Por ejemplo,
la siguiente instrucción recupera sólo aquellas filas con PART_NO mayor a 543:

SELECT * FROM PARTS

WHERE PART_NO > 543

La cláusula WHERE puede incluir el predicado IN, seguido por una lista parentizada
de valores. Por ejemplo, la siguiente instrucción recupera sólo aquellas filas donde el
número de parte se acopla a un item en la lista del predicado IN:

SELECT * FROM PARTS

WHERE PART_NO IN (543, 544, 546, 547)

Adicionalmente a operaciones de comparación escalares ( =, <, > ... ) también se


pueden usar predicados adicionales que usan IN, ANY, ALL, EXISTS.

INSERT
En SQL, INSERT es de dos formas:

INSERT INTO CUSTOMER (FIRST_NAME, LAST_NAME, PHONE)

VALUES(:fname, :lname, :phone_no)

La insersión de una tabla a otra a través de una subconsulta no es permitida.

Ejemplos:

La siguiente instrucción añade una fila a una tabla, asignando valores a dos comlumnas:

INSERT INTO EMPLOYEE_PROJECT (EMP_NO, PROJ_ID)

VALUES (52, "DGPII");


La siguiente instrucción especifica valores para insertar dentro de una tabla con una
instrucción de SELECT:

INSERT INTO PROJECTS

SELECT * FROM NEW_PROJECTS

WHERE NEW_PROJECTS.START_DATE > "6-JUN-1994";

UPDATE
No hay restricciones o extensiones de la instrucción UPDATE del ANSI-estandar.

DELETE
No hay restricciones o extensiones para la instrucción DELETE Ansi-estandar.

Predicados y Conectores
Para encontrar el nombre y la ciudad de todos los clientes que tienen un préstamo en alguna
sucursal. En SQL se podría escribir así:

SELECT DISTINCT cliente.nombre-cliente, ciudad-cliente

FROM préstamo, cliente

WHERE préstamo.nombre-cliente = cliente.nombre-cliente

Obsérvese que SQL usa la notación nombre-relación.nombre-atributo, con el álgebra


relacional, para evitar ambiguedad en los casos en los que un atributo aparece en el esquma
de más de una relación. Podíamos haber escrito cliente.ciudad-cliente en ves de ciudad-
cliente en el SELECT. Sin embargo, puesto que el atributo ciudad-cliente aparece solamente
en una de las relaciones que se nombran en la cláusula FROM, no hay ambiguedad al escribir
ciudad-cliente.

Ampliemos la consulta anterior y consideremos un caso algo más complicado en el que se


requiere tamibén que todos los clientes tengan un préstamo en la sucursal Perryridge:
"Encontrar el nombre y la ciudad de todos los clientes que tienen un préstamo en la sucursal
Perryridge" Para eso vamos a usar un AND.

SELECT DISTINCT cliente.nombre-cliente, ciudad-cliente

FROM préstamo, cliente

WHERE préstamo.nombre-cliente=cliente.nombre-cliente

AND nombre-sucursal = "Perryridge"

SQL usa los conectores lógicos AND, NOT y OR.

SQL incluye un operador de comparacion BETWEEN para simplificar la cláusula WHERE. Si


queremos encontrar el número de cuentas con saldos entre 90.000 y 100.000 dólares
podemos usa la comparación siguiente:

SELECT número-cuenta
FROM depósito

WHERE saldo BETWEEN 90000 AND 100000

Lo mismo se puede hacer con el operador NOT BETWEEN.

SQL también incluye un operador de selección para comparaciones de cadenas de


caracteres. Los modelos se describen usando estas dos características especiales:

+ porcentaje (%) que es igual a cualquier subcadena.

+ subrayado _. El Carácter _ es igual a cualquier caracter.

Ejemplos:

+ "Perry%" es igual a cualquier subcadena que empiece por Perry.

+ "%idge%" es igual a cualquier cadena que contenga "idge" como subcadena.,

+ "___" es igual a cualquier cadena de 3 caracteres.

Los modelos de comparación en SQL se expresan usando el operadir LIKE. "Encontrar los
nombres de todos los clientes cuya calle incluye la subcadena 'Main'":

SELECT nombre-cliente

FROM cliente

WHERE calle LIKE "%Main%"

Hay también caracteres de escape para indicar que se va a incluir un caracter especial dentro
de la cadena de búsqueda, con la cláusula ESCAPE

+ LIKE "ab\%cd%" ESCAPE "\" es igual a todas las cadenas que empiezan por "ab%cd".

Pertenencia a un conjunto
SQL se basa en un conjunto relacional de operaciones que permiten probar la pertenencia de
las tuplas a una relación. El conector IN prueba si se es miembro de un conjunto, donde el
conjunto es una colección de valores porducidos por una cláusula SELECT. El conecto NOT IN
prueba la no pertenencia al conjunto. Para ilustrarlo, considérese de nuevo la consulta
"Encontrar a todos los clientes que tienen un préstamo y una cuenta en el Perryridge".
Vamos a hacer esto realizando una subconsulta.

SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal= "Perryridge" AND

nombre-cliente IN

(SELECT nombre-cliente

FROM depósito
WHERE nombre-sucursal = "Perryridge")

En SQL pueden haber varias consultas que significan lo mismo. Por ejemplo para encontrar
los clientes que tienen una cuenta y un préstamo en al sucursal de Perryridge:
SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge" AND

<nombre-sucursal, nombre-cliente> IN

(SELECT nombre-sucursal, nombre-cliente

FROM depósito)

Para el uso de NOT IN tenemos el siguiente ejemplo. Vamos a buscar los clientes que tienen
una cuenta en la sucursal Perryridge pero no tienen un préstamos en la sucursal Perryridge:
SELECT DISTINCT nombre-cliente

FROM depósito

WHERE nombre-sucursal ="Perryridge" AND

nombre-cliente NOT IN

(SELECT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge")

Variables de Tupla
SQL toma prestada la notación de variables de tupla dell cálcdiro relacional de tuplas. Una
variable de tupla en SQL debe estar asociada con una relación determinada. Las variables de
tupla se definen en la cláusula FROM. Para ilustrarlo, volvemos a escribir la consulta:
"Encontrar el nombre y la ciudad de todos los clientes que tienen un préstamo en alguna
sucursal", así:

SELECT DISTINCT T.nombre-cliente, ciudad cliente

FROM préstamo S, cliente T

WHERE S.nombre-cliente = T.nombre-cliente

Nótese q ue una variable de tupla se define en la cláusula FROM colocándola después del
nombre de la relación con la cual está asociada, separada por uno o más espacios.

En consultas que contienen subconsultas, se aplica una regla de ámbito a las variables de
tupla. En una subconsulta, está permitido usar sólo variables de tupla definidas en la misma
subconsulta o en cualquier consulta que contenga la subconsulta. Si una variable de tupla
está definida tanto localmente en una subconsulta como globalmente en una consulta que la
contiene, se aplica la definición local. Cuando escribimos expresiones de la forma nombre-
relación.nombre-atributo, el nombre de la relación es, en efecto, una variable de tupla
definida implícitamente.
Las variables de tuplas son muy útiles para comparar dos tuplas de la misma relación. En
tales casos el álgebra relacional usa la operación renombrar. Supóngase que queremos
encontrar todos los clientes que tienen una cuenta en la misma sucursal en la que Jones
tiene una cuenta. Escribimos esta consulta:

SELECT DISTINCT T.nombre-cliente

FROM depósito S, depósito T

WHERE S.nombre-cliente = "Jones" AND

S.nombre-sucursal = T.nombre-sucursal

Obsérvese que no podríamos usar la notación depósito.nombre-sucursal, puesto que no


estaría claro cuál es la referencia a depósito que se quiere hacer.
SELECT DISTINCT nombre-cliente FROM depósito

WHERE nombre-sucursal IN

(SELECT nombre-cliente FROM depósito

WHERE nombre-cliente = "Jones")

Comparación de conjuntos
Fue posible utilizar la construcción IN en la consulta anterior porque estuvimos probando la
igualdad entre dos nombres de sucursales. Considérese la consulta: "Encontrar los nombres
de todas las sucursales que tienen un activo mayor que alguna sucursal situada en
Brooklyn". Podemos escribir la expresión:

SELECT DISTINCT nombre-cliente

FROM sucursal T, sucursal S

WHERE T.activo > S.activo AND

S.ciudad-sucursal = "Brooklyn"

Hay otra forma adicional que ofrece SQL para escribir este tipo de consultas con la frase
"mayor que algún" >SOME.
SELECT nombre-sucursal FROM sucursal

WHERE activo > SOME

(SELECT activo

FROM sucursal

where ciudad-sucursal = "Brooklyn")

Las construcciones IN, > SOME, > ALL nos permiten probar un único valor con los miembros
del conjunto completo. Puesto que SELECT genera un conjunto de tuplas, a veces podemos
querer comparar conjuntos para determinar si un conjunto contiene todos los miembros de
algún otro conjunto. Tales comparaciones se hacen en SQL usando las construcciones
CONTAINS y NOT CONTAINS.
Considérese la consulta "Encontrar todos los clientes que tiene una cuenta en todas las
sucursales situadas en Brooklyn". Para cada cliente, necesitamos ver si el conjunto de todas
las sucursales en las que el cliente tiene una cuenta contiene el conjunto de todas las
sucursales de Brooklyn.

SELECT DISTINCT S.nombre-cliente

FROM depósito S

WHERE (SELECT T.nombre-sucursal

FROM depósito T

WHERE S.nombre-cliente = T.nombre-cliente)

CONTAINS

(SELECT nombre-sucursal FROM sucursal

WHERE ciudad-sucursal = "Brooklyn")

CONTAINS no forma parte del SQL ANSI estándar.

Prueba de relaciones vacías


SQL incluye una característica para probar si una subconsulta tiene alguna tupla en su
resultado. La construcción EXISTS devuelve el valor de verdadero si la subconsulta del
argumento no está vacía. usando la construcción EXISTS, podemos escribir la consulta
"Encontrar a todos los clientes que tienen una cuenta y un préstamo en la sucursal
Perryridge".

SELECT nombre-cliente FROM CLIENTE

WHERE EXISTS( SELECT * FROM depósito

WHERE depósito.nombre-cliente =

cliente.nombre-cliente AND

nombre-sucursal = "Perryridge")

AND EXISTS (SELECT * FROM préstamo

WHERE préstamo.nombre-cliente=

cliente.nombre-cliente

AND nombre-sucursal= "Perryridge")

Como ejemplo final, considérese la consulta "Encontrar a todos los clientes que tienen una
cuenta en todas las sucursales situadas en Brooklyn". Para cada cliente, necesitamos ver si
el conjunto de todas las sucursales de Brooklyn. Usando la construcción MINUS, podemos
escribir la siguiente consulta.
SELECT DISTINCT S.nombre-cliente FROM depósito S

WHERE NOT EXISTS ((SELECT nombre-sucursal FROM sucursal


WHERE ciudad-sucursal = "Brooklyn")

MINUS

(SELECT T.nombre-sucursal

FROM depósito T

WHERE

S.nombre-cliente=T.nombre-cliente))

Ordenación de la presentación de las tuplas


La cláusula ORDER BY especifica el orden de las filas recuperadas. Por ejemplo, la siguiente
consulta recupera una lista de todas las partes listadas en orden alfabético por nombre de
parte:

SELECT * FROM partes

ORDER BY nombre-parte ASC

La siguiente consulta recupera toda la información de partes ordenada en sentido


descendento por número de parte:
SELECT * FROM PARTS

ORDER BY PART_NO DESC

Si queremos listar en orden alfabético todos los clientes que tienen una cuenta en Perryridge
SELECT DISTINCT nombre-cliente

FROM préstamo

WHERE nombre-sucursal = "Perryridge"

ORDER BY nombre-cliente

Supóngase que queremos listar la relación préstamo completa en orden descendente de


cantidad. Si varios préstamos tienen la misma cantidad, los ordenamos en orden ascendente
por número de préstamo.
SELECT *

FROM préstamo

ORDER BY cantidad DESC, número-préstamo ASC

Los campos calcdirados pueden ser ordenados por nombre de correlación o posición ordinal.
Por ejemplo, la siguiente consulta ordena las filas por FdirL_NAME, un campo calcdirado:
SELECT apellido || ', ' || primer-nombre

AS nombre-completo, teléfono

FROM clientes

ORDER BY nombre-completo ASC

No se requiere proyección de todos los agrupamientos u ordenamiento de columnas.


Funciones de agregación
SQL ofrece la posibilidad de calcdirar funciones en grupos de tuplas usando la cláusula
GROUP BY. El atributo o atributos dados en la cláusula GROUP BY se usan para formar
grupos. Las tuplas con el mismo valor en todos los atributos en la cláusula GROUP BY se
coloca en un grupo. SQL incluye también funciones de agregación:

SUM(), para totalizar valores numéricos en una columna

AVG(), para promediar todos los valores numéricos no Ndiros en una columna

MIN(), para determinar el valor mínimo en una columna

MAX(), para determinar el valor máximo en una columna

COUNT(), para contar el número de valores en una columan que cumplen con el
criterio especificado

Las operaciones como AVG se llaman funciones de agregación porque operan sobre grupos
de tuplas. El resultado de una función de agregación es un valor único. Para ilustrarlo
considérese la consulta " Encontrar el saldo promedio de las cuentas en todas las
sucursales".
SELECT nombre-sucursal, AVG(saldo)

FROM depósito

GROUP BY nombre-sucursal

La retención de duplicados es importante para calcdirar un promedio.

Se usa la cláusula DISTINCT por ejemplo en la siguiente consulta: "Encontrar el número de


clientes con depósitos para cada sucursal"

SELECT nombre-sucursal, COUNT (DISTINCT, nombre-cliente)

FROM depósito

GROUP BY nombre-sucursal

cláusula HAVING

La cláusula HAVING especifica condiciones que los registros deben cumplir para ser incluidos
en el retorno de una consulta. Es una expresión condicional usada junto con la cláusula
GROUP BY. Los Grupos que no cumplan con la expresión en la cláusula HAVING son omitidos
del conjunto resultado.

Las subconsultas son soportadas en la cláusula HAVING. Una subconsulta trabaja como una
condición de búsqueda para restringir el número de filas devueltas por la consulta externa, o
"padre". Vea la cláusula WHERE adicionalmente a los operadores de comparación escalar
( =, <, > ... ) se pueden usar predicados adicionales usando IN, ANY, ALL, EXISTS.

A veces es útil declarar una condición que se aplica a los grupos más que a las tuplas. Por
ejemplo, podríamos estar interesados únicamente en sucursales en las que el saldo promedio
de las cuentas es mayor a 1200 dólares. Esta condición no se aplica a una única tupla.

Más bien se aplica a cada grupo construido mediante la cláusula GROUP BY. Para expresar
una consulta de este tipo, usamo sl a cláusula HAVING. Los predicados de la cláusula
HAVING se aplican después de la formación de grupos, por lo que pueden utilizarse funciones
dke agregación.

SELECT nombre-sucursal, AVG (saldo)

FROM depósito

GROUP BY nombre-sucursal

HAVING AVG(saldo) > 1200

Veamos el siguiente caso "Encontrar aquellas sucursales con el saldo promedio mayor". Las
funciones de agregados no pueden componerse en SQL. Significa que cualquier intento de
utilizar MAX(AVG(... no estará permitida. En cambio, nuestra estrategia es encontrar
aquellas sucursales para las que el balance promedio es mayor o igual que todos los
balances promedio.
SELECT nombre-sucursal FROM depósito

GROUP BY nombre-sucursal

HAVING

AVG(saldo) >= ALL (SELECT AVG(saldo) FROM depósito

GROUP BY (nombre-sucursal)))

La función de agregación COUNT se usa frecuentemente para contar el número de tuplas en


una relación. La relación para esto en SQL es COUNT (*). Así, para encontrar el número de
tuplas en la relación cliente, escribimos
SELECT COUNT (*)

FROM cliente

SELECT COUNT (persona)


cláusula UNION

La cláusula UNION combina los resultados de dos o más instrucciones SELECT para
producir una tabla simple.

Joins heterogéneos

El SQL soporta uniones o joins de tablas en diferentes formatos de bases de datos;


tal como un join es llamado un "join heterogéneo". Cuando usted realiza un join
heterogéneo, usted puede seleccionar un alias local.. Para seleccionar un alias,
escoja SQL|Select Alias. Si usted no ha seleccionado un alias, SQL intentará
encontrar la tabla en el directorio actual de la base de datos que está siendo usado.
Por ejemplo, el alias :WORK: podría ser el handle de base de datos pasado dentro de
la función. Cuando usted especifica una tabla luego de selecciona un alias local:

Para tablas locales, especifique el alias o el path. para tablas remotas, especifique el
alias.

Las siguientes instrucciones recuperan datos de una tabla de Paradox y una tabla de
dBase:

SELECT DISTINCT C.CUST_NO, C.STATE, O.ORDER_NO

FROM "CUSTOMER.DB" C, "ORDER.DBF" O


WHERE C.CUST_NO = O.CUST_NO

Usted también puede usar alias BDE junto con los nombres de las tablas.

Las siguientes secciones describen funciones disponibles para instrucciones DML en SQL.

Las substituciones de parámetros en instrucciones DML

Funciones agregadas

Funciones de String

Función DATE

Operadores

consultas Actualizables

Substitución de parámetros en instrucciones DML


Los marcadores de variables o parámetros (?) pueden ser usados en instrucciones DML en
lugar de los valores. Las variables deben siempre estar precedidas por dos puntos (:), por
ejemplo:

SELECT apellido, primer-nombre FROM "CUSTOMER.DB"

WHERE apellido > :var1 AND primer-nombre < :var2

Funciones de agregación
Se incluyen también expresiones agregadas complejas, tal como:

SUM( Field * 10 )

SUM( Field ) * 10

SUM( Field1 + Field2 )

Funciones de String
El SQL soporta las siguientes funciones de manipdiración de cadenas del SQL ANSI-standard
para recuperación, insersión y actualización:

UPPER(), para forzar una cadena a estar en mayúscdiras

LOWER(), para forzar una cadena a estar en minúscdiras

TRIM(), para quitar repeticiones de un caracter especificado desde la izquierda,


derecha o a ambos lados de una cadena

SUBSTRING() para crear una subcadena de una cadena


Función Date
El SQL soporta la función EXTRACT() para aislar un campo numérico simple de un campo
date/time al recuperar usando la siguiente sintaxis:

EXTRACT (extract_field FROM field_name)

Por ejemplo, la siguiente instrucción extrae el valor del año de un campo DATE:

SELECT EXTRACT(YEAR FROM HIRE_DATE)

FROM EMPLOYEE

Usted puede también extraer MONTH, DAY, HOUR, MINUTE, y SECOND usando esta función.

Nota: EXTRACT no soporta las cláusulas TIMEZONE_HOUR o TIMEZONE_MINUTE.

Operadores
El SQL soporta los siguientes operadores:

Tipo Operator

Aritméticos + - * /

Comparación < > = <> >= =<

IS NdirL IS NOTNdirL

Lógico AND OR NOT

Concatenación de cadenas ||

consultas actualizables
SQL Links ofrece soporte expandido para consultas actualizables de tabla simple y multi-
tabla.

Estas restricciones se aplican a las actualizaciones:

Campos enlazadas no pueden ser actualizados

El cambio de índice causará un error

Restricciones sobre las consultas en vivo


La semántica de consultas en vivo, para todos los métodos de manipdiración de datos,
devuelve cursores que son funcional y semánticamente similares a los cursores retornados
por la función DbiOpenTable del BDE. Las consultas de tablas simples o las vistas son
actualizables, siempre que:

No hay operaciones JOIN, UNION, INTERSECT, o MINUS

No hay una palabra clave DISTINCT en el SELECT. (Esta restricción puede ser
relajada si todos los campos de un índice único están protegidos).
Todo en la cláusula SELECT es una referencia de columna simple o un campo
calcdirado, no se permiten agregaciones.

La tabla referenciada en la cláusula FROM es una tabla base actualizable o una vista
actualizable.

No hay una cláusula de GROUP BY o HAVING.

No hay subconsultas que referencian la tabla en la cláusula FROM ni en subconsultas


correlacionadas.

Cualquier cláusula ORDER BY puede ser satisfecha con un índice.

Las restricciones adicionales pueden aplicarse a los métodos de los campos o cursores. Si un
índice es usado para satisfacer una cláusula de orden, la función DbiSwitchToIndex del BDE
devuelve un error.

Restricciones a uniones en vivo


Las uniones en vivo dependen de los cursores compuestos. Los joins en vivo pueden usarse
sólo si:

Todos All joins are left-to-right outer joins.

All join are equi-joins.

All join conditions are satisfied by indexes (for Paradox and dBASE)

Output ordering is not defined.

Each table in the join is a base table.

The query contains no elements listed above that wodird prevent single-table
updatability.

Constraints
Usted puede restringir cualquier consulta actualizable asignando la propiedad de la
instrucción de consulta stmtCONSTRAINED a TRUE antes de ejecución. Un error será
entonces retornado cada vez que una modificación o insersión cause que el nuevo registro
desaparezca del conjunto resultado.

Campos calcdirados (Calcdirated fields)


Para consultas actualizables con campos calcdirados, una propiedad adicional de campo
identifica un campo resultado como de sólo lectura y calcdirado. Todas las llamadas a la
función BDE DbiPutField causa una recalcdiración de cualquier campo dependiente.

Llamadas de función BDE acerca de resultados de consultas


Si una consulta devuelve un cursor, ese cursor soportará completamente las capacidades de
consulta de bajo nivel de un cursor devuelto de la función BDE DbiOpenTable. Por eso los
filtros y los mapas de campo puede ser aplicado para refinar más el conjunto resultado. A
diferencia de los cursores de tabla abierta, algunas operaciones tal como DbiAddIndex o
DbiSwitchToIndex no son soportados.
Ejemplos DML
Las siguientes cláusulas son soportadas:

SELECT FROM, WHERE, ORDER BY, GROUP BY, and HAVING

Los siguientes agregados son soportados:

SUM, AVG, MIN, MAX, COUNT

Los siguientes operadores son soportados:

, -, *, /, =, < >, IS NdirL

Las operaciones UPDATE, INSERT, DELETE son soportados completamente. Los siguientes
ejemplos muestras instrucciones DML con bases de datos estandar:

Ejemplo 1: UPDATE

update goods

set city = 'Santa Cruz'

where goods.city = 'Scotts Valley'

Ejemplo 2: INSERT
insert

into goods ( part_no, city )

values ( 'aa0094', 'San Jose' )

Ejemplo 3: DELETE
delete

from goods

where part_no = 'aa0093'

Ejemplo 4: SELECT used to join

El siguiente ejemplo ilustra cómo se soportan las instrucciones SELECT como un equivalente
de JOIN:

select distinct p.part_no, p.quantity, g.city

from parts p, goods g

where p.part_no = g.part_no

and p.quantity > 20

order by p.quantity, g.city, p.part_no


Una instrucción SELECT que contiene un join debe tener una cláusula WHERE en la cual por
lo menos un campo de cada tabla se ve envuelta en un chequeo de seguridad.

Ejemplo 5: Sub-selects

Se soportan las consultas sub-seleccionadas. El siguiente ejemplo ilustra esta sintaxis.

select p.part_no

from parts p

where p.quantity in

(select i.quantity

from inventory i

where i.part_no = 'aa9393')

Ejemplo 6: GROUP BY

Los siguentes ejemplos ilustran la cláusula GROUP BY:

select part_no, sum(quantity) as PQTY

from parts

group by part_no

Nota: Los agregados en la cláusula SELECT debe tener una cláusula GROUP BY si se usa un
campo proyectado, como se muestra en el primer ejemplo.

Ejemplo 7: ORDER BY

El siguiente ejemplo ilustra el ORDER BY con una cláusula DESCENDING:

select distinct customer_no

from c:\data\customer

order by customer_no descending

Definición de Datos
Local SQL supports data definition language (DDL) for creating, altering, and dropping
tables, and for creating and dropping indexes.

Views are supported.

Local SQL does not permit the substitution of variables for values in DDL statements.

The following DDL statements are supported:

CREATE TABLE

ALTER TABLE
DROP TABLE

CREATE INDEX

DROP INDEX

CREATE VIEW

For additional illustrative Ejemplos see:

DDL Ejemplos

CREATE TABLE

CREATE TABLE is supported with the following limitations:

Column definitions based on domains are not supported.

Constraints are limited to PRIMARY KEY for Paradox. Constraints are unsupported in dBASE.

For Ejemplo, the following statement creates a Paradox table with a PRIMARY KEY constraint
on the LAST_NAME and FIRST_NAME columns:

CREATE TABLE "employee.db"

LAST_NAME CHAR(20),

FIRST_NAME CHAR(15),

SALARY NUMERIC(10,2),

DEPT_NO SMALLINT,

PRIMARY KEY(LAST_NAME, FIRST_NAME)

The same statement for a dBASE table shodird omit the PRIMARY KEY definition:

CREATE TABLE "employee.dbf"

LAST_NAME CHAR(20),

FIRST_NAME CHAR(15),

SALARY NUMERIC(10,2),

DEPT_NO SMALLINT

Creating Paradox and dBASE tables


You create a Paradox or dBASE table using local SQL by specifying the file extension when
naming the table:

".DB" for Paradox tables

".DBF" for dBASE tables

If you omit the file extension for a local table name, the table created is the table type
specified in the Defadirt Driver setting in the System page of the BDE Configuration Utility.

Data type mappings for CREATE TABLE

The following table lists SQL syntax for data types used with CREATE TABLE, and describes
how those types are mapped to Paradox and dBASE types by the BDE:

SQL Syntax BDE Logical Paradox dBASE

SMALLINT fldINT16 Short Number (6,10)

INTEGER fldINT32 Long Integer Number (20,4)

DECIMAL(x,y) fldBCD BCD N/A

NUMERIC(x,y) fldFLOAT Number Number (x,y)

FLOAT(x,y) fldFLOAT Number Float (x,y)

CHARACTER(n) fldZSTRING Alpha Character

VARCHAR(n) fldZSTRING Alpha Character

DATE fldDATE Date Date

BOOLEAN fldBOOL Logical Logical

BLOB(n,1) fldstMEMO Memo Memo

BLOB(n,2) fldstBINARY Binary Binary

BLOB(n,3) fldstFMTMEMO Formatted memo N/A

BLOB(n,4) fldstOLEOBJ OLE OLE

BLOB(n,5) fldstGRAPHIC Graphic N/A

TIME fldTIME Time N/A

TIMESTAMP fldTIMESTAMP Timestamp N/A

MONEY fldFLOAT, fldstMONEY Money Number (20,4)

AUTOINC fldINT32, fldstAUTOINC Autoincrement N/A

BYTES(n) fldBYTES(n) Bytes N/A

x = precision (defadirt: specific to driver)


y = scale (defadirt: 0)

n = length in bytes (defadirt: 0)

1-5 = BLOB subtype (defadirt: 1)

ALTER TABLE

Local SQL supports the following subset of the ANSI-standard ALTER TABLE statement. You
can add new columns to an existing table using this ALTER TABLE syntax:

ALTER TABLE table ADD column_name data_type [, ADD column_name data_type ...]

For Ejemplo, the following statement adds a column to a dBASE table:

ALTER TABLE "employee.dbf" ADD BUILDING_NO SMALLINT

You can delete existing columns from a table using the following ALTER TABLE syntax:

ALTER TABLE table DROP column_name [, DROP column_name ...]

For Ejemplo, the next statement drops two columns from a Paradox table:

ALTER TABLE "employee.db" DROP LAST_NAME, DROP FIRST_NAME

ADD and DROP operations can be combined in a single statement. For Ejemplo, the following
statement drops two columns and adds one:

ALTER TABLE "employee.dbf" DROP LAST_NAME, DROP FIRST_NAME, ADD FdirL_NAME


CHAR[30]

DROP TABLE

DROP TABLE deletes a Paradox or dBASE table. For Ejemplo, the following statement drops a
Paradox table:

DROP TABLE "employee.db"

CREATE VIEW

A view creates a virtual table from a SELECT statement. You can look at just the data you
need within this movable frame or window on the table, while the technical underpinnings
are hidden. Instead of entering a complex qualified SELECT statement, the user simply
selects a view.

CREATE VIEW describes a view of data based on one or more underlying tables in the
database. The rows to return are defined by a SELECT statement that lists columns from the
source tables. A view does not directly represent physically stored data. It is possible to
perform select, project, join, and union operations on views as if they were tables.

CREATE VIEW enables users to create views on tables by using the following syntax:

CREATE VIEW view_name [ (column_name [, column_name]...)]

CREATE VIEW is supported in conjunction with the Client Data Repository (CDR). The CDR
stores the SELECT statement that defines the view.
The "WITH CHECK OPTION" is supported to create a constrained view.

Views of Views are supported. However, the CASCADE/LOCAL view attribute is not
supported, because all updateable views CASCADE the constraints.

DDL Ejemplos

The following Ejemplos show the use of DDL statements with standard databases.

Ejemplo 1a: DDL (DROP TABLE)

When the table name contains a period "." character, enclose the name in quotation marks:

drop table "c:\data\customer.db"

Ejemplo 1b: DDL (DROP TABLE)

No quotation marks are used if the table name does not contain the "." character:

drop table clients

Ejemplo 2: DDL (CREATE INDEX)

create index part on parts (part_no)

Paradox: Paradox primary indexes can be created only when creating the table. Secondary
indexes are created as case insensitive and maintained, when possible.

dBASE: dBASE indexes are created as maintained. The Index name specified is the tag
name.

For more information about different types of indexes, see DbiAddIndex in the Borland
Database Engine Online Reference.

Ejemplo 3: DDL (DROP INDEX)

The syntax for drop index is tablename.indexname:

drop index parts.part_no

Paradox: For Paradox only, the syntax tablename.primary indicates the primary index:

drop index parts.primary

Introduction to Borland SQL Links for Windows (32-bit version)

Borland SQL Links for Windows is a set of BDE-hosted driver connections to database
servers. By creating queries, SQL Links emdirates fdirl navigation capabilities, enabling users
to access and manipdirate data in SQL databases by using convenient features in Borland
applications.

Any Borland application based upon the Borland Database Engine (BDE) can use Borland SQL
Links, including your custom applications built using the BDE API. Borland SQL Links is
included with some Borland client/server application development tools such as Delphi
Client/Server.
The SQL Links product package includes database drivers for InterBase, ORACLE, Sybase,
and Microsoft SQL Server databases. These drivers require the installation of the appropriate
vendor's server connectivity API or interface software. Borland Database Engine includes
built-in drivers for Borland standard databases.

Other topics in this Introduction to SQL Links

Additional information

Other BDE online documentation

SQL Reserved Words.


This document contains a list of reserved words for Local SQL in the Borland Database
Engine (BDE).

This file contains an alphabetical list of words reserved by

Local SQL in the Borland Database Engine. Note that this file

is provided as-is.

ACTIVE, ADD, ALL, AFTER, ALTER, AND, ANY, AS, ASC, ASCENDING,

AT, AUTO, AUTOINC, AVG

BASE_NAME, BEFORE, BEGIN, BETWEEN, BLOB, BOOLEAN, BOTH, BY,

BYTES

CACHE, CAST, CHAR, CHARACTER, CHECK, CHECK_POINT_LENGTH,

COLLATE, COLUMN, COMMIT, COMMITTED, COMPUTED, CONDITIONAL,

CONSTRAINT, CONTAINING, COUNT, CREATE, CSTRING, CURRENT,

CURSOR

DATABASE, DATE, DAY, DEBUG, DEC, DECIMAL, DECLARE, DEFAdirT,

DELETE, DESC, DESCENDING, DISTINCT, DO, DOMAIN, DOUBLE, DROP

ELSE, END, ENTRY_POINT, ESCAPE, EXCEPTION, EXECUTE, EXISTS,

EXIT, EXTERNAL, EXTRACT

FILE, FILTER, FLOAT, FOR, FOREIGN, FROM, FdirL, FUNCTION

GDSCODE, GENERATOR, GEN_ID, GRANT, GROUP,

GROUP_COMMIT_WAIT_TIME

HAVING, HOUR

IF, IN, INT, INACTIVE, INDEX, INNER, INPUT_TYPE, INSERT,


INTEGER, INTO, IS, ISOLATION

JOIN

KEY

LONG, LENGTH, LOGFILE, LOWER, LEADING, LEFT, LEVEL, LIKE,

LOG_BUFFER_SIZE

MANUAL, MAX, MAXIMUM_SEGMENT, MERGE, MESSAGE, MIN, MINUTE,

MODdirE_NAME, MONEY, MONTH

NAMES, NATIONAL, NATURAL, NCHAR, NO, NOT, NdirL,

NUM_LOG_BUFFERS, NUMERIC

OF, ON, ONLY, OPTION, OR, ORDER, OUTER, OUTPUT_TYPE, OVERFLOW

PAGE_SIZE, PAGE, PAGES, PARAMETER, PASSWORD, PLAN, POSITION,

POST_EVENT, PRECISION, PROCEDURE, PROTECTED, PRIMARY,

PRIVILEGES

RAW_PARTITIONS, RDB$DB_KEY, READ, REAL, RECORD_VERSION,

REFERENCES, RESERV, RESERVING, RETAIN, RETURNING_VALUES,

RETURNS, REVOKE, RIGHT, ROLLBACK

SECOND, SEGMENT, SELECT, SET, SHARED, SHADOW, SCHEMA,

SINGdirAR, SIZE, SMALLINT, SNAPSHOT, SOME, SORT, SQLCODE,

STABILITY, STARTING, STARTS, STATISTICS, SUB_TYPE, SUBSTRING,

SUM, SUSPEND

TABLE, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,

TO, TRAILING, TRANSACTION, TRIGGER, TRIM

UNCOMMITTED, UNION, UNIQUE, UPDATE, UPPER, USER

VALUE, VALUES, VARCHAR, VARIABLE, VARYING, VIEW

WAIT, WHEN, WHERE, WHILE, WITH, WORK, WRITE

YEAR

OPERATORS:

||, -, *, /, <>, <, >, ,(comma), =, <=, >=, ~=, !=, ^=, (, )
16 ANEXOS
16.1 Resolución de Problemas

16.1.1 Buscar Información duplicada en un campo de una tabla.

Para generar este tipo de consultas lo más sencillo es utilizar el asistente de consultas de
Access, editar la sentencia SQL de la consulta y pegarla en nuestro código. No obstante
este tipo de consulta se consigue de la siguiente forma:

SELECT DISTINCTROW Lista de Campos a Visualizar FROM Tabla


WHERE CampoDeBusqueda In (SELECT CampoDeBusqueda FROM Tabla As
psudónimo
GROUP BY CampoDeBusqueda HAVING Count(*)>1 ) ORDER BY
CampoDeBusqueda;

Un caso práctico, si deseamos localizar aquellos empleados con igual nombre y


visualizar su código correspondiente, la consulta sería la siguiente:

SELECT DISTINCTROW Empleados.Nombre, Empleados.IdEmpleado


FROM Empleados WHERE Empleados.Nombre In (SELECT Nombre FROM
Empleados As Tmp GROUP BY Nombre HAVING Count(*)>1)
ORDER BY Empleados.Nombre;

16.1.2 Recuperar Registros de una tabla que no contengan registros relacionados en


otra.

Este tipo de consulta se emplea en situaciones tales como saber que productos no se han
vendido en un determinado periodo de tiempo,

SELECT DISTINCTROW Productos.IdProducto, Productos.Nombre FROM


Productos
LEFT JOIN Pedidos ON Productos.IdProducto = Pedidos.IdProduct WHERE
(Pedidos.IdProducto Is Null) AND (Pedidos.Fecha Between #01-01-98# And
#01-30-98#);

La sintaxis es sencilla, se trata de realizar una unión interna entre dos tablas
seleccionadas mediante un LEFT JOIN, establecimiendo como condición que el campo
relacionado de la segunda sea Null.

16.2 Utlizar SQL desde Visual Basic

Existen dos tipos de consultas SQL: las consultas de selección (nos devuelven datos) y
las consultas de acción (aquellas que no devuelven ningún registro). Ambas pueden ser
tratadas en Visual Basic pero de forma diferente.

Las consultas de selección se ejecutan recogiendo la información en un recordset


previamente definido mediante la instrucción openrecordset(), por ejemplo:

Dim SQL as String


Dim RS as recordset
SQL = "SELECT * FROM Empleados;"
Set RS=MiBaseDatos.OpenRecordSet(SQL)

Si la consula de selección se encuentra almacenada en una consulta de la base de datos:

Set RS=MiBaseDatos.OpenRecordset("MiConsulta")

Las consultas de acción, al no devolver ningún registro, no las podemos asignar a


ningún recordset, en este caso la forma de ejecutarlas es mediante los métodos Execute
y ExecuteSQL (para bases de datos ODBC), por ejemplo:

Dim SQL as string

SQL = "DELETE * FROM Empleados WHERE Categoria = 'Ordenanza';"


MiBaseDatos.Execute SQL

16.3 Funciones de Visual Basic utilizables en una Instrucción SQL

Función Sintaxis Descripción


Now Variable= Now Devuelve la fecha y la hora actual del sistema
Date Variable=Date Devuelve la fecha actual del sistema
Time Variable=Time Devuelve la hora actual del sistema
Devuelve los cuatro dígitos correspondientes al
Year Variable=Year(Fecha)
año de Fecha
Month Variable=Month(Fecha) Devuelve el número del mes del parámetro fecha.
Devuelve el número del día del mes del parámetro
Day Variable=Day(Fecha)
fecha.
Devuelve un número entero que representa el día
Weekday Variable=Weekday(Fecha)
de la semana del parámetro fecha.
Devuelve un número entre 0 y 23 que representa la
Hour Variable=Hour(Hora)
hora del parámetro Hora.
Devuelve un número entre 0 y 59 que representa
Minute Variable=Minute(Hora)
los minutos del parámetro hora.
Devuelve un número entre 0 y 59 que representa
Second Variable=Second(Hora)
los segundos del parámetro hora.

DatePart

Esta función devuelve una parte señalada de una fecha concreta. Su sintaxis es:

DatePart(Parte, Fecha, ComienzoSemana, ComienzoAño)

Parte representa a la porción de fecha que se desea obtener, los posibles valores son:
Valor Descripción
yyyy Año
q Trimestre
m Mes
y Día del año
d Día del mes
w Día de la semana
ww Semana del año
h Hora
m Minutos
s Segundos

ComienzoSemana indica el primer día de la semana. Los posibles valores son:

Valor Descripción
0 Utiliza el valor pode efecto del sistema
1 Domingo (Valor predeterminado)
2 Lunes
3 Martes
4 Miércoles
5 Jueves
6 Viernes
7 Sábado

ComienzoAño indica cual es la primera semana del año; los posibles valores son:

Valor Descripción
0 Valor del sistema
1 Comienza el año el 1 de enero (valor predeterminado).
2 Empieza con la semana que tenga al memos cuatro días en el nuevo año.
3 Empieza con la semana que esté contenida completamente en el nuevo año.

16.4 Evaluar valores antes de ejecutar la Consuta.


Dentro de una sentencia SQL podemos emplear la función iif para indicar las
condiciones de búsqueda. La sintaxis de la función iif es la siguiente:

iif(Expresion,Valor1,Valor2)

En donde Expresión es la sentencia que evaluamos; si Expresión es verdadera entonces


se devuelve Valor1, si Expresión es falsa se devuelve Valor2.

SELECT * Total FROM Empleados WHERE Apellido =


iff(TX_Apellido.Text <> '', TX_Apellido.Text, *) ;

Supongamos que en un formulario tenemos una casilla de texto llamanda


TX_Apellido. Si cuando ejecutamos esta consulta la casilla contiene algún valor
se devuelven todos los empleados cuyo apellido coincida con el texto de la
casilla, en caso contrario se devuelven todos los empleados.
SELECT Fecha, Producto, Cantidad, (iif(CodigoPostal>=28000 And
CodigoPostal <=28999,'Madrid','Nacional')) AS Destino FROM Pedidos;
Esta consulta devuelve los campos Fecha, Nombre del Producto y Cantidad de
la tabla pedidos, añadiendo un campo al final con el valor Madrid si el código
posta está dentro del intervalo, en caso contario devuelve Nacional.
16.5 Un Pequeño Manual de Estilo

Siempre es bueno intentar hacer las cosas de igual modo para que el mantenimiento y la
revisión nos sea una labor lo más sencilla posible. En lo que a mi respecta utilizo las
siguiente normas a la hora de elaborar sentecias SQL:

1. Las cláusulas siempre las escribo con Mayúsculas.


2. Los operadores lógicos de sentencias siempre con Mayúsculas.
3. Las operaciones siempre la primera letra con mayúsculas y el resto en
minúsculas.
4. Los operadores lógicos incluidos en otros operadores la primera letra con
mayúsculas y el resto con minúculas.

Los Nombres de las Tablas, Campos y Consultas, los escribo siempre la primera letra
con mayúsculas y el resto con minúsculas, en algunos casos utilizo el carácter "_" para
definir mejor el nombre: Detalles_Pedidos.

Aunque con el motor Jet se pueden utilizar acentos y espacios en blanco para nombrar
los campos, las tablas y las consultas no los utilizo porque cuando se exportar tablas a
otros sistemas los acentos y los espacios en blanco pueden producir errores
innecesarios.

Recuerda siempre que si utilizas espacios en blanco para llamar tablas o consultas cada
vez que hagas referencias a ellos en una consulta debes incluir sus nombres entre
corchetes.

SELECT [ID de Pedido], [Nombre del Producto], Cantidad FROM [Detalles del
Pedido];

S-ar putea să vă placă și