Capítulo 4 CLASE 4

4.1 Consulta de datos de SQL

Aca debé descargar del aula MOODLE el archivo DATOS INVENTARIO para que pueda probar los ejemplos.

4.2 SELECT

La instrucción SELECT es una expresión de consulta que comienza con la palabra clave SELECT e incluye una serie de elementos que forman la expresión. La sintaxis básica para la instrucción SELECT puede dividirse en varias cláusulas específicas, cada una de las cuales ayuda a refinar la consulta para que sólo se devuelvan los datos requeridos. La sintaxis para la instrucción SELECT puede mostrarse como sigue:

SELECT [ DISTINCT | ALL ] { * | < selección de lista > }

FROM [ {, }… ]

[ WHERE ]

[ GROUP BY ]

[ HAVING ]

[ ORDER BY ]

Para resumir todo esto, las cláusulas de la instrucción SELECT se aplican en el siguiente orden:

  • Cláusula FROM
  • Cláusula WHERE (opcional)
  • Cláusula GROUP BY (opcional)
  • Cláusula HAVING (opcional)
  • Cláusula ORDER BY (opcional)

Es importante tener un entendimiento básico del orden de evaluación al crear instrucciones SELECT más complejas.

Como se puede observar, las únicas cláusulas requeridas son la cláusula SELECT y la cláusula FROM. Todas las demás cláusulas son opcionales.

La cláusula SELECT incluye las palabras clave DISTINCT y ALL. La palabra clave DISTINCT se utiliza si se desean eliminar filas duplicadas de los resultados de la consulta, y la palabra clave ALL se utiliza si se quieren devolver todas las filas de los resultados de una consulta.

Además de las palabras clave DISTINCT y ALL, la cláusula SELECT incluye el asterisco (*) y el marcador de posición . Se debe especificar una de estas opciones en la cláusula. Si se especifica el asterisco, todas las columnas aplicables se incluyen en el resultado de la consulta. Si no se especifica el asterisco en la cláusula SELECT, se debe especificar cada columna tal como se deriva del origen. El marcador de posición se puede desglosar en la siguiente sintaxis:

< columna derivada > [ [AS] < nombre de la columna > ] [ {, < columna derivada > [ [AS] < nombre de la columna >] }… ]

Poer ejemplo, la instrucción SELECT puede generar los promedio de los valores en tres diferentes columnas, como se muestra en la siguiente instrucción SELECT:

SELECT AVG(AÑO_1999), AVG(AÑO_2000), AVG(AÑO_2001)

FROM COMISIONES_EMPLEADO;

Hay tres expresiones que se utilizan para el marcador de posición : AVG(AÑO_1999), AVG(AÑO_2000) y AVG(AÑO_2001).

SELECT AÑO_1999, AÑO_2000, AÑO_2001

FROM COMISIONES_EMPLEADO;

La cláusula SELECT también permite proporcionar un nombre de columna para cada columna derivada. Para hacer esto, se añade la palabra clave AS y el nuevo nombre de columna después de la columna derivada, como se muestra en el siguiente ejemplo:

SELECT AVG(AÑO_1999) AS PROMEDIO_1999

FROM COMISIONES_EMPLEADO;

En esta instrucción SELECT, el valor que se devuelve de la columna AÑO_1999 se coloca en la columna llamada PROMEDIO_1999. Éste es el nombre de la columna que se devuelve como parte de una tabla virtual en los resultados de la consulta. Si no se especifica la subcláusula AS, el nombre de columna en la tabla virtual es el mismo que el nombre de columna en la tabla origen.

Observe que en los ejemplos anteriores la cláusula FROM se utiliza para especificar la tabla (COMISIONES_EMPLEADO) que contiene las columnas mencionadas en la cláusula SELECT. La cláusula FROM incluye la palabra clave FROM y una o más tablas de referencia. Si hay varias tablas de referencia, deben separarse utilizando comas.

Juntas las cláusulas SELECT y FROM forman las bases para la instrucción SELECT, que puede ser tan simple como consultar cada fila y cada columna de una tabla, como se muestra en el siguiente ejemplo:

SELECT * FROM INTERPRETES;

Ahora suponga que desea devolver sólo las columnas NOMBRE_INTERPRETE y LUGAR_ DE_NACIMIENTO. Se puede modificar la instrucción SELECT para verse como la siguiente:

