SELECT seguida de una lista de atributos que interese obtener como respuesta (SELECT A1 ,..., An).Nota: El nombre de la cláusula SELECT es engañoso, ya que lo que hace no es una selección, sino una proyección.
FROM seguida de la lista de las relaciones que usamos en la consulta (FROM r1,...,rm).
WHERE (cláusula opcional) va seguida del predicado de selección (WHERE p).
SELECT A1,...,AnA continuación se muestran las operaciones posibles en SQL, por medio de ejemplos:
FROM r1,...,rm » ΠA1 ,..., An (σ P (r1 x r2 x .... x rm))
WHERE P
"Seleccionar todos los atributos de préstamo para los préstamos de más de mil €". (Selección)Una de las posibilidades que ofrece SQL, es que cuando se quieren todos los atributos de una relación, en la cláusula SELECT no hace falta que se todos, basta con poner un asterisco (*). De esta manera, la selección anterior quedaría:
SELECT nombre_sucursal, num_prestamo, nombre_cliente, importe
FROM prestamo
WHERE importe > 1000
SELECT *Ahora realizaremos una consulta para obtener los nombres y las ciudades en que viven de los clientes que tienen un préstamo en la sucursal principal. (Proyección sobre una selección realizada sobre un producto cartesiano).
FROM prestamo
WHERE importe > 1000
SELECT prestamo.nombre_cliente, ciudadSQL incluye también unión, intersección y diferencia. Veamos como podemos realizar dichas operaciones:
FROM cliente, prestamo
WHERE nombre_sucursal = "Principal" and prestamo.nombre_cliente = cliente.nombre_cliente
(SELECT nombre_cliente
FROM prestamo
WHERE nombre_sucursal = "Principal")
UNION
(SELECT nombre_cliente
FROM deposito
WHERE nombre_sucursal = "Principal")
SELECT distinc nombre_clienteLas vistas hasta ahora son básicamente las operaciones de SQL basadas en el álgebra relacional, a continuación veremos algunas basadas en el cálculo relacional. Por ejemplo las operaciones referentes a pertenencia (Cálculo relacional orientado a dominios).
FROM prestamo, deposito
(SELECT nombre_clienteUna 2ª forma basada también en el álgebra relacional sería esta otra:
FROM prestamo
WHERE nombre_sucursal = "Principal")
INTERSECT
(SELECT nombre_cliente
FROM deposito
WHERE nombre_sucursal = "Principal")
SELECT prestamo.nombre_clientePodemos usar una 3ª forma basada en el cálculo relacional, que sería la siguiente: (IN es el operador de pertenencia).
FROM prestamo, deposito
WHERE prestamo.nombre_cliente = deposito.nombre_cliente and prestamo.nombre_sucursal = "Principal"
SELECT nombre_clienteIncluso una 4ª forma:
FROM prestamo
WHERE nombre_sucursal = "Principal" and
nombre_cliente IN (SELECT nombre_cliente
FROM deposito
WHERE nombre_sucursal = "Principal")
SELECT nombre_clienteSQL, también permite realizar algunas operaciones propias del cálculo relacional orientado a tuplas. Las variables de tupla se definen en la cláusula FROM, la mejor forma de ver esto es por medio de algunos ejemplos:
FROM prestamo
WHERE nombre_sucursal="Principal" and <nombre_cliente, nombre_sucursal>
IN (SELECT nombre_cliente, nombre_sucursal
FROM deposito)
SELECT t.nombre_cliente, ciudad_clienteNótese que los atributos que son comunes a las relaciones cliente y prestamo, cuando son utilizados ha de ser especificado a cual de las dos relaciones nos estamos refiriendo. En el caso anterior definimos una tupla t de la relación cliente, y una tupla s de la relación prestamo, y nos quedamos con todas aquellas tuplas que existen al mismo tiempo en ambas relaciones y cuyo valor para el atributo nombre_sucursal en la relación prestamo es "Principal".
FROM cliente t, prestamo s
WHERE t.nombre_cliente = s.nombre_cliente and nombre_sucursal = "Principal"
SELECT t.nombre_clienteEsta misma consulta podría también ser hecha de esta otra forma:
FROM deposito t, deposito s
WHERE s.nombre_cliente ="Lopez" and t.nombre_sucursal = s.nombre_sucursal
SELECT nombre_clienteOtro caso en que las variables de tupla pueden ser de interés es cuando lo que nos interesa no es comprobar si un elemento pertenece a un conjunto, sino comparar un elemento con todos los elementos de un conjunto. Por ejemplo: "Queremos conocer las sucursales que tienen un activo mayor que alguna de las sucursales de Murcia"
FROM deposito
WHERE nombre_sucursal IN (SELECT nombre_sucursal
FROM deposito
WHERE nombre_cliente = "Lopez")
SELECT t.nombre_sucursalSQL incorpora otras cláusulas para poder hacer esto sin tener que usar el cálculo relacional de tuplas. La cláusula some situada delante de un conjunto, se refiere a algún elemento de ese conjunto. De esta manera la consulta anterior quedaría:
FROM sucursal t, sucursal s
WHERE t.activo > s.activo and s.ciudad_sucursal = "Murcia"
SELECT nombre_sucursalEn algunas versiones antiguas en lugar de some podemos encontrar any.
FROM sucursal
WHERE activo > some (SELECT activo
FROM sucursal
WHERE ciudad_sucursal = "Murcia")
SELECT nombre_sucursalLas cláusulas some y all, nos permiten comparar un valor con un conjunto de valores, pero si lo que queremos es un conjunto de valores con otro, podemos usar la cláusula contains, que indica si un conjunto está contenido en otro. Como ejemplo para el uso de esta cláusula sería válido el siguiente: "Encontrar los clientes que tengan una cuenta en todas las sucursales de Murcia". Lo que buscamos es un conjunto de clientes que tienen cuentas en todas las sucursales de un conjunto de sucursales que contiene a todas las sucursales de Murcia.
FROM sucursal
WHERE activo > all (SELECT activo
FROM sucursal
WHERE ciudad_sucursal = "Murcia")
SELECT t.nombre_clienteOtra cláusula que incluye SQL es la cláusula exists, que devuelve verdadero cuando la subconsulta que se pone detrás devuelva un valor que no sea vacío, y devuelve falso si la subconsulta que se pone detrás devuelve un conjunto vacío. Ejemplo: "Clientes que tengan un préstamo y cuenta en la sucursal principal".
FROM deposito t
WHERE (SELECT s.nombre_sucursal
FROM deposito s
WHERE t.nombre_cliente = s.nombre_cliente) contains
(SELECT nombre_sucursal
FROM sucursal
WHERE ciudad_sucursal = "Murcia")
SELECT nombre_clienteSQL nos permite también, obtener el resultado de todas nuestras operaciones por orden (basándose en uno de los atributos de la relación resultante). Con este fin se introdujo la cláusula ORDER BY, que se pone detrás de las 3 cláusulas SELECT, FROM y WHERE, y que debe ir seguida del nombre del atributo por el cual queremos ordenar. Esta cláusula puede ir acompañada por dos modificadores (asc o dec), según queramos obtener el resultado en orden ascendente o descendente, respectivamente. Estos modificadores irán emplazados detrás del atributo por el cual queremos ordenar nuestra consulta. Ejemplo: "Queremos obtener los nombres de los clientes de Murcia por orden alfabético".
FROM cliente
WHERE exists (SELECT *
FROM prestamo
WHERE prestamo.nombre_cliente = cliente.nombre_cliente and nombre_sucursal = "Principal")
and exists (SELECT * FROM deposito
WHERE deposito.nombre_cliente = cliente.nombre_cliente and nombre_sucursal = "Principal")
SELECT nombre_clienteEl modificador por defecto es asc.
FROM cliente
WHERE ciudad_cliente = "Murcia"
ORDER BY nombre_cliente
SELECT nombre_clienteCon esa orden conseguiríamos obtener los nombres de los clientes que tienen un préstamo ordenados por orden alfabético, pero en caso de que dos clientes tuviesen el mismo nombre, saldría primero aquel cuyo préstamo fuese más alto.
FROM prestamo
ORDER BY nombre_cliente asc, importe dec
Veamos ahora como se podría contar el número de tuplas de cliente:
SELECT nombre_sucursal, avg (saldo)
FROM deposito
GROUP BY nombre_sucursal
SELECT count (*)Hay casos en los que las condiciones que imponemos, nos interesa que las cumpla un grupo de tuplas, y no una sola, en ese caso usamos la cláusula HAVING.
FROM cliente
El orden de las cláusulas sería: SELECT, FROM, WHERE, ORDER BY, GROUP BY y HAVING.
SELECT avg (importe)
FROM prestamo
WHERE nombre_sucursal = "Principal"
GROUP BY nombre_cliente
HAVING avg (importe) > 10000
SELECT nombre_clientees equivalente a:
FROM deposito
WHERE saldo ³ 100.000 and saldo £ 1.000.000
SELECT nombre_clienteSQL ofrece también una cláusula para tratar cadenas de caracteres, se trata de la cláusula like. Cuando usamos esta cláusula, el símbolo % en una cadena es un comodín de 0, 1, o más caracteres, y el carácter _ es un comodín de un carácter (equivalentes al * y la ? de MS-DOS respectivamente). Ejemplo en el que se usa esta cláusula:
FROM deposito
WHERE saldo BETWEEN 100.000 and 1.000.000
SELECT nombre_clienteDe esta manera obtenemos los nombres de todos los clientes cuyo atributo ciudad_cliente empiece por Mur. Si queremos que en una cadena aparezca uno de los dos caracteres comodines, tendremos que ponerlos con el carácter \ delante, que servirá de carácter de escape. Si por ejemplo ponemos like "ANT\%2" estaremos comparando con la cadena "ANT%2".
FROM cliente
WHERE ciudad_cliente like "Mur%"
DELETE rdonde r es la relación de la que queremos borrar tuplas, y p es el predicado que deben de cumplir las tuplas que queremos borrar. Por ejemplo, para borrar los préstamos de Pepito deberíamos hacer:
WHERE p
DELETE prestamoSQL adolece de que no cumple la integridad de referencia, es decir, que si dos relaciones tienen en común un atributo que en una de las relaciones es clave primaria, y en la otra es clave ajena, este atributo debería ser igual en ambas relaciones en todo momento, sin embargo en SQL esto no es así, ya que cuando borras una tupla en una relación, si tiene un atributo (clave primaria) en común en otra relación, éste no se ve modificado.
WHERE nombre_cliente = "Pepito"
UPDATE depositoC)Inserción. Tiene dos variantes: En primer lugar insertar en una relación tuplas una a una, o la segunda, insertar conjuntos de tuplas enteras que son resultado de una operación SELECT.
SET saldo = saldo + 3
WHERE nombre_sucursal = "10"
INSERT INTO prestamoLos valores se deben introducir en el orden correcto en que están los atributos en la relación.
VALUES (102, "Principal", "Manolo", 2.000.000)
INSERT INTO deposito
SELECT num_prestamo, nombre_cliente, nombre_sucursal, 1
FROM prestamo
INSERT INTO deposito (saldo, num_cuenta, nombre_sucursal, nombre_cliente)
SELECT 100, num_prestamo, nombre_sucursal, nombre_cliente
FROM prestamo
donde t1,.....,tm son las tuplas que usamos para la consulta, r1,...,rm son las relaciones correspondientes a t1,...,tm. La cláusula RETRIEVE es equivalente a la cláusula SELECT de SQL, y P es el predicado de selección.
RANGE OF t1 IS r1
RANGE OF t2 IS r2
...................................
..................................
RANGE OF tm IS rm
RETRIEVE (ti1.Aj1, ti2.Aj2, ........, tim.Ajm)
WHERE P
RANGE OF t IS deposito RETRIEVE (t.nombre_cliente) WHERE t.nombre_sucursal = "Principal".Como ejemplo de una consulta en la que aparezcan dos tuplas de dos relaciones distintas podríamos usar el siguiente: " Obtener todos los nombres de los clientes y sus ciudades de residencia que tienen préstamo en la sucursal principal."
RANGE OF t IS cliente RANGE OF s IS prestamo RETRIEVE (s.nombre_cliente, t.ciudad_cliente) WHERE s.nombre_sucursal = "Principal" AND t.nombre_cliente = s.nombre_clienteQUEL no incluye eliminación de duplicados por defecto, si se quiere conseguir ésta, es necesario indicarlo mediante la cláusula UNIQUE.
RANGE ............. RETRIEVE UNIQUE (.............) WHERE .......Así mismo QUEL tampoco incluye las operaciones de unión, intersección y diferencia , como tampoco permite subconsultas anidadas, por lo que es un poco menos amigable que SQL.
RANGE OF t IS depositoExiste una variante: Operación (t.Ai by t.Aj) ,donde t.Aj es la condición de agrupamiento.
RETRIEVE avg (t.saldo WHERE t.nombre_sucursal = "Principal")
RANGE OF t IS deposito
RETRIEVE avg (t.saldo by t.nombre_sucursal)
RANGE OF t IS deposito
RETRIEVE (t.num_cuenta)
WHERE t.saldo > avg (t.saldo by t.nombre_sucursal).
Ej: APPEND TO deposito (num_cuenta = 287, nombre_sucursal = "Murcia"....)
APPEND TO deposito (lista de atributos con valores nuevos).
RANGE OF t IS prestamoDonde temp quedará formada como una relación cuyo único atributo es nombre_cliente. Si temp ya existiera cuando se realizó la inserción, entonces los atributos que tenga temp deben coincidir con los atributos que insertamos en la cláusula APPEND.
APPEND TO temp (t.nombre_cliente)
WHERE t.nombre_sucursal = "Principal"
RANGE OF t IS depositoD) Eliminación.
REPLACE t (saldo = t.saldo x 1.05)
RANGE OF t IS prestamo
DELETE (t)
WHERE nombre_cliente = "López".
préstamo | num_prestamo | nombre_sucursal | nombre_cliente | importe |
|
|
Principal |
P.ALL. _X |
|
prestamo | num_prestamo | nombre_sucursal | nombre_cliente | importe |
|
|
Principal |
P._X |
|
cliente | nombre_cliente | calle | ciudad |
|
_X |
|
P._Y |
deposito | num_cuenta | nombre_sucursal | nombre_cliente | saldo |
|
|
P.G._X |
|
P.ALL.AVG._Y |
deposito |
num_cuenta | nombre_sucursal | nombre_cliente | saldo |
I. |
207 |
Principal |
García |
2.000.000 |
prestamo | num_prestamo | nombre_sucursal | nombre_cliente | importe |
|
|
Principal |
_X |
|
temp | nombre_cliente |
I. |
_X |
prestamo | num_prestamo | nombre_sucursal | nombre_cliente | importe |
|
_X |
|
|
_Y |
|
_X |
|
|
U ._Y * 2 |
cliente | nombre_cliente | calle | ciudad |
D. |
Lopez |
|
|