BLOQUE 3 (III): LENGUAJE SQL 3.13.- INTRODUCCIÓN SQL es un lenguaje estándar que permite realizar diferentes operaciones sobre datos almacenados en bases de datos relacionales, estas bases de datos se caracterizan porque la información está contenida en tablas. Aunque se ha traducido SQL (Structured Query Language) como lenguaje estructurado de consultas, en realidad el SQL permite organizar, gestionar y recuperar los datos de las bases de datos relacionales, permitiendo realizar modificaciones, operaciones aritméticas, combinacionales y lógicas con los datos. La representación de su funcionamiento puede ser la siguiente: Petición SQL ______ ______ ______ Datos Sistema de Gestión de Bases de Datos D.B.M.S. Base de Datos ______ ______ ______ Sistema Informático Se tiene un sistema informático que tiene una base de datos y el programa que controla la base de datos o Sistema de Gestión de Bases de Datos. Cuando se necesita recuperar datos de la base de datos, se utiliza SQL para realizar la petición, el SGBD procesa la petición, recupera los datos solicitados y los devuelve al usuario. Aunque su traducción parece indicar que el SQL solo permite realizar consultas sobre la Base de Datos, la realidad no es esa ya que permite realizar otras operaciones sobre ella, es un lenguaje de control e interacción con el Sistema de Gestión de la Base de Datos. Sin embargo no es un lenguaje de programación completo ya que carece de lo siguiente: . Sentencias condicionales . Sentencias de salto. . Sentencias repetitivas. 3.14.- HISTORIA DEL SQL La historia del SQL está unida al desarrollo de las bases de datos relacionales y su evolución ha sido constante para adaptarse a las nuevas tecnologías: - En junio de 1970, Codd de IBM publica un artículo en el que se recoge la base matemática para almacenar y manipular datos con estructura tabular. - De 1974 a 1979 se investiga en IBM sobre el campo relacional y sobre SQL. - En 1979 aparece Oracle y se convierte en el primer SGBD relacional comercial. - En 1982 ANSI (American National Standards Institute) forma el comité de estandares SQL. - En 1983, IBM anuncia DB2 - En 1986 se produce la revisión de ISO (International Standards Organization) ISO del SQL. - En 1987 aparece el estandar ISO. 3.15.-CARACTERISTICAS DEL SQL Las principales características de este lenguaje de gestión de bases de datos son: - Fundamento relacional: SQL es un lenguaje para bases de datos relacional. - Estructura de alto nivel: las sentencias de SQL paracen frases en inglés, por tanto es un lenguaje a nivel humano. - Estándares SQL: ANSI e ISO han publicado conjuntamente un estándar oficial. - Independencia de las casas que lo comercializan: El SQL forma parte de todos los productos SGBD y ningún producto orientado a las bases de datos podría tener éxito sin soportarlo. - Portabilidad: las aplicaciones basadas en SQL son facilmente portables de unos sistemas a otros. - Vistas múltiples de datos: mediante SQL el administrador de una base de datos puede dar diferentes vistas de los datos a distintos usuarios. - Lenguaje completo de base de datos: aunque en principio se desarrolló como un lenguaje para consulta, es más completo ya que permite crear una base de datos, gestionar su contenido, recuperar datos, etc.. - Definición dinámica de datos: la estructura de una base de datos puede modificarse y ampliarse de forma dinámica, incluso cuando los usuarios están accediendo a los datos. - Arquitectura cliente/servidor: sirve como enlace entre los sistemas “front-end” optimizados para la interacción del usuario y los sistemas “back-end” especializados para la gestión de bases de datos. 3.16.- FORMAS DE UTILIZACION - SQL se puede utilizar de forma interactiva como un lenguaje de consultas. - SQL embebido: las mismas sentencias que se utilizan de forma interactiva pueden formar parte de un programa escrito en un lenguaje de programación de propósito general. CTSQL puede utilizarse embebido en CTL. 3.17.-TIPOS DE LENGUAJE QUE INCORPORA SQL Está formado por cuatro sublenguajes: - DDL (Data Definition Language): Lenguaje de definición de datos, que comprende todas las instrucciones relativas a la definición de los elementos que componen una base de datos: creación de bases de datos, tablas, índices, etc.. - QL (Query Languaje): Lenguaje de consulta, que se encarga de extraer información de las tablas de la base de datos, está formado por la instrucción SELECT. - DML (Data Management Language): Lenguaje de manipulación de datos, se encarga del mantenimiento de los datos en la base de datos, permite actuar sobre las tablas de la base de datos, dando de alta nuevos valores, modificarlos o borrarlos. - DCL (Data Control Language): Lenguaje de control de acceso a datos, se encarga de conceder y retirar permisos a usuarios sobre las base de datos, tablas y columnas, también se encarga de los bloqueos o control de concurrencia entre usuarios. 3.18.- LENGUAJE DE DEFINICION DE DATOS (DDL) Es el sublenguaje encargado de la definición y mantenimiento de los elementos que se manejarán en una aplicación. OPERACIONES SOBRE LA BASE DE DATOS Sobre una base de datos se pueden realizar las siguientes operaciones: - Creación de la base de datos. Borrado de la base de datos. Selección de la base de datos con la que se va a trabajar. Cierre de la base de datos. Las operaciones correspondientes a la selección y cierre de la base de datos forman parte del lenguaje de manipulación de datos (DML). CREACIÓN DE UNA BASE DE DATOS Sintaxis: CREATE DATABASE base_datos [WITH LOG IN “fichero_log”] [COLLATING “fichero_ordenación”] Crea un subdirectorio con el nombre indicado (base_datos) y extensión (.dbs), dentro del directorio en curso en nuestro caso (G:\MB). WITH LOG IN : se utiliza para crear bases de datos transaccionales. COLLATING: para cambiar la tabla de caracteres. Dentro del directorio se crean ficheros con extensiones (.dat) y (.idx) son las tablas del catálogo (repositorio o diccionario) de la base de datos BORRADO DE UNA BASE DE DATOS. DROP DATABASE base_datos Borra el directorio de la base de datos y todas las tablas que haya generado. OPERACIONES CON TABLAS Los datos del sistema se almacenan en tablas de la base de datos, formadas por una o varias columnas. Cada tabla y cada columna debe tener un nombre que cumpla las codiciones dadas para los identificadores. Una columna se pueden nombrar mediante su identificador: EMPNUM o bien indicando la tabla a la que pertenece y su identificador: EMP.EMPNUM No debemos utilizar el mismo nombre para una tabla y para una columna Las operaciones que se pueden realizar sobre las tablas son: - Creación. Definición de la integridad referencial (lo estudiaremos más adelante). Modificación de la estructura de las tablas. Renombrado Borrado. CREACIÓN DE TABLAS Sintaxis de la instrucción: CREATE [TEMP] TABLE nombre_tabla( Nombre columna tipo_sql atributos, Nombre columna tipo_sql atributos,....) [IN “directorio”] [PRIMARY KEY (lista_columnas)] [FOREIGN KEY identificador (lista_columnas) REFERENCES nombre_tabla ON UPDATE {RESTRICT | SET NULL} ON DELETE {RESTRICT | SET NULL} [FOREIGN KEY ....] Cuando se crea una tabla aparecen dos ficheros con las extensiones (.dat) para los datos y (.idx) para los índices de la tabla, sus nombres están formados por: - Una parte alfabética, que se toma del nombre asignado a la tabla en el momento de su creación. - Una parte numérica, que es el número de identificación de la tabla dentro de la base de datos, es un número secuencial que comienza con 150 y cambia automáticamente cuando se modifica la estructura de la tabla. BORRADO DE UNA TABLA Sintaxis de la instrucción: DROP TABLE nombre_tabla Esta operación elimina los ficheros (.dat) y (.idx) asociados a la tabla y toda la información que contengan. MODIFICACIÓN DE LA ESTRUCTURA DE LAS TABLAS Se puede modificar la estructura de una tabla en cualquier momento, tengo o no datos, el cambio puede consistir en cualquiera de las operaciones siguientes: - Añadir una columna nueva. - Modificar el tipo o los atributos de una columna de la tabla (lo estudiaremos más adelante). Borrar una columna de la tabla. Añadir o borrar la clave primaria de la tabla (lo estudiaremos más adelante). Añadir o borrar claves referenciales de la tabla (lo estudiaremos más adelante). Sintaxis: ALTER TABLE nombre_tabla [ADD (nombre_columna tipo_sql atributos [BEFORE columna_existente],...)][,] [DROP (columna_existente)][,] [MODIFY (columna_existente atributos [REMOVE lista_atributos],...)][,] [PRIMARY KEY (lista_columnas)][,] [FOREIGN KEY identificador (lista_columnas) REFERENCES nombre_tabla ON UPDATE {RESTRICT | SET NULL} ON DELETE {RESTRICT | SET NULL}] [,] [DROP PRIMARY KEY] [,] [DROP FOREIGN KEY identificador] [,] Cuando se modifica la estructura de una tabla, se modifica el nombre de sus ficheros físicos ya que cambia el número de identificador interno de la tabla. RENOMBRAR UNA TABLA Esta operación realiza un cambio del nombre de una tabla, si tenemos una aplicación con varios módulos de programa, donde se utiliza esta tabla, habría que realizar el cambio del nombre de la tabla en todos ellos. Sintaxis: RENAME TABLE nombre_tabla TO nuevo_nombre_tabla OPERACIONES CON COLUMNAS La única operación que se puede realizar sobre un columna desde el DDL es cambiarla de nombre, esta operación puede traer problemas si estamos desarrollando una aplicación en la que diferentes módulos de programa trabajan con esta columna ya que habría que cambiar el nombre en todos los módulos. Sintaxis: RENAME nuevo_nombre_columna COLUMN nombre_tabla.nombre_columna TO 3.18.- LENGUAJE DE MANIPULACION DE DATOS Este sublenguaje comprende las siguientes operaciones: - Apertura y cierre de la base de datos. Inserción de filas Borrado de filas. Modificación de filas. OPERACIONES SOBRE LA BASE DE DATOS A.- APERTURA DE LA BASE DE DATOS Antes de trabajar con una base de datos hay que abrirla utilizando la instrucción: DATABASE base_datos [EXCLUSIVE] EXCLUSIVE: indica que se bloquea la base de datos para el resto de los usuarios. B.- CIERRE DE LA BASE DE DATOS En cada momento solamente puede estar activa una base de datos, por tanto si tenemos tenemos abierta una base de datos y queremos cambiar para trabajar en otra, debemos cerrar la primera base de datos con: CLOSE DATABASE OPERACIONES CON LAS FILAS A.- INSERCIÓN DE FILAS Sintaxis: INSERT INTO nombre_tabla [(columna, columna,...)] VALUES (valor, valor,....) Esta instrucción añade nuevas filas o tuplas a la tabla indicada (de una en una), asignando a las columna los valores que se indican. La inserción física de las nuevas filas se realiza secuencialmente en el orden de llegada en el fichero de datos (.dat). Para insertar un bloque de filas procedentes de otra tabla: INSERT INTO tabla [(columnas)] instrucción_select B.- BORRADO DE FILAS El borrado de filas consiste en marcar físicamente las filas que cumplan una determinada condición, no se realiza el borrado físico sino lógico. Sintaxis: DELETE FROM tabla [WHERE {condición_comparación | condición_subselect}] C.- MODIFICACIÓN DE FILAS Esta operación modifica los valores de las columnas de una tabla, de todas las columnas o de parte de ellas. Sintaxis: UPDATE tabla SET columna=expresión [,columna=expresión] [,...] [WHERE {condición_comparación | condición_subselect}] Si se incluye la cláusula WHERE, solamente cambiarán los valores de las filas que cumplan la condición impuesta por esta cláusula. 3.19.- LENGUAJE DE CONSULTAS (QL) a) SELECT [ALL | DISTINCT |UNIQUE] lista_select FROM lista_tablas [WHERE {condición_comparación | condición_subselect}] [GROUP BY lista_grupos] [ORDER BY columna [ASC | DESC] [, columna [ASC | DESC] [, ...] ] [INTO TEMP tabla_temporal] b) SELECT [ALL | DISTINCT | UNIQUE] lista_select FROM lista_tablas [WHERE {condición_comparación | condición_subselect}] [GROUP BY lista_grupos] [HAVING condición_grupos] [UNION [ALL] ] SELECT [ALL | DISTINCT | UNIQUE] lista_select FROM lista_tablas [WHERE {condición_comparación | condición_subselect}] [GROUP BY lista_grupos] [HAVING condición_grupos] [UNION [ALL] ] SELECT ... [ORDER BY columna [ASC | DESC] [, columna [ASC | DESC] [, ...] ] [INTO TEMP tabla_temporal ] CLAUSULA SELECT Es una de las claúsulas obligatorias, indica las columnas que tendrá la tabla derivada, su sintaxis es la siguiente: SELECT [ALL | DISTINCT | UNIQUE ] lista_select FROM lista_tablas ALL(*): palabra reservada que indica que se seleccionarán todas las filas que satisfagan la claúsula WHERE, si existe, sin eliminar las filas duplicadas, se utiliza por defecto. DISTINCT: palabra reservada que indica que se eliminarán las filas duplicadas que resulten de la selección, de cada grupo de filas duplicadas, solamente aparecerá una de ellas. UNIQUE: es un sinónimo de DISTINCT. Lista_select: lista de elementos separados por comas, como lista puede aparecer: *: se deben seleccionar todas las columnas de las tablas especificadas en la claúsula FROM. Tabla.*: indica que se seleccionarán todas las columnas de la tabla indicada. Expresión: cualquier expresión válida de CTSQL. Expresión [alias]: un alias es un nombre que se asigna a la expresión en una instrucción SELECT. Los alias de las columnas solo se pueden utilizar en las claúsulas ORDER BY e INTO TEMP. PREDICADOS PARA LA CLÁUSULA WHERE WHERE condición PREDICADOS BÁSICOS Expresan condiciones de comparación entre dos valores, se utilizan operadores relacionales (<, >, =, <>, <= y >=). Si los valores que se comparan son no nulos tendremos un resultado verdadero en los siguientes casos: Predicado X=Y X <> Y X<Y X>Y X <= Y X >= Y Es ‘Verdadero’ si, y solo si X es igual a Y X no es igual a Y X es menor que Y X es mayor que Y X es menor o igual que Y X es mayor o igual que Y Si alguno de los comparandos, X o Y, o los dos son desconocidos, el resultado toma el valor ‘Desconocido’, en el resto de los casos el resultado será ‘Falso’. PREDICADO NULL Expresión IS [NOT] NULL Devuelve ‘Verdadero’ o ‘Falso’ en caso de que el resultado de la expresión sea o no un valor nulo. La partícula NOT invierte el resultado. No puede tomar el valor ‘Desconocido’ ya que el resultado de la expresión es nulo o no es nulo. PREDICADO BETWEEN Expresión [NOT] BETWEEN expresión_desde AND expresión_hasta Esta condición devuelve verdadero o falso en caso de que el resultado de una expresión esté comprendido o no en el rango dado por las otras dos expresiones, y tomará el valor ‘Desconocido’, si alguna de las expresiones que intervienen toma dicho valor. La partícula NOT invierte el resultado. Expresión: cualquier expresión válida. NOT: palabra reservada que invierte el resultado. BETWEEN: palabra reservada que indica el rango. Expresión_desde: el resultado de esta expresión indica el valor inicial del rango y está incluido en el rango. Expresión_hasta: el resultado de esta expresión indica el valor final del rango, también está incluido en el rango y debe ser mayor que el valor que tome expresión_desde. PREDICADO LIKE Expresión [NOT] LIKE “literal” Condición de comparación de expresiones de tipo alfanumérico, solamente se podrá aplicar a las columnas de tipo CHAR. Devuelve verdadero o falso en caso de que el resultado de la expresión se ajuste o no al patrón definido en literal. Expresión: cualquier expresión de tipo alfanumérico válida. NOT: partícula que invierte el resultado. LIKE: palabra reservada “literal”: patrón con el que se va a comparar el resultado de la expresión. Puede contener dos caracteres con significados especiales que pueden aparecer más de una vez: %: el lugar ocupado por este carácter podrá estar ocupado por ningún, por uno o por más de un carácter. _(subrayado): se tiene que sustituir obligatoriamente por un carácter. PREDICADO IN Expresión [NOT ] IN (lista_valores) Esta condición devuelve verdadero o falso en caso de que el resultado de la expresión sea igual o no a uno de los valores indicados en lista_valores. Expresión: cualquier expresión válida. NOT: partícula que invierte el resultado. IN: palabra reservada. Lista_valores: lista de valores separados por comas y encerrados entre paréntesis, los valores serán del mismo tipo que el resultado de la expresión. Los valores de tipo CHAR, TIME y DATE tienen que ir entre comillas. PREDICADO MATCHES Expresión [NOT] MATCHES “literal” Solo se puede aplicar a columnas de tipo CHAR, es igual a LIKE salvo que permite utilizar más caracteres para formar el literal: *: el lugar ocupado por este carácter se puede sustituir por ninguno, uno o varios caracteres. ?: se debe sustituir obligatoriamente por un carácter. [caracteres]: los corchetes indican que cualquiera de los caracteres incluidos entre ellos pueden aparecer en la posición que ocupan dentro del literal. Se puede indicar un rango de caracteres separando el inicial y el final por un guión. [^caracteres]: similar al anterior, pero el carácter ^ indica que los caracteres o rangos no pueden aparecer en la posición que ocupan dentro del literal. \: indica que el carácter al que precede no debe ser considerado como metacarácter sino un carácter más dentro del literal. CONDICIÓN DE SUBSELECCIÓN Una condición subselect consiste en comparar una expresión, que generalmente será una columna, con una tabla derivada devuelta por otra instrucción SELECT. Hay tres formas de realizar condiciones subselect: A.- Expresión operador_relación {ALL | [ANY | SOME] } (subselect) Devuelve verdadero o falso dependiendo de si se cumple o no cierta relación entre el resultado de la expresión y el resultado de una subquery, en función del operador que intervenga. Expresión: cualquier expresión válida. Generalmente será una columna de la tabla cuyos datos generarán la tabla derivada. Operador_relación: puede ser cualquiera de los siguientes (=, != o <>, >, >=, <, <=). Subselect: instrucción SELECT cuya lista_select solo podrá contener una columna en la tabla derivada que genere, esta columna deberá ser del mismo tipo de dato que la columna que condiciona expresión. ALL: indica que el resultado de la comparación debe ser verdadero para cada uno de los valores devueltos por la subselect. ANY: indica que el resultado de la comparación debe ser verdadero al menos en uno de los valores devueltos por la instrucción subselect. SOME: sinónimo de ANY. B.- Expresión [NOT] IN (subselect) Devuelve verdadero o falso dependiendo de si se cumple o no cierta relación entre expresión y el resultado de la instrucción subselect. Subselect: instrucción SELECT cuya selección solo podrá contener una columna en la tabla derivada que genere, la columna debe ser del mismo tipo de dato que la columna que condiciona expresión. NOT: invierte el resultado. IN: pregunta si expresión es alguno de los valores devueltos por subselect. (La partícula IN puede simularse por la subselect ANY, y la partícula NOT IN puede reemplazarse por la subselect “!=ALL”. C.- [NOT] EXISTS (subselect) esta condición devuelve verdadero o falso dependiendo de si existe o no alguna fila resultado de la instrucción subselect. La partícula NOT invierte el resultado. EXISTS: evalua la existencia o no de alguna fila en la tabla derivada de la instrucción subselect. Subselect: instrucción SELECT válida. La lista_select de esta instrucción puede contener más de una columna o expresión, ya que esta no se utilizará para la comparación de expresiones de la condición. ALIAS Un alias es un nombre alternativo que se asigna en una instrucción de lectura (SELECT), a una tabla o columna. El alias se construye de la misma forma que un identificador de la base de datos pero admite letras en mayúsculas. El alias de una columna se utiliza para mostrar una etiqueta concreta a esa columna cuando se muestra la tabla derivada resultante de la instrucción SELECT. Este renombrado es temporal y solo tiene validez mientras se está ejecutando la instrucción SELECT, de forma que se puede utilizar en la cláusula ORDER BY. SELECT NOMEM, (SALAR+COMIS) SALARIO FROM TEMPLE WHERE COMIS IS NOT NULL ORDER BY SALARIO Los alias de tablas son especialmente importantes cuando se desea enlazar una tabla consigo misma. FUNCIONES DE VALORES AGREGADOS: Permiten obtener un solo valor como resultado de aplicar una operación a los valores contenidos en una columna de una tabla. Se utilizan en una instrucción SELECT como resultado a obtener y ese resultado es siempre una tabla con una sola fila y tantas columnas como expresiones haya en la lista_select. El argumento de estas funciones puede ser el nombre de una columna o una expresión en la que intervienen nombres de columnas: SELECT SUM(A), (MAX(A)+MAX(B*3))/2 Donde A y B serían columnas. COUNT(*): devuelve el número de filas que cumplen la cláusula WHERE de la instrucción SELECT: SELECT COUNT(*) FROM TEMPLE WHERE SALAR >200 Cuenta el número de filas de la tabla TEMPLE en las que SALAR es mayor que 200. COUNT(DISTINCT X): devuelve el número de valores únicos en la columna X en las filas que cumplen la cláusula WHERE de la instrucción SELECT: SELECT COUNT (DISTINCT SALAR) FROM TEMPLE WHERE SALAR > 200 Cuenta el número de filas de la tabla TEMPLE en las que SALAR > 200, pero solamente cuenta una vez los valores que se repiten. SUM([DISTINCT] X): se utiliza con columnas numéricas y devuelve la suma de todos los valores de la columna X para las filas que cumplen la cláusula WHERE. Si se utiliza la palabra clave DISTINCT el resultado es la suma de los valores distintos de la columna X. AVG([DISTINCT] X): se utiliza con columnas numéricas y devuelve el valor medio de todos los valores de la columna X para las filas que cumplen la cláusula WHERE. Si se utiliza la palabra clave DISTINCT, el resultdo será el valor medio de los valores distintos de la columna X. MAX(X): devuelve el valor máximo de la columna X de aquellas filas que cumplen la cláusula WHERE. MIN(X): devuelve el valor mínimo de la columna X de aquellas filas que cumplen la cláusula WHERE. NOTAS: 1.- La cláusula WHERE solo se puede utilizar en las siguientes instrucciones: SELECT, UPDATE y DELETE. 2.- En las funciones SUM(X), AVG(X), MAX(X) y MIN(X), X puede ser una expresión en vez de una columna. En este caso la expresión se evalúa sobre los valores de la expresión en las columnas que cumplan la cláusula WHERE correspondiente. 3.- La palabra clave DISTINCT solo se puede utilizar con columnas, nunca con expresiones. 4.- La palabra clave DISTINCT solo se puede utilizar una vez en una SELECT. 5.- Los valores nulos que pueda tener una columna afectan a los valores agregados de la siguiente manera: - COUNT(*) cuenta las filas aunque el valor de la columna sea nulo. COUNT(DISTINCT X), AVG(X), SUM(X), MAX(X) y MIN(X) ignoran las filas que contienen valores nulos en la columna X, pero si la columna X solo tiene valores nulos devulve el valor NULL para esa columna. 3.20.- CONSULTAS CON AGRUPAMIENTOS: GROUP BY, HAVING Vamos a estudiar como se pueden formar grupos de filas en una tabla aplicando un determinado criterio, despues de agruparlas, podremos aplicar funciones colectivas a cada grupo. CLÁUSULA GROUP BY Sintaxis: SELECT lista_select FROM lista_tablas [WHERE {condición_comparación | condición_subselect}] [GROUP BY lista_grupos] [ORDER BY columna [ASC | DESC][,...]] lista_grupos: nombre de columna, o lista de nombres de columnas separados por comas, que determinan como se van a agrupar las filas, formarán un mismo grupo todas las filas que tengan el mismo valor en las columnas de agrupamiento. Los valores nulos de las columnas de agrupamiento se consideran distintos y por tanto cada una forma un grupo diferente. En vez de los nombres de las columnas, se pueden utilizar números enteros que indican la posición que ocupan las columnas en la lista_select. Es obligatorio utilizar números cuando los elementos de la lista_select por los que se quiere agrupar son expresiones en vez de columnas. NOTAS: - El máximo número de columnas que se puede incluir en la cláusula GROUP BY es 8, y en total la suma de las longitudas de las columnas no debe superar 120 bytes. En la lista_select de la instrucción SELECT no se pueden indicar columnas que no estén incluidas en la cláusula GROUP BY. Cuando en la lista_select se incluye una función de valores agregados junto a otras columnas, obligatoriamente requiere utilizar grupos por dichas columnas no agregadas. No es obligatorio introducir una función de valor agregado en la lista_select de una instrucción SELECT con cláusula GROUP BY. SELECT numde FROM temple GROUP BY numde ORDER BY numde El resultado de la instrucción SELECT será una fila por cada uno de los grupos constituidos y tantas columnas como se indiquen en lista_select. CLÁUSULA HAVING Se utiliza para descartar filas de grupos que no cumplan una determinada condición. Sintaxis: SELECT lista_select FROM lista_tablas [WHERE {condición_comparación | condición_subselect}] [GROUP BY lista_grupos] [HAVING condición_grupos] [ORDER BY columna [ASC | DESC][,...]] condición_grupos: cualquier condición de las que hemos estudiado para la cláusual WHERE en la instrucción SELECT. La condición puede estar formada por una lista de condiciones unidas por AND u OR. Una de las expresiones que componen la condición obligatoriamente debe ser una función de valor agregado. Si la instrucción SELECT de la que forma parte la cláusula HAVING, no tiene cláusula GROUP BY, se considera que toda la tabla forma un grupo. PASOS PARA EJECUTAR UNA SENTENCIA SELECT 1.- Ejecutar la cláusula FROM: seleccionar la tabla con la que vamos a trabajar. 2.- Ejecutar la cláusula WHERE: eliminar de la tabla resultante anterior las filas que no cumplan las condiciones indicadas en la cláusula WHERE. 3.- Ejecutar la cláusula GRUOP BY: formar los grupos con las filas de la tabla resultante en el punto anterior, que tengan los mismos valores en las columnas de agrupamiento. 4.- Ejecutar la cláusula HAVING: descartar los grupos que no satisfagan la condición indicada en la cláusula HAVING. 5.- Ejecutar la cláusula SELECT: evaluar las expresiones para cada grupo, produciendo por cada uno de ellos una fila en la tabla resultante, tendrá tantas columnas como expresiones tenga la SELECT. Si se ha incluido DISTINCT, se eliminan las filas repetidas. 6.- Ejecutar la cláusula ORDER BY: la tabla resultante en el apartado anterior se ordena de acuerdo con los valores de las columnas indicadas en la cláusula ORDER BY.