SELECT NOMBRE_INTERPRETE AS NAME, LUGAR_DE_NACIMIENTO

FROM INTERPRETES;

Los resultados de la consulta ahora contienen sólo dos columnas, como se muestran a continuación:

Observe que el nombre de la primera columna es NOMBRE, en lugar de NOMBRE_INTERPRETE. Esto es debido a que la subcláusula AS (especificada en NOMBRE) se define como parte de la columna derivada NOMBRE_INTERPRETE.

Ahora veamos un ejemplo que utilice la palabra clave DISTINCT. Suponga que la base de datos incluye una tabla que empareje a los intérpretes con los tipos de música, como se muestra en la figura

Si la instrucción SELECT incluye ambas (todas) columnas en la cláusula SELECT, como se muestra en el siguiente ejemplo, la consulta devolvería todas las filas:

SELECT * FROM TIPO_INTERPRETE;

No importa si se especifica la palabra clave DISTINCT en este caso, ya que los resultados de la consulta no incluyen filas duplicadas. Los resultados serían los mismos si se incluyera la palabra clave ALL, en lugar de DISTINCT, o si no se especifican ninguno de los dos calificadores. En ambos casos, los resultados de la consulta incluyen la misma información que se muestra en la tabla de la figura anterior.

Ahora echemos un vistazo a la misma instrucción, sólo que esta vez se especifica la palabra clave DISTINCT y sólo una de las dos columnas:

SELECT DISTINCT NOMBRE_INTERPRETE

FROM TIPO_INTERPRETE;

Observe que esta instrucción incluye sólo la columna NOMBRE_INTERPRETE, que incluye valores duplicados. Mediante el uso de la palabra clave DISTINCT, los resultados de la consulta incluirían sólo un ejemplo de cada uno de los valores. Si se ejecuta la instrucción SELECT en el ejemplo anterior, los resultados de la consulta serían similares a los siguientes:

    NOMBRE_INTERPRETE
    -----------------
    Jennifer Warnes
    Joni Mitchell
    Kitaro
    William Ackerman

Aunque hay siete filas en la tabla TIPO_INTERPRETE, sólo se devuelven cuatro filas, ya que existen sólo cuatro valores únicos en la columna NOMBRE_INTERPRETE y los demás valores son duplicados.

4.3 WHERE

La cláusula WHERE toma los valores devueltos por la cláusula FROM (en la tabla virtual) y aplica la condición de búsqueda que se define en la cláusula WHERE. La cláusula WHERE actúa como filtro sobre los resultados devueltos por la cláusula FROM.

La condición de búsqueda se compone de uno o más predicados que se utilizan para poner a prueba el contenido devuelto por la cláusula FROM. Un predicado es una expresión de SQL que define un hecho acerca de cualquier fila devuelta por la instrucción SELECT.

SELECT TITULO_CD, DERECHOSDEAUTOR, EN_EXISTENCIA

FROM INVENTARIO_DISCO_COMPACTO

WHERE DERECHOSDEAUTOR > 1989 AND DERECHOSDEAUTOR < 2000;

Esta instrucción consulta tres columnas en la tabla INVENTARIO_DISCO_COMPACTO. La cláusula SELECT especifica las columnas que se devuelven, y la cláusula FROM especifica la tabla origen. La cláusula WHERE determina qué filas (basado en la cláusula FROM) se incluyen en los resultados. En este caso, la cláusula WHERE contiene dos predicados que se conectan por la palabra clave AND. El primer predicado (DERECHOSDEAUTOR > 1989) especifica que todas las filas incluidas en los resultados de la consulta deben contener un valor mayor que 1989 en la columna DERECHOSDEAUTOR. El segundo predicado (DERECHOSDEAUTOR < 2000) especifica que todas las filas incluidas en los resultados de la consulta deben contener un valor menor que 2000 en la columna DERECHOSDEAUTOR.

Cada predicado evalúa como verdadero, falso o desconocido. Si se incluye más de un predicado en la cláusula WHERE, éstos se unen por la palabra clave OR o por la palabra clave AND:

4.4 OR

