USE AdventureWorks2008R2;
GO
SELECT SalesOrderID, ProductID, OrderQty
,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
,AVG(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Avg'
,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Count'
,MIN(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Min'
,MAX(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Max'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
Leí sobre esa cláusula y no entiendo por qué la necesito. ¿Qué hace la función Over
? ¿Qué Partitioning By
hacer? ¿Por qué no puedo hacer una consulta con la escritura Group By SalesOrderID
?
mysql
sql
sql-server
aggregate-functions
clause
Con gran éxito
fuente
fuente
Respuestas:
Usted puede utilizar
GROUP BY SalesOrderID
. La diferencia es que con GROUP BY solo puede tener los valores agregados para las columnas que no están incluidas en GROUP BY.Por el contrario, utilizando funciones agregadas en ventana en lugar de GROUP BY, puede recuperar valores agregados y no agregados. Es decir, aunque no está haciendo eso en su consulta de ejemplo, puede recuperar
OrderQty
valores individuales y sus sumas, recuentos, promedios, etc. sobre grupos de los mismosSalesOrderID
s.Aquí hay un ejemplo práctico de por qué los agregados con ventana son geniales. Suponga que necesita calcular qué porcentaje de un total es cada valor. Sin agregados en ventanas, primero tendría que derivar una lista de valores agregados y luego unirlos nuevamente al conjunto de filas original, es decir, así:
Ahora mire cómo puede hacer lo mismo con un agregado con ventana:
Mucho más fácil y limpio, ¿no?
fuente
La
OVER
cláusula es poderosa porque puede tener agregados en diferentes rangos ("ventanas"), ya sea que useGROUP BY
o noEjemplo: obtener conteo por
SalesOrderID
y conteo de todosObtener diferentes
COUNT
s, noGROUP BY
fuente
Si solo quisiera GRUPAR POR el SalesOrderID, entonces no podría incluir las columnas ProductID y OrderQty en la cláusula SELECT.
La cláusula PARTITION BY le permite dividir sus funciones agregadas. Un ejemplo obvio y útil sería si quisiera generar números de línea para líneas de pedido en un pedido:
(Mi sintaxis puede estar ligeramente apagada)
Luego obtendría algo como:
fuente
Déjame explicarte con un ejemplo y podrás ver cómo funciona.
Suponiendo que tiene la siguiente tabla DIM_EQUIPMENT:
Ejecutar debajo de SQL
El resultado sería el siguiente
Mira lo que pasó.
Puede contar sin Agrupar por en AÑO y Emparejar con FILA.
Otra FORMA interesante para obtener el mismo resultado si, como se muestra a continuación, utiliza la cláusula WITH, WITH funciona como VISTA en línea y puede simplificar la consulta, especialmente las complejas, lo cual no es el caso aquí, ya que solo estoy tratando de mostrar el uso
fuente
La cláusula OVER cuando se combina con PARTITION BY indica que la llamada a la función anterior debe realizarse analíticamente evaluando las filas devueltas de la consulta. Piense en ello como una declaración GROUP BY en línea.
OVER (PARTITION BY SalesOrderID)
indica que para la función SUMA, AVG, etc., devuelve el valor SOBRE un subconjunto de los registros devueltos de la consulta y PARTICIONA ese subconjunto POR la clave foránea SalesOrderID.Por lo tanto, SUMAREMOS todos los registros de OrderQty para CADA ID de pedido único, y ese nombre de columna se llamará 'Total'.
Es un medio MUCHO más eficiente que usar múltiples vistas en línea para encontrar la misma información. Puede colocar esta consulta dentro de una vista en línea y luego filtrar en Total.
fuente
Query Petition
cláusula.Similar a la
Group By
CláusulaSintaxis:
función (...) SOBRE (PARTICIÓN POR col1 col3, ...)
Las funciones
COUNT()
,SUM()
,MIN()
,MAX()
, etc.ROW_NUMBER()
. Ej .RATION_TO_REOIRT()
, Etc.)Más información con ejemplo: http://msdn.microsoft.com/en-us/library/ms189461.aspx
fuente
Ese es el resultado de la consulta. La tabla utilizada como fuente es el mismo exept que no tiene última columna. Esta columna es una suma móvil de la tercera.
Consulta:
(la tabla va como public.iuk)
Está un poco por encima del nivel de dbase (1986), no sé por qué se han necesitado más de 25 años para terminarlo.
fuente