tipos tablas row_number paso particiones particionamiento particion datos cluster sql-server tsql aggregate-functions window-functions

tablas - SQL Server: diferencia entre PARTICIÓN POR y GRUPO POR



tipos de particiones en base de datos (10)

He estado usando GROUP BY para todos los tipos de consultas agregadas a lo largo de los años. Recientemente, he estado aplicando ingeniería inversa a algunos códigos que usan PARTITION BY para realizar agregaciones. Al leer toda la documentación que puedo encontrar sobre PARTITION BY , suena muy parecido a GROUP BY , ¿quizás con una pequeña funcionalidad adicional agregada? ¿Son dos versiones de la misma funcionalidad general, o son algo completamente diferente?


PARTICIÓN POR Divide el conjunto de resultados en particiones. La función de ventana se aplica a cada partición por separado y los reinicios de cómputo para cada partición.

Encontrado en este enlace: Cláusula OVER


A mi entender, Partition By es casi idéntico a Group By, pero con las siguientes diferencias:

Ese grupo en realidad agrupa el conjunto de resultados que devuelve una fila por grupo, lo que se traduce, por lo tanto, en que SQL Server solo permite en la lista SELECCIONAR funciones agregadas o columnas que forman parte de la cláusula grupo por grupo (en cuyo caso, SQL Server puede garantizar que existen resultados para cada grupo).

Considere, por ejemplo, MySQL, que permite tener en la lista SELECCIONAR columnas que no están definidas en la cláusula Agrupar por, en cuyo caso todavía se devuelve una fila por grupo, sin embargo, si la columna no tiene resultados únicos, entonces no hay garantía ¿Cuál será la salida?

Pero con Partition By, aunque los resultados de la función son idénticos a los resultados de una función agregada con Group By, todavía está obteniendo el conjunto de resultados normal, lo que significa que uno obtiene una fila por fila subyacente, y no una fila por grupo, y debido a esto uno puede tener columnas que no son únicas por grupo en la lista SELECCIONAR.

Así que como resumen, Agrupar por sería mejor cuando se necesita una salida de una fila por grupo, y Partición por sería mejor cuando uno necesita todas las filas pero aún así quiere la función agregada basada 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 .


Pequeña observación. El mecanismo de automatización para generar dinámicamente SQL utilizando la "partición por" es mucho más sencillo de implementar en relación con el "grupo por". En el caso de ''agrupar por'', debemos cuidar el contenido de la columna ''seleccionar''.

Lo siento por mi ingles.


Podemos tomar un ejemplo sencillo.

Tenemos 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

Agrupar por

La cláusula SQL GROUP BY se puede usar en una declaración SELECT para recopilar datos en varios registros y agrupar los resultados por una o más columnas.

En palabras más simples, la instrucción GRUPO POR se usa junto con las funciones agregadas para agrupar el conjunto de resultados por una 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 GroupBy 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 tabla real tenemos 7 filas y cuando aplicamos grupo por id, el servidor agrupa los resultados basados ​​en id

En palabras simples

aquí, el grupo normalmente reduce el número de filas devueltas al enrollarlas y calcular la suma de cada fila.

partición por

antes de ir a la partición por

Veamos la cláusula OVER

Según la definición de MSDN

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

La partición no reducirá el número de filas devueltas

Podemos aplicar partición por en nuestra tabla de ejemplo

select SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname from TableA

resultado:

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

mire los resultados, hará una partición de las filas y dará como resultado todas las filas que no sean agrupadas por.


Proporciona datos enrollados sin enrollar

es decir, supongamos que quiero devolver la posición relativa de la región de ventas

Usando PARTICIÓN POR, puedo devolver el monto de ventas para una región determinada y el monto MAX 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 datos, como sería el caso de GROUP BY.


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

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

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

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

Un group by normalmente reduce el número de filas devueltas al enrollarlas y al calcular promedios o sumas para cada fila. partition by no afecta el número de filas devueltas, pero cambia la forma en que se calcula el resultado de una función de ventana.


Supongamos que tenemos 14 registros de columna de 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 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'';

Será 14 filas de aumento en la cuenta.


PARTITION BY es analítica, mientras que GROUP BY es agregado. Para poder utilizar PARTITION BY , debe contenerlo con una cláusula OVER .


partition by realmente no enrolla los datos. Te permite restablecer algo por grupo. Por ejemplo, puede obtener una columna ordinal dentro de un grupo al particionar en el campo de agrupación y usar rownum() sobre las filas dentro de ese grupo. Esto le da algo que se comporta un poco como una columna de identidad que se restablece al principio de cada grupo.


-- 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