se utiliza OR, entonces al menos uno de los predicados de cualquier lado de OR debe evaluar como verdadero para que la fila pase el filtro, y por lo tanto aparece en los resultados de la consulta. Es decir, se toma uno Ó el otro, no necesariamente ambos.

La tabla enumera la evaluación de una condición de búsqueda si la palabra clave OR se utiliza para separar dos predicados:

pareje una condición de la columna de la izquierda a una condición en la fila superior. El resultado (donde una fila y una columna se intersectan para formar una celda) muestra cómo la condición de búsqueda se evalúa sobre la base de cómo se evalúa cada predicado.

Como muestra la tabla, si ambos predicados evalúan como verdadero, entonces la condición de búsqueda evalúa como verdadero. Si ambos son falsos, entonces la condición de búsqueda evalúa como falso.

Se proporciona una condición para cada posible encuentro. Por ejemplo, suponga que la instrucción SELECT incluye la siguiente cláusula WHERE:

WHERE TIPO_INTERPRETE = ‘Folk’ OR TIPO_INTERPRETE = ‘Jazz’

Ahora suponga que el primer predicado en este ejemplo (TIPO_INTERPRETE = ‘Folk’) evalúa como verdadero y el segundo predicado (TIPO_INTERPRETE = ‘Jazz’) evalúa como falso. Esto significa que la fila evaluada contiene el valor Folk en la columna TIPO_INTERPRETE, pero no contiene el valor Jazz en esa columna.

Si selecciona Verdadero de la primera columna, selecciona Falso de la fila superior, y luego empareja estos dos valores (buscando dónde se intersectan), se puede observar que la condición de búsqueda evalúa como verdadero; por lo tanto, la fila se incluye en los resultados de la consulta.

4.5 AND

Si se utiliza AND entonces los predicados de cualquier lado deben evaluar como verdaderos para que la fila pase el filtro. Obligatoriamente AMBOS.

Veremos un poco mas de estos predicados mas adelante.

Si una condición de búsqueda incluye más de dos predicados, los predicados se evalúan de acuerdo con un orden escogido por el RDBMS, a menos que se utilicen paréntesis para separar las combinaciones de predicados.

Como se puede observar, la palabra clave AND es mucho menos indulgente que la palabra clave OR. La única manera para que la condición de búsqueda evalúe como verdadero es que ambos predicados evalúen como verdaderos:

Si una condición de búsqueda incluye más de dos predicados, los predicados se evalúan de acuerdo con un orden escogido por el RDBMS, a menos que se utilicen paréntesis para separar las combinaciones de predicados.

Por ejemplo, se tiene la instrucción SELECT que incluye la siguiente cláusula WHERE:

WHERE EN_EXISTENCIA = 6 OR EN_EXISTENCIA = 27 AND ID_DISQUERA = 833 OR ID_DISQUERA = 829

Observe que hay cuatro predicados en esta cláusula y no hay paréntesis. Asumiendo que se evalúa AND antes que OR, la anterior cláusula WHERE se evaluaría como si se escribiera de esta manera:

WHERE EN_EXISTENCIA = 6 OR (EN_EXISTENCIA = 27 AND ID_DISQUERA = 833) OR ID_DISQUERA = 829

Con el fin de evaluar como verdadero, una fila debe contener uno de los siguientes valores o conjunto de valores:

EN_EXISTENCIA valor de 6 EN_EXISTENCIA valor de 27 y ID_DISQUERA valor de 833 ID_DISQUERA valor de 829

Cuando se incluyen ambas palabras clave AND y OR en la misma cláusula WHERE, siempre es una buena idea incluir paréntesis para asegurar que se reciba el filtrado intentado, teniendo en cuenta que los predicados entre paréntesis se evalúan siempre primero.

Si los RDBMS hacen otras suposiciones, o si los paréntesis se utilizan alrededor de otros conjuntos de predicados, los resultados serán diferentes de lo que se ha visto. Por ejemplo, suponga que utiliza los paréntesis de la siguiente manera:

WHERE (EN_EXISTENCIA = 6 O EN_EXISTENCIA = 27) AND (ID_DISQUERA = 833 O ID_DISQUERA = 829)

