sql >> Base de Datos >  >> RDS >> Sqlserver

Cálculo del total acumulado con la cláusula OVER y la cláusula PARTITION BY en SQL Server

A menudo te encuentras con escenarios en los que tienes que calcular el total acumulado de una cantidad.

Un total acumulado se refiere a la suma de valores en todas las celdas de una columna que precede a la siguiente celda en esa columna en particular.

Echemos un vistazo a un ejemplo para aclarar esto.

Como puede ver, la tercera fila de la columna RunningAgeTotal contiene la suma de todos los valores en las filas 1 a 3 de la columna StudentAge, es decir, 14 + 12 + 13 =39.

De manera similar, el valor de la fila 4 de la columna RunningAgeTotal es 49, que es la suma de los valores en las filas 1 a 4 de la columna StudentAge.

En SQL Server, la cláusula OVER se puede utilizar para calcular los totales acumulados.

Exploremos cómo usar esto con la ayuda de un ejemplo a continuación.

Ejemplo simple de cálculo del total acumulado de SQL

Vamos a crear algunos datos ficticios antes de escribir una consulta que calcule un total acumulado.

Primero, ejecute el siguiente script:

CREATE DATABASE School
GO

USE School
GO

CREATE TABLE Students
(
	Id INT PRIMARY KEY IDENTITY,
	StudentName VARCHAR (50),
	StudentGender VARCHAR (50),
	StudentAge INT
)
GO

INSERT INTO Students VALUES ('Sally', 'Female', 14 )
INSERT INTO Students VALUES ('Edward', 'Male', 12 )
INSERT INTO Students VALUES ('Jon', 'Male', 13 )
INSERT INTO Students VALUES ('Liana', 'Female', 10 )
INSERT INTO Students VALUES ('Ben', 'Male', 11 )
INSERT INTO Students VALUES ('Elice', 'Female', 12 )
INSERT INTO Students VALUES ('Nick', 'Male', 9 )
INSERT INTO Students VALUES ('Josh', 'Male', 12 )
INSERT INTO Students VALUES ('Liza', 'Female', 10 )
INSERT INTO Students VALUES ('Wick', 'Male', 15 )

Este script crea la tabla Estudiantes dentro de la base de datos Escuela. Hay cuatro columnas en la tabla:Id, StudentName, StudentGender y Student. La instrucción INSERT agrega 10 registros ficticios a la base de datos.

Para calcular el total acumulado de sql, tenemos que usar una cláusula OVER y agregar la columna para la que queremos calcular el total acumulado. El siguiente script calcula el total acumulado de los valores en la columna StudentAge y agrega el resultado a la columna RunningAgeTotal.

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal
FROM Students

En el script anterior, la instrucción SELECT recupera las columnas StudentName, StudentGender y StudentAge junto con la columna del total acumulado, es decir, RunningAgeTotal. La función SUM Aggregate agrega los valores a la columna StudentAge y la cláusula OVER determina que la suma debe realizarse en forma de total acumulado ordenado por la columna Id. El resultado del script anterior es el siguiente:

Calcular el promedio de ejecución de SQL

Puede modificar la secuencia de comandos en la última sección para calcular la edad promedio móvil de todos los estudiantes en la tabla Estudiantes. Para hacer esto, ejecute el siguiente script:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal,
AVG (StudentAge) OVER (ORDER BY Id) AS RunningAgeAverage
FROM Students

Como puede ver, usamos la función de agregado AVG para calcular la edad promedio de todos los estudiantes en la columna StudentAge. El resultado del script anterior se ve así:

Eche un vistazo a la tercera fila de la columna RunningAgeAverage. Contiene el promedio de valores de las filas 1 a 3 en la columna StudentAge, es decir (14 + 12 + 13)/3 =13.

Partición del total acumulado por valores de columna

También puede calcular un total acumulado dividiendo los datos por los valores de una columna en particular. Por ejemplo, puede calcular un total acumulado de sql de la edad de los estudiantes, dividido por género. Para hacer esto, debe usar una instrucción PARTITION BY junto con la cláusula OVER.

Echa un vistazo al siguiente ejemplo:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (PARTITION BY StudentGender ORDER BY Id) AS RunningAgeTotal
FROM Students

La única diferencia entre calcular el total acumulado de todos los registros y calcular el total acumulado por sexo es el uso de la cláusula PARTITION BY StudentGender entre paréntesis después de la cláusula OVER. La secuencia de comandos anterior calcula el total acumulado de los valores de la columna StudentAge, dividido por los valores de la columna StudentGender. La salida se ve así.

Ahora, eche un vistazo a los primeros cuatro valores en la columna RunningAgeTotal (resaltados por el rectángulo rojo). Estos valores son el total acumulado de las alumnas. De manera similar, las últimas 6 filas (resaltadas por el rectángulo verde) contienen un total acumulado de la edad de los estudiantes varones en la tabla de Estudiantes.

Problemas con OVER cuando una columna tiene una columna duplicada

Surge un problema si se utiliza una columna con valores duplicados con una cláusula OVER para calcular un total acumulado. Eche un vistazo a la columna StudentAge. Elice, Edward y Josh tienen la misma edad, es decir, 12. Del mismo modo, Liana y Liza también tienen los mismos valores en la columna StudentAge, es decir, 10.

Si intenta calcular un total acumulado especificando la columna StudentAge entre paréntesis después de la cláusula OVER, verá algunos resultados extraños. Ejecutemos esta consulta:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY StudentAge) AS RunningAgeTotal
FROM Students

El resultado de la consulta anterior es el siguiente:

En la segunda fila de la columna RunningAgeTotal, el valor es 29. Sin embargo, debería ser 19 porque las filas 1 y 2 de la columna StudentAge contienen 9 y 10 respectivamente. En este caso, dado que las filas 2 y 3 de la columna StudentAge contienen un valor duplicado, es decir, 10, el valor de la fila 2 de la columna RunningAgeTotal se calcula sumando 9, 10 y 10. De manera similar, para la fila 3 de la columna RunningAgeTotal, se utiliza el valor de la segunda fila que es 29.

Del mismo modo, si observa la fila 5 de la columna RunningAgeTotal, el valor es 76. En realidad, debería ser 40 + 12 =52. Sin embargo, dado que las filas 5, 6 y 7 de la columna StudentAge tienen valores duplicados, es decir, 12, el total acumulado se calcula sumando 40 + 12 + 12 + 12 =76. Este total acumulado se ha utilizado para las filas 6 y 7 de la columna RunningAgeTotal porque las filas 6 y 7 de la columna StudentAge contienen los valores duplicados como la fila 5.

Para evitar esta situación, debe dejar de usar columnas con valores duplicados junto con la cláusula OVER. La columna Clave principal siempre es una buena opción para usar con la cláusula OVER, ya que solo contiene valores únicos.

Leer también:

Agrupación de datos usando las funciones OVER y PARTITION BY

Lecciones sobre el uso de OVER y PARTITION BY