Introducción a SQL TEMA 5: SQL (Structured Query Language) 5.1 INTRODUCCIÓN Fue la empresa IBM (International Businessman Machine) quien desarrolló la versión original de este lenguaje en el San José Research Center, originalmente se denominó Sequel, como parte del proyecto System R a comienzos de 1970. El lenguaje Sequel ha evolucionado desde entonces y ha pasado a llamarse SQL(Structured Query Language) convirtiéndose en el lenguaje estándar para Bases de Datos relacionales. La evolución en el tiempo de este lenguaje ha sido la siguiente: En 1986, los organismos ANSI (American National Standars Institute) e ISO (International Standars Organization) publicaron una norma para este lenguaje que se denominó SQL-86. En 1987 IBM publicó su propia norma de SQL corporativo denominada SAA –SQL (System Application Arquitecture Database Interface). En 1989 se publicó una norma extendida para SQL denominada SQL-89, actualmente los sistemas de bases de datos son compatibles con esta norma. La siguiente versión de la norma fue SQL-92, siendo la más reciente la denominada SQL:1999. En este apartado se presentará una visión general de SQL-92 y algunas características de SQL:1999. Los componentes de este lenguaje son: Un Lenguaje de Definición de Datos (LDD), que incluye órdenes para la definición de esquemas de relación, borrado de relaciones, creación de índices y modificación de esquemas de relación. Un Lenguaje de Manipulación de Datos (LMD), basado en el álgebra relacional. Un módulo para el control de transacciones. SQL Dinámico e Incorporado para definir la forma como pueden incorporarse las instrucciones SQL en lenguajes de propósito general. También incluye comandos para la especificación de las restricciones de integridad que deben satisfacer los datos en la Base de Datos y Órdenes para especificar los derechos de acceso a las relaciones y vistas. El SQL es un lenguaje de acceso a bases de datos que explota la flexibilidad y potencia de los sistemas relacionales permitiendo gran variedad de operaciones sobre los mismos. Es un lenguaje declarativo de "alto nivel" o "de no procedimiento", que gracias a su fuerte base teórica y su orientación al manejo de conjuntos de registros, y no a registros individuales, permite una alta productividad en codificación y la orientación a objetos. De esta forma una sola sentencia puede equivaler a uno o más programas que utilizas en un lenguaje de bajo nivel orientado a registro. Nota: Los ejemplos de este capítulo se basan en una empresa bancaria con los siguientes esquemas de relación: Esquema Sucursal = (nombre_sucursal, ciudad_sucursal, activo) Esquema Cliente = (id_cliente, nombre_cliente, calle_cliente, ciudad_cliente) Esquema Prestamo = (numero_prestamo, nombre_sucursal, importe) Esquema Prestatario = (numero_prestamo, nombre_cliente) 1 Introducción a SQL Esquema Cuenta = (numero_cuenta, nombre_sucursal, saldo) Esquema Impositor = (nombre_cliente, numero_cuenta) 5.2 ESTRUCTURA BÁSICA El Lenguaje de consulta estructurado (SQL) es un lenguaje declarativo de acceso a bases de datos relacionales que permite especificar diversos tipos de operaciones sobre las mismas. Una de sus características es el manejo del álgebra y el cálculo relacional permitiendo lanzar consultas con el fin de recuperar de una forma sencilla información de interés de una base de datos, así como también hacer cambios sobre la misma. La estructura básica de una expresión SQL consiste en tres cláusulas: select, from, where. ⇒ La cláusula select corresponde a la operación de proyección del álgebra relacional. Se usa para listar los atributos deseados del resultado de una consulta. ⇒ La cláusula from corresponde a la operación de producto cartesiano del álgebra relacional. Lista las relaciones que se van a examinar en la evaluación de la expresión. ⇒ La cláusula where corresponde al predicado de selección del álgebra relacional. Consta de un predicado que implica los atributos de las relaciones que aparecen en la cláusula from. Una consulta típica en SQL tiene la forma: select A1,A2,..An from r1,r2,..rn where P Cada A1,A2,..An representa un atributo y cada r1,r2,..rn representa una relación. P es un predicado. La consulta equivalente a la siguiente expresión del álgebra relacional: SQL forma el producto cartesiano de las relaciones incluidas en la cláusula from, lleva a cabo la selección del álgebra relacional usando el predicado de la cláusula where y entonces proyecta el resultado sobre los atributos de la cláusula select. 5.2.1 Cláusula select Utilizado para consultar registros de la base de datos. El resultado de una consulta, es una relación. Esta operación de SQL es una de las más utilizada y obedece a la implementación de las operaciones básicas del álgebra relacional: Proyección, Selección, Producto cartesiano, Producto natural. La sintaxis básica de una consulta de selección es la siguiente: select Campos from Tabla; Ejemplo: “Obtener los nombres de todas las sucursales en la relación Prestamo”: Solución: select nombre_sucursal from Prestamo 2 Introducción a SQL El resultado de esta consulta, es una relación que contendrá como único atributo nombre_sucursal. Los lenguajes formales están basados en la noción matemática de que una relación es un conjunto. Así, nunca aparecen tuplas duplicadas en las relaciones. En la práctica, la eliminación de duplicados consume tiempo. Sin embargo, SQL permite duplicados en las relaciones, así como en el resultado de las expresiones SQL. En aquellos casos en los que se quiera forzar la eliminación de duplicados, se insertará la palabra clave distinct después de la cláusula select. Por tanto, la consulta anterior se puede reescribir de la siguiente manera: Ejemplo: Obtener los nombre de todas las sucursales, sin duplicados, que aparecen en la relación Prestamo Solución: select distinct nombre_sucursal from Prestamo Es importante destacar que SQL permite usar la palabra clave all para especificar explícitamente que no se eliminan los duplicados. Solución: select all nombre_sucursal from Prestamo El símbolo asterisco (*) se puede usar para denotar todos los atributos. Una cláusula select de la forma select * indica que se deben seleccionar todos los atributos de todas las relaciones que aparecen en la cláusula from. Solución: select * from Prestamo La cláusula select también puede contener expresiones aritméticas que contengan los operadores (+, -, *, /) sobre constantes o atributos de las tuplas. Ejemplo: Obtener la relación Prestamo con el atributo importe multiplicado por 100 Solución: select numero_prestamo, nombre_sucursal, importe*100 from Prestamo 5.2.2 Cláusula where La cláusula where especifica una condición que debe cumplirse para que los datos sean devueltos por la consulta. Ejemplo: Obtener todos los números de préstamo para préstamos realizados en la sucursal de nombre Subtiava Solución: select numero_prestamo from Prestamo where nombre_sucursal = ‘Subtiava’ SQL utiliza las conectivas lógicas and, or y not en la cláusula where. Los operadores de las conectivas pueden ser expresiones que contengan los operadores de comparación <,<=,>,>=,= y <>. Ejemplo: Obtener todos los números de préstamo para préstamos realizados en la sucursal de nombre Subtiava, en los que el importe sea superior a C$ 1200.00. 3 Introducción a SQL Solución: select numero_prestamo from Prestamo where nombre_sucursal = ‘Subtiava’ and importe >1200 SQL incluye un operador de comparación between para simplificar las cláusulas where que especifica que un valor sea menor o igual que un valor y mayor o igual que otro valor. Ejemplo: Obtener el número de préstamo de aquellos préstamos por importes entre C$ 1000 y C$ 10000. Solución: select numero_prestamo from Prestamo where importe between 1000 and 10000 En lugar de escribir: select numero_prestamo from Prestamo where importe >=1000 and importe <=10000 De forma análoga se puede utilizar el operador de comparación not between. 5.2.3 Implementación de la Proyección y Selección πS σ cond (R) donde S = { s1, s2, s3,.... sm } ⊆ T = { t1, t1, t1,.... tn } es el conjunto de atributos de R y cond es una condición lógica en función de los atributos de R, entonces: πS σcond (R)= select s1, s2, s3,.... sm from R where Cond. Sí la expresión del álgebra relacional se refiere sólo a la proyección o sólo a la Selección, las respectivas expresiones son las siguientes: πS (R)= select s1, s2, s3,.... sm from R σcond (R)= Select * From R Where Cond, donde * indica que se incluyen a todos los atributos de la relación R. 5.2.4 Cláusula from La cláusula from define por sí misma el producto carteasiano de las relaciones que aparecen en la cláusula. Ejemplo: Obtener los nombres, números de préstamo e importes de todos los clientes que tienen un préstamo en el banco Solución: select nombre_cliente, importe, prestatario.numero_prestamo from Prestatario, Prestamo where prestatario.numero_prestamo = prestamo.numero_prestamo SQL usa la notación nombre_relación.nombre atributo, como en el álgebra relacional, para evitar ambigüedad en los casos en que un atributo aparece en el esquema de más de una relación. Ejemplo: Se puede extender la consulta anterior y Obtener los nombres, números de préstamo e importes de todos los clientes que tienen un préstamo en la Sucursal “Proquinsa”. 4 Introducción a SQL Solución: select nombre_cliente, importe, prestatario.numero_prestamo from Prestatario, Prestamo where prestatario.numero_prestamo = prestamo.numero_prestamo and nombre_sucursal = ‘Proquinsa’ 5.2.5 Operación Renombramiento La operación de renombramiento se puede utilizar tanto para relaciones como para atributos mediante la cláusula as, que tiene la siguiente forma: nombre_antiguo as nombre_nuevo Así si se desea renombrar el atributo préstamo.número_préstamo como id_préstamo, la nueva expresión tendría la forma: Solución: select Prestatario.nombre_cliente, Prestamo.numero_prestamo as id_prestamo, Prestamo.importe from prestatario,préstamo where Prestamo.numero_prestamo = Prestatario. numero_prestamo 5.2.6 Variables Tupla Una variable tupla es una variable que adopta como valores las tuplas de una relación. Es decir, cualquier asignación de valores a una variable tupla tiene el mismo número de y tipo de atributos. Ejemplo: Dado el esquema Alumnos(id,nombre,edad), y la tupla Alumnos(11,Carlos,20) Si la variable x es de tipo tupla y es asignada a la tupla en Alumnos, entonces lo siguiente es válido: x .id =11; x.nombre = ‘Carlos’; x.edad = 20 La cláusula as es particularmente útil en la definición del concepto de variables tupla. Una variable tupla en SQL se debe asociar con una relación concreta. Las variables tupla se definen en la cláusula from mediante el uso de la cláusula as. Ejemplo: Obtener los nombres y números de préstamo de todos los clientes que tienen un préstamo en el banco: Solución: select nombre_cliente, T.numero_prestamo, S.importe from Prestatario as T, Prestamo as S where T.numero_prestamo = S.numero_prestamo Ejemplo 2: Obtener los nombres de las sucursales cuyos activos son mayores que alguna de las sucursales localizadas en León. Solución: select distinct T.Nombre_Sucursal from sucursal as T,sucursal as S where T.activo > S.activo and S.ciudad_Sucursal=’León’ En este caso se han definido dos variables de tupla T, S (con dominios diferentes) para una sola relación: Sucursal, en este caso es imprescindible la utilización de la cláusula as. Nótese que T representa todas las tuplas de Sucursal, mientras que S solamente aquellas de sucursal que cumplen la condición ciudad_Sucursal=’León’. 5.2.7 Operaciones sobre cadenas SQL especifica las cadenas de caracteres encerrándolas entre comillas simple. Un carácter comilla que sea parte de una cadena se puede especificar usando dos caracteres comilla. 5 Introducción a SQL El Operador like La operación más usada sobre cadenas es el encaje de patrones, para que el que se usa el operador like. Para la descripción de patrones se utilizan los dos caracteres especiales siguientes: • Tanto por ciento (%): El carácter % encaja con cualquier subcadena. • Subrayado (_): El carácter _ encaja con cualquier carácter. Los patrones son muy sensibles, esto es, los caracteres en mayúsculas no encajan con los caracteres en minúscula, o viceversa. Ejemplos: • ‘Ma%’ encaja con cualquier cadena que empiece con <<Ma>>. • ‘%cer%’ encaja con cualquier cadena que contenga <<cer>> como subcadena. Por ejemplo: ‘Cáceres’, ‘Becerril’, etc. • ‘_ _ _’ Encaja con cualquier cadena de tres caracteres. • ‘_ _ _ %’ Encaja con cualquier cadena de al menos tres caracteres. Los patrones se expresan en SQL utilizando el operador de comparación like. Ejemplo: Obtener los nombres de todos los clientes cuyas ciudades contengan la subcadena ‘eo’. Solución: select nombre_cliente from cliente where ciudad_cliente like ‘%eo%’ Para que los patrones puedan contener los caracteres espaciales patrón (esto es, % y _, SQL permite la especificación de un carácter de escape. El carácter de escape se utiliza inmediatamente antes de un carácter especial patrón para indicar que ese carácter espacial va a ser tratado como un carácter normal. El carácter de escape para una comparación like se define utilizando la palabra clave escape. Por ejemplo: • like ‘ab\%cd%’ escape ‘\’ encaja con todas las cadenas que empiecen por ab%cd. • like ‘ab\\cd%’ escape ‘\’ encaja con todas las cadenas que empiecen por ab\cd. SQL también permite buscar discordancias en lugar de concordancias utilizando el operador de comparación not like. 5.2.8 Fechas y Horas con SQL Las implementaciones de SQL suelen soportar fechas y horas como tipos especiales de datos. Estos valores pueden representarse en varios formatos aunque el estándar SQL-92 es muy específico respecto al formato. • Fecha: Se representa con la palabra clave DATE seguida de una cadena con el formato ‘AAAA-MM-DD’. • Hora: Se representa con la palabra clave TIME seguida de una cadena con el formato ‘HH:MM:SS:d’. 6 Introducción a SQL 5.2.9 Orden en la presentación de las tuplas (Order by) En SQL la cláusula order by permite un cierto control sobre el orden en el que se presentan las tuplas del resultado. Ejemplo: Para listar en orden alfabético todos los clientes que tienen un préstamo en la Sucursal ‘Subtiava’ se escribe la siguiente consulta Solución: select nombre_cliente from Prestatario, Prestamo where Prestatario.numero_prestamo = Prestamo.numero_prestamo and nombre_sucursal = ‘Subtiava’ order by nombre_cliente De manera predeterminada la cláusula order by lista los elementos en orden ascendente. Para especificar el tipo de ordenación se puede incluir la cláusula Desc para ordenación descendente o asc para orden ascendente. Además se puede ordenar con respecto a más de un atributo. Ejemplo: Listar la relación Prestamo en orden descendente para importe. Solución: select * from Prestamo order by importe desc, número_prestamo asc 5.3 OPERACIONES SOBRE CONJUNTOS Las operaciones de SQL-92 unión, intersect y except operan sobre relaciones y corresponden a las operaciones del álgebra relacional U, ∩ y -. Al igual que la unión, intersección y diferencia de conjuntos en el álgebra relacional, las relaciones que participan en las operaciones han de ser compatibles; esto es, deben tener el mismo conjunto de atributos. 5.3.1 La operación Unión Forma General: Sean R1 y R2 dos relaciones. Sean r11, r12, r13,... r1m atributos de R1 y r21, r22,... r2m atributos de R2, entonces: select r11, r12, r13,... r1m from R1 union select r21, r22,... r2m from R2 Genera la unión de conjunto de las filas de la relación. select r11, r12, r13,... r1m from R1 con la relación select r21, r22,... r2m from R2 Ejemplo: Obtener el nombre de todos los clientes que tienen una cuenta en el banco así también los nombres de los que tengan un préstamo. En este caso se requiere unir los nombres de los clientes en Impositor(Los que tienen cuenta en el banco) con los nombres de los clientes de prestatario(Los que tienen un préstamo). Por tanto la expresión SQL es la siguiente: (select Prestatario) nombre_cliente from Impositor) 7 union (select nombre_cliente from Introducción a SQL Dado que la operación unión es una operación de conjunto por defecto no presenta valores duplicados por lo que si se desea conservarlos se debe utilizar la cláusula union all en lugar de union, así en el ejemplo anterior, la expresión SQL quedaría de la siguiente manera: Solución: (select nombre_cliente from Impositor) union all (select nombre_cliente from Prestatario) 5.3.2 La operación Intersección Esta operación obtiene las tuplas comunes de dos relaciones. Forma General: Sean R1 y R2 dos Relaciones, sean R11, R12... R1m atributos de R1 y R21, R22, R23... R2m atributos de R2 entonces la expresión SQL para la intersección es: (select R11, R12… R1m from R1 where P1) intersect (select R21, R22… R2m from R2 where P2) Donde P1 y P2 son expresiones lógicas sobre los atributos de R1 y R2 respectivamente. Ejemplo: Obtener todos clientes que tienen tanto un préstamo como una cuenta en el Banco. Solución: (select distinct Nombre_Cliente from Impositor) intersect (select distinct Nombre_cliente from prestatario) Como en el caso de la operación unión, la operación de intersección elimina los duplicados por lo que como antes si estos se desean en la consulta se debe de utilizar la cláusula all es decir intersect all en lugar de intersect. Ejemplo: Obtener todos clientes que tienen tanto un préstamo como una cuenta en el Banco. Solución: (select distinct nombre_Cliente from Impositor) intersect all (select distinct nombre_cliente from Prestatario) 5.3.3 La operación excepto Esta operación representa a la operación de conjunto menos (-) del álgebra relacional. Forma General: Sean R1, R2 dos relaciones y sean R11, R12... R1m y R21, R22,... R2m atributos de R1 y R2 respectivamente, entonces la expresión SQL para esta operación es: (select R11, R12… R1m from R1 where P1) except (select R21, R22,... R2m from R2 where P2) Donde P1 y P2 son expresiones lógicas sobre los atributos de R1 y R2 respectivamente. Esta expresión obtiene las tuplas generadas por la expresión select R11, R12…R1m from R1 where P1 menos las tuplas generadas por la expresión: select R21, R22... R2m from R2 where P2. 8 Introducción a SQL Ejemplo: Obtener todos los clientes que tienen una cuenta en el banco pero que no tienen un préstamo. Solución: (select distinct nombre_cliente Impositor) except (select distinct nombre_cliente from Prestatario) Dado que esta operación es también una operación de conjunto, elimina los duplicados por lo que si estos se desean en la consulta se debe utilizar except all en lugar de except. Solución: (select distinct nombre_cliente Impositor) except all (select distinct nombre_cliente from Prestatario) 5.4 FUNCIONES DE AGREGACIÓN Las funciones de agregación son funciones que toman una colección (conjunto o multiconjunto) de valores como entrada y producen un único valor como salida. Las funciones primitivas de agregación son: Media (avg): Promedio de los valores del grupo. Mínimo (min): Mínimo de los valores del grupo. Máximo (max): Máximo de los valores del grupo. Suma (sum): Suma de los valores del grupo. Cuenta (count): Cuenta el número de valores, incluyendo los duplicados a menos que se eliminen con distinct Los valores de entrada a sum y avg debe ser una colección de números, pero el resto de funciones pueden operar también sobre cadenas. Ejemplo: Obtener la media de los saldos de las cuentas de la sucursal “Linda Vista” El conjunto de los Datos sobre los cuales actuará la función de agregación es el determinado por el atributo saldo de la relación Cuenta, la expresión SQL es la siguiente: Solución: select avg(saldo) from Cuenta where nombre_sucursal = 'Linda Vista' El resultado de esta consulta será una relación con un único atributo, que contendrá una única fila con un valor numérico correspondiente al saldo promedio de la Sucursal Linda Vista. Opcionalmente se puede dar un nombre al atributo resultado de la relación, usando la cláusula as. 5.4.1 La cláusula group by y las funciones de Agregación Existen situaciones en que es deseable aplicar las funciones de Agregación a determinadas agrupaciones de un atributo o conjunto de atributos, estas agrupaciones se logran utilizando la cláusula group by. El atributos o atributos especificados en la cláusula group by se usan para formar grupos. Las tuplas con el mismo valor en todos los atributos especificados en la cláusula group by se colocan en un grupo. Ejemplo: Obtener el promedio de saldo de las cuentas de cada sucursal. Solución: select nombre_sucursal, avg (saldo) from Cuenta group by nombre_sucursal 9 Introducción a SQL La conservación de duplicados es importante al calcular un promedio. Supongase que los saldos de las cuentas en la sucursal ‘Linda Vista’ son C$ 1000, C$ 2500, C$ 3800, C$ 7800. El saldo medio es 15100/4= C$ 3775. Hay casos en los que se deben eliminar los duplicados antes de calcular una función de agregación. Para eliminar duplicados se utiliza la palabra clave distinct en la expresión de agregación. Ejemplo: Obtener el número de impositores de cada sucursal. En este caso un impositor sólo se debe contar una vez, sin tener en cuenta el número de cuentas que el impositor pueda tener. Solución: select nombre_sucursal count (distinct nombre_cliente) from Impositor, Cuenta where Impositor.numero_cuenta = Cuenta.numero_cuenta group by nombre_sucursal 5.4.2 Uso de las cláusulas where y having con funciones de Agregación La cláusula where en este contexto se utiliza de forma similar a como se utiliza con comandos select que no utilizan funciones de agregación. Sin embargo se debe tener particular cuidado cuando se requiera realizar filtros sobre una consulta que ha utilizado funciones de agregación con agrupaciones, en este caso no se debe utilizar la cláusula where si no que la cláusula having. En otras palabras si en una misma consulta se desea efectuar un filtro para determinar la relación sobre la cual actuarán las funciones de agregación y otro filtro sobre la relación generada por estas funciones de agregación y la cláusula group by, entonces primero se utiliza la cláusula where y posteriormente en la expresión la cláusula having. Ejemplo: Obtener el promedio de los saldos mayores de 3,000 agrupados por nombre_sucursal. En este caso solo existe filtro a nivel de la salida agrupada (Promedio de los saldos > 3000), es decir solo se utilizará la cláusula having, la expresión SQL es: Solución: select nombre_sucursal, avg (saldo) from Cuenta group by nombre_sucursal having avg (saldo) > 3000 Con mucha frecuencia se usa la función de agregación count para contar el número de tuplas de una relación. La notación para esta función en SQL es count (*). Ejemplo: Encontrar el número de tuplas de la relación Cliente. Solución: select count (*) from Cliente SQL no permite el uso de distinct con count (*). Si se permite, sin embargo, el uso de distinct con max y min, incluso cuando el resultado no cambia. Se puede usar la palabra clave all en lugar de distinct para especificar la retención de duplicados, pero como all se especifica de manera predeterminada, no es necesario incluir dicha cláusula. ⇒ Uso de where y having Si en una misma consulta aparece una cláusula where y una cláusula having, se aplica primero el predicado de la cláusula where. Las tuplas que satisfagan el predicado de la cláusula where se colocan en grupos según la cláusula group by. La cláusula having, si existe, se aplica entonces a cada grupo; los grupos que no satisfagan el predicado de la cláusula having se 10 Introducción a SQL eliminan. La cláusula select utiliza los grupos restantes para generar las tuplas resultado de la consulta. Ejemplo 2: Obtener el promedio del saldo de todos los clientes que viven en Managua y tienen como mínimo tres cuentas. σCliente.Ciudad_Cliente='Managua' (Impositor lXl Cliente lXl Cuenta) La agrupación se hará en función del atributo Impositor.nombre_cliente y el filtro (having) de la consulta de agrupación es 'tener como mínimo tres cuentas', por tanto la expresión SQL es: Solución: select Impositor.nombre_cliente, avg (saldo) from Impositor, Cuenta, Cliente where Impositor.numero_cuenta = Cuenta.Numero_Cuenta and Impositor.id_cliente = Cuenta.id_cliente and ciudad_cliente = 'Managua' group by Impositor.nombre_cliente having count (distinct impositor.numero_cuenta) > = 3 Nótese como en la cláusula having se pueden utilizar funciones de agregación, lo cual no es posible en la cláusula where. 5.4.3 SQL y valores nulos SQL permite el uso de valores nulos, indicando así la ausencia de información sobre el valor de un atributo. En un predicado se puede usar la palabra clave especial null para comprobar si un valor es nulo. Ejemplo: Obtener los números de préstamos en la relación Prestamo que no cuentan con datos en el atributo Importe. Solución: select numero_prestamo from Prestamo where Importe is null Nota: Si al contrario de esta consulta, se está interesado en obtener los números de prestamos con datos de Importe, en lugar de is null se utiliza la cláusula is not null. Algunas soluciones a las problemáticas de valores nulos en SQL (a) a op b = null para op = +, -, *, / Si a = null ó b = null (b) a comp b = desconocido para comp = (< =,<,> =,>,=,<>) si a ó b son nulos Las reglas extendidas para los conectores lógicos and y or son los siguientes: Cierto Falso Desconocido Cierto Falso Desconocido and and and or or or Desconocido Desconocido Desconocido Desconocido Desconocido Desconocido Desconocido Falso Desconocido Cierto Desconocido Desconocido Por otra parte SQL para expresiones del tipo select... from R1, R2,... Rn where P; si el predicado P es falso ó desconocido para un determinado conjunto de tuplas, estas no se añaden al resultado de la consulta. 11 Introducción a SQL SQL también permite decidir si el resultado de una operación aritmética ó lógica es desconocida utilizando la cláusula is unkown ó por el contrario se puede utilizar la cláusula is not unknown para indicar que la operación genera un determinado valor que no es desconocido. 5.4.4 Los valores Nulos y las funciones de Agregación En general las funciones de agregación tratan a los valores nulos según la siguiente regla: Todas las funciones de agregación excepto la función count ignoran los valores nulos del conjunto de datos de entrada de la función. En el caso de count si todos los valores del conjunto de datos son nulos entonces count devuelve 0, el resto de funciones devuelven un valor nulo en este caso. La existencia de valores nulos también complica el procesamiento de los operadores de agregación. Supóngase que algunas tuplas en la relación Préstamo tienen valor nulo para el atributo importe. Considérese en ese caso la siguiente consulta, que calcula el total de todas las cantidades prestadas: Solución: select sum(importe) from Prestamo En general, las funciones de agregación tratan los valores nulos según la regla siguiente: todas las funciones de agregación excepto count (*) ignoran los valores nulos de la colección de datos de entrada. Como resultado de ignorar los valores nulos, la colección de valores de entrada resulta vacía. 12