Los predicados primero se evalúan dentro del contexto de los paréntesis y luego se comparan con otros predicados en consecuencia. En este caso, una fila debe contener uno de los dos valores EN_EXISTENCIA y la fila debe contener uno de los dos valores ID_DISQUERA. Como resultado, una fila debe contener uno de los siguientes conjuntos de valores para evaluar como verdadero:

Valor de EN_EXISTENCIA de 6 y valor de ID_DISQUERA de 833 Valor de EN_EXISTENCIA de 6 y valor de ID_DISQUERA de 829 Valor de EN_EXISTENCIA de 27 y valor de ID_DISQUERA de 833 Valor de EN_EXISTENCIA de 27 y valor de ID_DISQUERA de 829

4.6 NOT

Puede utilizarse sola o junto con las palabras clave AND y OR para especificar el inverso de un predicado. Por ejemplo, la instrucción SELECT puede incluir la siguiente cláusula WHERE:

WHERE NOMBRE_INTERPRETE = ‘Joni Mitchell’ OR NOT NOMBRE_INTERPRETE = ‘Kitaro’

En este caso, el valor NOMBRE_INTERPRETE puede ser Joni Mitchell o puede ser cualquier valor distinto de Kitaro. Por supuesto, Joni Mitchell no es igual que Kitaro, de modo que el predicado es redundante y se obtiene el mismo resultado si se elimina

4.6.1 EJEMPLOS:

Ahora que tiene una visión general de cómo definir la cláusula WHERE, pongamos juntas las cláusulas SELECT y FROM y veamos algunos ejemplos. Los ejemplos que veremos se basan en la tabla INVENTARIO, mostrada:

La tabla INVENTARIO contiene cinco columnas, algunas de las cuales utilizaremos para definir nuestras condiciones de búsqueda.

El primer ejemplo que veremos incluye la cláusula WHERE, que define qué filas se pueden devolver basadas en los valores EN_EXISTENCIA:

SELECT * FROM INVENTARIO

WHERE EN_EXISTENCIA < 20;

Si ejecuta esta instrucción, los resultados serán similares a los siguientes:

Las filas no incluidas contienen valores EN_EXISTENCIA mayores que 20.

SELECT * FROM INVENTARIO

WHERE EN_EXISTENCIA < 20 AND PRECIO_MENUDEO < 15.00;

Cuando se ejecuta esta instrucción, se reciben los siguientes resultados:

Sólo estas dos filas tienen un valor EN_EXISTENCIA menor que 20 y un valor PRECIO_MENUDEO menor que 15.00. Debido a que se utiliza la palabra clave AND, ambos predicados deben evaluar como verdadero, que se aplica para estas dos filas.

SELECT * FROM INVENTARIO

WHERE EN_EXISTENCIA < 20 AND NOT PRECIO_MENUDEO < 15.00;

La palabra clave NOT cambia los resultados de la consulta. Como se puede observar, tres filas se devuelven:

Cada una de las filas devueltas contiene un valor EN_EXISTENCIA menor que 20 y un valor PRECIO_MENUDEO que no es menor que 15.00, o 15.00 o mayor.

en esta ocasión los dos predicados se conectan por la palabra clave OR, como se muestra en el siguiente ejemplo:

SELECT * FROM INVENTARIO

WHERE EN_EXISTENCIA < 20 OR PRECIO_MENUDEO < 15.00;

la palabra clave OR permite que existan mayores oportunidades para que la búsqueda de la cláusula evalúe como verdadera:

Cada fila en los resultados de la búsqueda contiene un valor EN_EXISTENCIA menor que 20 o un valor PRECIO_MENUDEO menor que 15.00. Debido a que la palabra clave OR se utiliza, sólo uno de los predicados necesita evaluar como verdadero, aunque es aceptable si ambos predicados evalúan como verdadero.

En el siguiente ejemplo se añade un predicado más que limita las filas devueltas a aquellas con un valor EN_EXISTENCIA mayor que 5, puesto entre paréntesis para hacerlo claro:

SELECT * FROM INVENTARIO

WHERE (EN_EXISTENCIA < 20 AND EN_EXISTENCIA > 5) OR PRECIO_MENUDEO < 15.00;

Para devolver una fila, el valor EN_EXISTENCIA debe estar entre el rango de 5 y 20 o el valor PRECIO_MENUDEO debe ser menor que 15.00. Los resultados de la consulta de esta instrucción SELECT serían como sigue:

Ahora hagamos un cambio más a la cláusula WHERE. Suponga que desea que el valor EN_ EXISTENCIA sea menor que 20 y mayor que 5 o el valor EN_EXISTENCIA sea menor que 20 y el valor PRECIO_MENUDEO sea menor que 15. Una forma de hacer esto es colocando paréntesis en los últimos dos predicados:

SELECT * FROM INVENTARIO

WHERE EN_EXISTENCIA < 20 AND (EN_EXISTENCIA > 5 OR PRECIO_MENUDEO < 15.00);

Los resultados recibidos en esta ocasión son algo diferentes ya que la fila Blue ya no evalúa como verdadero:

4.7 GROUP BY

la cláusula GROUP BY se utiliza para agrupar tipos de información con el fin de resumir datos relacionados.

la sintaxis para la cláusula GROUP BY, como aparece en la sintaxis de la instrucción SELECT, se ve como se muestra a continuación:

[ GROUP BY ]

Sin embargo, el marcador de posición se puede dividir en elementos más pequeños:

[ {,< nombre de columna > }… ]

|{ ROLLUP | CUBE }( < nombre de columna > [ { , }… ] )

En realidad, la sintaxis , como algunas de las otras sintaxis en este libro, es incluso más compleja de la que se presenta aquí; sin embargo, para propósitos de este capítulo, esta sintaxis proveerá los detalles necesarios para usar la cláusula GROUP BY de manera efectiva.

Se usará la cláusula GROUP BY para agrupar filas basadas en la columna CATEGORIA de la tabla EXISTENCIA_ DISCO_COMPACTO, como se muestra en la siguiente instrucción SELECT:

SELECT CATEGORIA, SUM(A_LA_MANO) AS TOTAL_A_LA_MANO FROM EXISTENCIA_DISCO_COMPACTO GROUP BY CATEGORIA;

Primero echemos un vistazo a la cláusula GROUP BY, que especifica qué filas se deben agrupar basadas en la columna CATEGORIA. Si observa la figura:

verá que la columna contiene sólo dos valores: Vocal o Instrumental. Como resultado, la instrucción SELECT sólo devuelve dos columnas, una para Instrumental y otra para Vocal:

Lo que hace esta instrucción, entonces, es añadir los valores totales A_LA_MANO para cada valor en la columna CATEGORIA. En este caso, hay un total de 217 CD en existencia que entran en la categoría de interpretados, y 78 en existencia que entran en la categoría de instrumentales. Si hubiera otra categoría, entonces aparecería otra fila para ésa también.

suponga que desea ver los totales sólo de los CD que se vendieron por menos de $16.00. Para hacer esto, simplemente modifique la instrucción SELECT como se muestra a continuación:

SELECT CATEGORIA, SUM(A_LA_MANO) AS TOTAL_A_LA_MANO FROM EXISTENCIA_DISCO_COMPACTO WHERE PRICE < 16.00 GROUP BY CATEGORIA;

Los resultados de la consulta de esta instrucción serían ligeramente diferentes si no se incluyera la cláusula WHERE:

Observe que como los CD que se venden por $16.00 o más se excluyen, los resultados ahora muestran sólo 28 CD instrumental y 172 CD vocal.

También se pueden especificar columnas adicionales como sea necesario:

SELECT CATEGORIA, PRECIO, SUM(A_LA_MANO) AS TOTAL_A_LA_MANO

FROM EXISTENCIA_DISCO_COMPACTO

GROUP BY CATEGORIA, PRECIO;

Ahora los resultados de la consulta incluyen seis filas, en lugar de dos:

Observe que para cada valor en CATEGORIA, hay tres filas, una para cada uno de los valores PRECIO. Por ejemplo, en el grupo Vocal, hay 99 CD a 14.99, 73 CD a 15.99 y 45 CD a 16.99.

Ahora echemos un vistazo a los operadores ROLLUP y CUBE. Ambos operadores son similares en funcionamiento, ya que devuelven datos adicionales en los resultados de la consulta cuando se añade la cláusula GROUP BY. La principal diferencia entre los dos es que el operador CUBE devuelve más información que el operador ROLLUP. Empecemos con el ejemplo del operador ROLLUP para que se pueda demostrar la diferencia. En la siguiente instrucción SELECT, en la cláusula GROUP BY aplica el operador ROLLUP a las columnas CATEGORIA y PRECIO:

