Pergunta

Eu tenho usado GROUP BY para todos os tipos de consultas agregadas ao longo dos anos. Recentemente, eu estive a engenharia reversa algum código que usos PARTITION BY para executar agregações. Na leitura através de toda a documentação que pode encontrar sobre PARTITION BY, soa muito como GROUP BY, talvez com um pouco de funcionalidade extra adicionado? São duas versões da mesma funcionalidade geral, ou são algo completamente diferente?

Foi útil?

Solução

Eles são usados ??em lugares diferentes. modifica group by toda a consulta, como:

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

Mas partition by apenas funciona em uma função de janela , como row_number:

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

A group by normalmente reduz o número de linhas retornadas rolando-los e calcular médias ou somas para cada linha. partition by não afeta o número de linhas retornadas, mas muda como resultado de uma função de janela é calculada.

Outras dicas

Podemos tomar um exemplo simples.

Considere uma tabela chamada TableA com os seguintes 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

A cláusula SQL GROUP BY pode ser utilizado em uma instrução SELECT para coletar dados através de múltiplas fichas e agrupando os resultados por um ou mais colunas.

Em GROUP palavras mais simples pela declaração é usado em conjunto com as funções de agregação para o grupo de resultado-definidos por um ou mais colunas.

Sintaxe:

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

Podemos aplicar GROUP BY na nossa tabela:

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

Resultado:

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

Em nossa mesa real que temos 7 linhas e quando aplicamos GROUP BY id, o grupo de servidores os resultados com base em id:

Em palavras simples:

aqui GROUP BY normalmente reduz o número de linhas retornado por rolamento -los e calcular Sum() para cada linha.

PARTITION BY

Antes de ir para POR PARTITION, vamos olhar para a cláusula OVER:

De acordo com a definição MSDN:

cláusula OVER define uma janela ou especificado pelo usuário conjunto de linhas dentro de um consulta resultar set. A função de janela, em seguida, calcula um valor para cada linha na janela. Você pode usar a cláusula OVER com funções para computar valores agregados, como médias móveis, agregados cumulativos, executando totais, ou de uma parte superior de N por resultados do grupo.

PARTITION BY não vai reduzir o número de linhas retornadas.

Podemos aplicar PARTITION BY na nossa tabela de exemplo:

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  

Olhe para os resultados -. Ele vai dividir as linhas e retorna todas linhas, ao contrário GROUP BY

partition by na verdade não enrolar a dados. Ele permite-lhe repor algo em uma base por grupo. Por exemplo, você pode ter uma coluna ordinal dentro de um grupo de particionamento no campo de agrupamento e usando rownum() sobre as linhas dentro desse grupo. Isto dá-lhe algo que se comporta um pouco como uma coluna de identidade que redefine no início de cada grupo.

Por PARTITION Divide o conjunto de resultados em partições. A função de janela é aplicada a cada partição separadamente e de cálculo é reiniciado para cada partição.

encontrado neste link: SOBRE Cláusula

Ele fornece dados enroladas sem enrolar

i. Suponha que eu queira retornar a posição relativa da região de vendas

Usando PARTITION BY, eu posso devolver o montante de vendas para uma determinada região e a quantidade MAX em todas as regiões de vendas na mesma linha.

Isso significa que você terá que repetir os dados, mas pode atender o consumidor final, no sentido de que os dados foram agregados mas nenhum dado foi perdido -. Como seria o caso com GROUP BY

PARTITION BY é analítica, enquanto GROUP BY é agregada. Para utilizar PARTITION BY, você tem que contê-lo com um SOBRE cláusula .

A partir de minha partição compreensão por é quase idêntico ao Grupo por, mas com as seguintes diferenças:

Esse grupo por realmente grupos do conjunto de resultados retornar uma linha por grupo, o que resulta, portanto, em SQL Server permitindo apenas na lista SELECT funções agregadas ou colunas que fazem parte do grupo pela cláusula (caso em que o SQL Server pode garantir que existem resultados únicos para cada grupo).

Considere, por exemplo MySQL que permite ter nas colunas lista SELECT que não estão definidos na cláusula Group By, caso em que uma linha ainda está sendo devolvido por grupo, no entanto, se a coluna não tem resultados únicos, então não há garantia de que será a saída!

Mas com partição, embora os resultados da função são idênticos aos resultados de uma função agregada com Group By, ainda que você está recebendo o conjunto de resultados normal, o que significa que um está recebendo uma linha por linha subjacente, e não uma linha por grupo, e por isso pode-se ter colunas que não são únicas por grupo na lista SELECT.

Assim como um resumo, Group By seria melhor quando precisa de uma saída de uma linha por grupo e partição seria melhor quando se precisa de todas as linhas, mas ainda quer a função de agregação com base em um grupo.

É claro que também pode haver problemas de desempenho, consulte http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .

Suponha que temos 14 registros de coluna name na tabela

em group by

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

Ele lhe dará contagem em única ou seja linha 14

mas em partition by

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

que vai de 14 fileiras de aumento na contagem

observação

pequeno. mecanismo de automação para gerar dinamicamente SQL usando o 'partição' é muito mais simples de implementar em relação ao 'grupo por'. No caso do 'grupo por' Devemos cuidar do conteúdo da coluna 'selecionar'.

desculpe pelo meu Inglês.

Ele tem realmente diferentes cenários de uso. Quando você usa GROUP BY você mesclar alguns dos registros para as colunas que são mesmo e você tem uma agregação do conjunto de resultados.

No entanto, quando você usa PARTITION pelo seu conjunto de resultados é o mesmo, mas você só tem uma agregação sobre as funções da janela e você não mesclar os registros, você ainda terá a mesma contagem de registros.

Aqui está um comício útil artigo explicando a diferença: 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top