Pregunta

he estado usando GROUP BY para todo tipo de consultas agregadas a lo largo de los años.Recientemente, he estado aplicando ingeniería inversa a un código que utiliza PARTITION BY para realizar agregaciones.Al leer toda la documentación que puedo encontrar sobre PARTITION BY, suena mucho a GROUP BY, ¿tal vez con una pequeña funcionalidad adicional agregada?¿Son dos versiones de la misma funcionalidad general o son algo completamente diferente?

¿Fue útil?

Solución

Se utilizan en diferentes lugares. group by modifica toda la consulta, como:

select customerId, count(*) as orderCount
from Orders
group by customerId

Pero partition by solo funciona en una función de ventana , como row_number:

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

A group by reduce normalmente el número de filas devueltas por rodar hacia arriba y calcular los promedios o sumas para cada fila. partition by no afecta al número de filas devueltas, pero cambia la forma de calcular el resultado de una función de ventana.

Otros consejos

Podemos poner un ejemplo sencillo.

Considere una tabla llamada TableA con los siguientes valores:

id  firstname                   lastname                    Mark
-------------------------------------------------------------------
1   arun                        prasanth                    40
2   ann                         antony                      45
3   sruthy                      abc                         41
6   new                         abc                         47
1   arun                        prasanth                    45
1   arun                        prasanth                    49
2   ann                         antony                      49

GROUP BY

  

El grupo de SQL BY se puede utilizar en una instrucción SELECT para recoger   datos a través de varios registros y el grupo de los resultados por uno o más   columnas.

     

En más sencilla GRUPO palabras de instrucción se utiliza en conjunción con   las funciones de agregado para agrupar el conjunto de resultados por uno o más   columnas.

Sintaxis:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;

Podemos aplicar GROUP BY en nuestra mesa:

select SUM(Mark)marksum,firstname from TableA
group by id,firstName

Resultados:

marksum  firstname
----------------
94      ann                      
134     arun                     
47      new                      
41      sruthy   

En nuestra mesa real que tenemos 7 filas y cuando aplicamos GROUP BY id, el grupo de servidores basado en los resultados id:

En palabras sencillas:

  

aquí GROUP BY normalmente reduce el número de filas devueltas por laminado   para arriba y calcular Sum() para cada fila.

PARTITION BY

Antes de ir a la partición, echemos un vistazo a la cláusula OVER:

De acuerdo con la definición de MSDN:

  

OVER cláusula define una ventana o especificado por el usuario conjunto de filas dentro de una   resultados de la consulta. Una función de ventana calcula entonces un valor para cada fila   en la ventana. Puede utilizar la cláusula OVER con funciones para calcular   valores agregados tales como medias móviles, agregados acumulados,   totales acumulados, o una N superior por los resultados del grupo.

por partición no reducir el número de filas devueltas.

Podemos aplicar PARTITION BY en nuestra tabla de ejemplo:

SELECT SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname FROM TableA

Resultados:

marksum firstname 
-------------------
134     arun                     
134     arun                     
134     arun                     
94      ann                      
94      ann                      
41      sruthy                   
47      new  

Mira los resultados - se repartirá las filas y vuelve todos filas, a diferencia de GROUP BY

.

partition by en realidad no enrollar los datos. Se le permite restablecer algo en función de cada grupo. Por ejemplo, se puede obtener un ordinal de columna dentro de un grupo mediante la partición en el campo de agrupamiento y usando rownum() sobre las filas de ese grupo. Esto le da algo que se comporta un poco como una columna de identidad que restablece al comienzo de cada grupo.

  

PARTITION BY   Divide el conjunto de resultados en particiones. La función de ventana se aplica a cada partición por separado y se reinicia de cálculo para cada partición.

Encontrados en este enlace: OVER Cláusula

Proporciona datos acumulados sin necesidad de acumularlos.

es decir.Supongamos que quiero devolver la posición relativa de la región de ventas.

Usando PARTITION BY, puedo devolver el monto de las ventas para una región determinada y el importe MÁXIMO en todas las regiones de ventas en la misma fila.

Esto significa que tendrá datos repetidos, pero puede ser adecuado para el consumidor final en el sentido de que los datos se han agregado pero no se han perdido, como sería el caso con GROUP BY.

PARTITION BY es analítico, mientras que GROUP BY es agregado. Para utilizar PARTITION BY, hay que contenerlo con un SOBRE cláusula .

A partir de mi entendimiento partición es casi idéntico al Grupo A, pero con las siguientes diferencias:

Ese grupo de realidad grupos el conjunto de resultados que regresan una fila por cada grupo, que por lo tanto resulta en SQL Server sólo permite en las funciones de agregado lista de selección o columnas que forman parte del grupo por la cláusula (en cuyo caso, SQL Server puede garantizar que hay resultados únicos para cada grupo).

Considere por ejemplo MySQL que permite tener en las columnas de lista de selección que no están definidos en la cláusula GROUP BY, en cuyo caso aún se devuelve una fila por cada grupo, sin embargo si la columna no tiene resultados únicos entonces hay hay garantía de lo que será la salida!

Pero con partición, aunque los resultados de la función son idénticos a los resultados de una función agregada con Agrupar por, todavía está recibiendo el conjunto de resultados normal, lo que significa que uno está recibiendo una fila por fila subyacente, y no una fila por cada grupo, y debido a esto uno puede tener columnas que no son únicos por grupo en la lista SELECT.

Así como un resumen, Grupo Por sería mejor cuando se necesita una salida de una fila por cada grupo, y la partición sería mejor cuando uno tiene todas las filas, pero todavía quiere que la función de agregado basado en un grupo.

Por supuesto, también puede haber problemas de rendimiento, consulte http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .

Supongamos que tenemos 14 registros de la columna name en la tabla

en group by

select name,count(*) as totalcount from person where name='Please fill out' group BY name;

se dará cuenta de en una sola fila es decir 14

pero en partition by

select row_number() over (partition by name) as total from person where name = 'Please fill out';

lo hará 14 filas de aumento en el recuento

Pequeño observación. mecanismo de automatización para generar dinámicamente SQL utilizando la 'partición' es mucho más sencillo de implementar en relación con el 'grupo por'. En el caso del 'grupo por', hay que cuidar el contenido de la columna 'Seleccionar'.

Lo siento por mi Inglés.

Tiene muy diferentes escenarios de uso. Cuando se utiliza GROUP BY que fusionar algunos de los registros de las columnas que son iguales y que tiene una agregación del conjunto de resultados.

Sin embargo, cuando se utiliza PARTITION BY su resultado es el mismo, pero sólo hay una agregación sobre las funciones de la ventana y no se combinan los registros, todavía tendrá el mismo número de registros.

Aquí es un artículo útil rally de explicar la diferencia: http://alevryustemov.com/sql/sql-partition-by/

-- BELOW IS A SAMPLE WHICH OUTLINES THE SIMPLE DIFFERENCES
-- READ IT AND THEN EXECUTE IT
-- THERE ARE THREE ROWS OF EACH COLOR INSERTED INTO THE TABLE
-- CREATE A database called testDB


-- use testDB
USE [TestDB]
GO


-- create Paints table
CREATE TABLE [dbo].[Paints](
    [Color] [varchar](50) NULL,
    [glossLevel] [varchar](50) NULL
) ON [PRIMARY]

GO


-- Populate Table
insert into paints (color, glossLevel)
select 'red', 'eggshell'
union
select 'red', 'glossy'
union
select 'red', 'flat'
union
select 'blue', 'eggshell'
union
select 'blue', 'glossy'
union
select 'blue', 'flat'
union
select 'orange', 'glossy'
union
select 'orange', 'flat'
union
select 'orange', 'eggshell'
union
select 'green', 'eggshell'
union
select 'green', 'glossy'
union
select 'green', 'flat'
union
select 'black', 'eggshell'
union
select 'black', 'glossy'
union
select 'black', 'flat'
union
select 'purple', 'eggshell'
union
select 'purple', 'glossy'
union
select 'purple', 'flat'
union
select 'salmon', 'eggshell'
union
select 'salmon', 'glossy'
union
select 'salmon', 'flat'


/*   COMPARE 'GROUP BY' color to 'OVER (PARTITION BY Color)'  */

-- GROUP BY Color 
-- row quantity defined by group by
-- aggregate (count(*)) defined by group by
select count(*) from paints
group by color

-- OVER (PARTITION BY... Color 
-- row quantity defined by main query
-- aggregate defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color)
from paints

/* COMPARE 'GROUP BY' color, glossLevel to 'OVER (PARTITION BY Color, GlossLevel)'  */

-- GROUP BY Color, GlossLevel
-- row quantity defined by GROUP BY
-- aggregate (count(*)) defined by GROUP BY
select count(*) from paints
group by color, glossLevel



-- Partition by Color, GlossLevel
-- row quantity defined by main query
-- aggregate (count(*)) defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color, glossLevel)
from paints
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top