SELECT CATEGORIA, PRECIO, SUM(A_LA_MANO) AS TOTAL_A_LA_MANO

FROM EXISTENCIA_DISCO_COMPACTO

GROUP BY ROLLUP (CATEGORIA, PRECIO);

Ahora cuando se ejecute la instrucción SELECT, los resultados de la consulta incluyen una fila adicional para cada valor en la columna CATEGORIA, además de una fila con el gran total al final:

Las dos filas adicionales de CATEGORIA proporcionan los totales para cada valor en la columna CATEGORIA. En el ejemplo anterior, el grupo Instrumental incluye un total de 78 CD, y el grupo Vocal incluye un total de 217 CD. Observe que la columna PRECIO incluye un valor nulo para estas filas en particular. Un valor no se puede calcular para esta columna, ya que los tres subgrupos (de la columna PRECIO) se representan aquí. La última fila (la fila con NULL para ambas columnas CATEGORIA y PRECIO) contiene el gran total de todos los CD incluidos por la consulta (ambas categorías de grupos y los tres subgrupos de precios).

El operador CUBE devuelve los mismos datos que el operador ROLLUP y algunos otros. Observe que en la siguiente instrucción SELECT, simplemente se reemplazó la palabra clave CUBE por ROLLUP:

SELECT CATEGORIA, PRECIO, SUM(A_LA_MANO) AS TOTAL_A_LA_MANO

FROM EXISTENCIA_DISCO_COMPACTO

GROUP BY CUBE (CATEGORIA, PRECIO);

Esta instrucción devuelve los siguientes resultados de la consulta:

Se puede observar que tres filas adicionales se añaden a los resultados de la consulta, una fila para cada valor diferente en la columna PRECIO. A diferencia del operador ROLLUP, el operador CUBE resume los valores para cada subgrupo. También observe que un valor nulo se muestra para la columna CATEGORIA para esas filas. Esto es debido a que ambos valores (vocal e instrumental) se incluyen en el resumen de cada subgrupo.

4.8 HAVING

La cláusula HAVING se refiere a grupos, no a filas individuales:

Si se especifica la cláusula GROUP BY, la cláusula HAVING se aplica a los grupos creados por la cláusula GROUP BY.

Si se especifica la cláusula WHERE y no se especifica la cláusula GROUP BY, la cláusula HAVING se aplica a la salida de la cláusula WHERE y se trata esa salida como un grupo.

Si no se especifica la cláusula WHERE ni la cláusula GROUP BY, la cláusula HAVING se aplica a la salida de la cláusula FROM y se trata esa salida como un grupo.

Si se fuera a utilizar la cláusula HAVING, en lugar de la cláusula WHERE, para limitar los valores a menos de 20, podría utilizar la siguiente instrucción SELECT:

SELECT CATEGORIA, AVG(PRECIO) AS PROM_PRECIO

FROM EXISTENCIA_DISCO_COMPACTO

GROUP BY CATEGORIA HAVING A_LA_MANO < 20;

Sin embargo, si se trata de ejecutar esta instrucción, se recibiría un error, ya que no se aplican los valores individuales A_LA_MANO a los grupos. Para que una columna se incluya en la cláusula HAVING, debe ser un grupo de columnas o deben estar resumidas de alguna manera.

Ahora veamos otro ejemplo que utilice la cláusula HAVING. En este caso, la cláusula incluye una columna resumida:

SELECT PRECIO, CATEGORIA, SUM(A_LA_MANO) AS TOTAL_ A_LA_MANO

FROM EXISTENCIA_DISCO_COMPACTO

GROUP BY PRECIO, CATEGORIA

HAVING SUM(A_LA_MANO) > 10;

La cláusula HAVING en esta instrucción funciona porque los valores A_LA_MANO se suman, lo que significa que pueden trabajar dentro de la estructura del grupo. Los resultados de la consulta serían como se muestra a continuación:

