Es muy común utilizar consultas en las que se desee agrupar los datos a fin de realizar cálculos en vertical, es decir calculados a partir de datos de distintos registros. Para ello se utiliza la cláusula GROUP BY que permite indicar en base a qué registros se realiza la agrupación. Con GROUP BY la instrucción SELECT queda de esta forma:
SELECT listaDeExpresiones
[JOIN tablasRelacionadasYCondicionesDeRelación]
[WHERE condiciones]
[GROUP BY grupos]
[HAVING condiciones de grupo]
[ORDER BY columnas];
En el apartado GROUP BY, se indican las columnas por las que se agrupa. La función de este apartado es crear un único registro por cada valor distinto en las columnas del grupo. Si por ejemplo agrupamos en base a las columnas tipo y modelo en una tabla de existencias, se creará un único registro por cada tipo y modelo distintos:
SELECT tipo,modelo
FROM existencias
GROUP BY tipo,modelo;
Si la tabla de existencias sin agrupar es:
Es decir es un resumen de los datos anteriores. Los datos n_almacen y cantidad no están disponibles directamente ya que son distintos en los registros del mismo grupo. Sólo se pueden utilizar desde funciones (como se verá ahora). Es decir esta consulta es errónea:
SELECT tipo,modelo, cantidad
FROM existencias GROUP BY tipo,modelo;
SELECT tipo,modelo, cantidad
*
ERROR en línea 1:
ORA-00979: no es una expresión GROUP BY
Funciones de cálculo con grupos
Lo interesante de la creación de grupos es las posibilidades de cálculo que ofrece. Para ello se utilizan funciones que permiten trabajar con los registros de un grupo son:
SELECT tipo,modelo, cantidad, SUM(Cantidad)
FROM existencias
GROUP BY tipo,modelo;
Obtiene este resultado:
condiciones HAVING
A veces se desea restringir el resultado de una expresión agrupada, por ejemplo con:
SELECT tipo,modelo, cantidad, SUM(Cantidad)
FROM existencias
WHERE SUM(Cantidad)>500
GROUP BY tipo,modelo;
Pero Oracle devolvería este error:
WHERE SUM(Cantidad)>500
*
ERROR en línea 3:
ORA-00934: función de grupo no permitida aquí
La razón es que Oracle calcula primero el WHERE y luego los grupos; por lo que esa condición no la puede realizar al no estar establecidos los grupos. Por ello se utiliza la cláusula HAVING, que se efectúa una vez realizados los grupos. Se usaría de esta forma:
FROM existencias
GROUP BY tipo,modelo
HAVING SUM(Cantidad)>500;
Eso no implica que no se pueda usar WHERE. Esta expresión sí es válida:
SELECT tipo,modelo, cantidad, SUM(Cantidad)
FROM existencias
WHERE tipo!='AR'
GROUP BY tipo,modelo
HAVING SUM(Cantidad)>500;
En definitiva, el orden de ejecución de la consulta marca lo que se puede utilizar con WHERE y lo que se puede utilizar con HAVING:
Pasos en la ejecución de una instrucción de agrupación por parte del gestor de bases de
datos:
1> Seleccionar las filas deseadas utilizando WHERE. Esta cláusula eliminará columnas en base a la condición indicada
2> Se establecen los grupos indicados en la cláusula GROUP BY
3> Se calculan los valores de las funciones de totales (COUNT, SUM, AVG,...)
4> Se filtran los registros que cumplen la cláusula HAVING
5> El resultado se ordena en base al apartado ORDER BY.
No hay comentarios:
Publicar un comentario