La cláusula HAVING se aplica a los resultados después de haberse agrupado (en la cláusula GROUP BY). Para cada grupo, los valores A_LA_MANO se añaden juntos, pero sólo se incluyen los grupos con los valores TOTAL_A_LA_MANO de más de 10. Si no se incluye la cláusula HAVING, los resultados de la consulta se incluirían en una fila adicional para el grupo de 14.99/Instrumental.

4.9 ORDER BY

La cláusula ORDER BY, cuando se usa en la instrucción SELECT, es la última cláusula procesada. La cláusula ORDER BY toma la salida de la cláusula SELECT y ordena los resultados de la consulta de acuerdo con las especificaciones dentro de la cláusula ORDER BY. La cláusula no agrupa las filas, como se agrupan por la cláusula GROUP BY, ni filtra las filas, como se filtran por la cláusula WHERE o la cláusula HAVING. Sin embargo, se puede especificar si las filas se organizan en un orden ascendente (utilizando la palabra clave ASC) o en orden descendente (usando la palabra clave DESC).

En el primer ejemplo se ordenan las filas basadas en la columna PRECIO:

SELECT * FROM EXISTENCIA_DISCO_COMPACTO

WHERE PRECIO < 16.00

ORDER BY PRECIO;

Observe que la columna PRECIO se especifica en la cláusula ORDER BY. También observe que si no se especifica la palabra clave ASC ni la palabra clave DESC, entonces se asume la palabra clave ASC. Si se ejecuta esta consulta, se recibirán resultados similares a los siguientes:

Las filas se enumeran de acuerdo con la columna PRECIO. Los valores en la columna PRECIO aparecen en orden ascendente (del precio más bajo al precio más alto). Ya que la cláusula WHERE se especifica, ninguna fila con precios por encima de 15.99 se incluye en los resultados de la consulta. Ya que se incluye sólo la columna PRECIO en ORDER BY, también el orden de las filas que tienen el mismo precio es impredecible. Por ejemplo, las cinco filas con un PRECIO de 14.99, aparecen todas antes que aquellas con un PRECIO de 15.99, pero esas cinco filas pueden aparecer en cualquier orden.

En el siguiente ejemplo, la instrucción SELECT es casi la misma que la última instrucción, excepto que se especifica una columna adicional en la cláusula ORDER BY:

SELECT * FROM EXISTENCIA_DISCO_COMPACTO

WHERE PRECIO < 16.00

ORDER BY PRECIO, A_LA_MANO DESC;

En este caso, a la columna A_LA_MANO le sigue la palabra clave DESC, lo que significa que las filas se enumeran en orden descendente. Sin embargo, ya que hay dos columnas, las filas primero se ordenan por la columna PRECIO y luego por la columna A_LA_MANO. Si se ejecuta esta instrucción SELECT, se recibirán los siguientes resultados:

Como se puede observar, las filas se enumeran según el orden de los valores de PRECIO, que es de forma ascendente. Además, los valores A_LA_MANO se enumeran con un orden descendente para cada precio. Por lo tanto, para el conjunto de valores PRECIO de 14.99, las filas comienzan con el valor de 42 en la columna A_LA_MANO y terminan con el valor de 5. Luego brinca al siguiente grupo de valores PRECIO: 15.99. Una vez más, el valor A_LA_MANO más grande para el rango de PRECIO de 15.99 aparece en primer lugar y la última fila contiene el valor A_LA_MANO más pequeño para el rango de PRECIO de 15.99.

Siempre que se utilice la cláusula ORDER BY, debe estar consciente del orden en el que enu- mera los nombres de columna dentro de la cláusula. En el ejemplo anterior, la columna PRECIO aparece en primer lugar; por lo tanto, las filas se ordenan primero por la columna PRECIO y luego por la columna A_LA_MANO. Sin embargo, puede invertir los nombres de columna, como se muestra en la siguiente instrucción SELECT:

SELECT * FROM EXISTENCIA_DISCO_COMPACTO

WHERE PRECIO < 16.00

ORDER BY A_LA_MANO, PRECIO DESC;

Esta vez, la columna A_LA_MANO aparece en primer lugar y la columna PRECIO aparece en segundo lugar, y a la columna PRECIO se le asigna la palabra clave DESC. Como resultado, las filas se ordenan primero por la columna A_LA_MANO, como se muestra en los siguientes resulta- dos de la consulta:

4.10 PASO A PASO: SELECT

  1. Abra la aplicación de clientes de su RDBMS y conecte la base de datos INVENTARIO.

  2. Debe correr la base con datos INVENTARIO.

3.Ahora consulte todos los datos de la tabla ARTISTAS. Introduzca y ejecute la siguiente instruc- ción SQL:

SELECT *

FROM ARTISTAS;

El resultado de su consulta debe incluir las columnas ID_ARTISTA, NOMBRE_ARTISTA y LUGAR_DE_NACIMIENTO. Debe componerse de 18 filas de datos en todas.

  1. Ahora debe crear una consulta que especifique qué columnas se incluyen en los resultados de la consulta. Para la siguiente instrucción SELECT, consulte la tabla DISCO_COMPACTO, pero devuelva sólo las columnas TITULO_CD y EN_EXISTENCIA. Introduzca y ejecute la siguiente instrucción SQL:

SELECT TITULO_CD, EN_EXISTENCIA

FROM DISCOS_COMPACTOS;

Los resultados de la consulta deben incluir sólo las dos columnas que se especifican en la instrucción SELECT. Además, la consulta debe devolver 15 filas de datos.

Observe que la instrucción SELECT es la misma que si fuera para una tabla base persistente. Puede incluso especificar los nombres de columna de la vista si se desea. (De hecho, debe ha- cerlo si consulta la vista de cualquier otra manera que a través de la invocación directa.) En la última instrucción SELECT, la consulta devolvió 15 filas, pero esta consulta devuelve sólo 12 filas, ya que los valores EN_EXISTENCIA deben estar por arriba de 10. La parte agradable sobre la vista es que ya está configurada para devolver exactamente la información deseada, sin tener que definir la cláusula WHERE.

  1. Ahora consulte la tabla DISCOS_COMPACTOS, pero refine la instrucción SELECT utilizando la cláusula WHERE. Introduzca y ejecute la siguiente instrucción SQL:

SELECT TITULO_CD, EN_EXISTENCIA

FROM DISCOS_COMPACTOS

WHERE EN_EXISTENCIA > 10 AND EN_EXISTENCIA < 30;

Debido a que se añade la cláusula WHERE, los resultados de la consulta ahora incluyen sólo nueve filas, y cada fila debe contener un valor EN_EXISTENCIA entre 10 y 30.

  1. La siguiente instrucción SELECT que se crea agrupa la información en la tabla DISCOS_ COMPACTOS. Introduzca y ejecute la siguiente instrucción SQL:

SELECT ID_DISQUERA, SUM(EN_EXISTENCIA) AS TOTAL_EN_EXISTENCIA

FROM DISCOS_COMPACTOS

GROUP BY ID_DISQUERA;

Se devuelve una fila para cada valor diferente ID_DISQUERA, y para cada uno de estos valo- res se devuelve el total para los valores EN_EXISTENCIA. Hay 10 filas. Observe que en los resultados de la consulta, el nombre de la columna con los totales EN_EXISTENCIA es TO- TAL_EN_EXISTENCIA.

  1. Ahora se añade la cláusula HAVING a la instrucción SELECT que se acaba de ejecutar. Intro- duzca y ejecute la siguiente instrucción SQL:

SELECT ID_DISQUERA, SUM(EN_EXISTENCIA) AS TOTAL_EN_EXISTENCIA

FROM DISCOS_COMPACTOS

GROUP BY ID_DISQUERA

HAVING SUM(EN_EXISTENCIA) > 10;

La cláusula HAVING limita las filas que se devuelven a aquellas cuyos valores TOTAL_EN_ EXISTENCIA sean mayores que 10. Ahora sólo se devuelven ocho filas.

  1. También se puede ejecutar la instrucción SELECT que ordene los datos devueltos por la con- sulta. Introduzca y ejecute la siguiente instrucción SQL:

SELECT *

FROM DISCOS_COMPACTOS

WHERE EN_EXISTENCIA > 10

ORDER BY TITULO_CD DESC;

Los resultados de la consulta deben estar organizados de acuerdo con la columna TITULO_CD, con las columnas enumeradas en orden descendente. Ya que se utiliza la cláusula WHERE, sólo 12 filas se deben devolver.

  1. Cierre la aplicación clientes y envie el resultado final.