Domanda

Sto usando GROUP BY per tutti i tipi di query aggregate nel corso degli anni.Recentemente, ho decodificato alcuni codici che utilizzano PARTITION BY per effettuare aggregazioni.Leggendo tutta la documentazione che riesco a trovare su PARTITION BY, sembra molto simile GROUP BY, magari con l'aggiunta di qualche funzionalità extra?Sono due versioni della stessa funzionalità generale o sono qualcosa di completamente diverso?

È stato utile?

Soluzione

Sono abituati in luoghi diversi. group by modifica l'intera query, come:

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

Ma partition by solo funziona su una funzione finestra , come row_number:

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

A group by riduce normalmente il numero di righe restituite da loro avvolgimento e calcolo delle medie o somme per ogni riga. partition by non influisce sul numero di righe restituite, ma cambia come risultato di una funzione finestra è calcolato.

Altri suggerimenti

Siamo in grado di fare un semplice esempio.

Si consideri una tabella denominata TableA con i seguenti valori:

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

  

Il Gruppo SQL dalla clausola può essere utilizzato in un'istruzione SELECT per la raccolta   dati su più dischi e di gruppo i risultati per uno o più   colonne.

     

In parole più semplici GROUP BY viene utilizzato in combinazione con   le funzioni di aggregazione per raggruppare il risultato-ausilio di uno o più   colonne.

La sintassi:

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

Possiamo applicare GROUP BY nella nostra tabella:

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

Risultati:

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

Nel nostro vero tavolo abbiamo 7 file e quando applichiamo GROUP BY id, il gruppo di server i risultati sulla base di id:

In parole semplici:

  

qui riduce GROUP BY normalmente il numero di righe restituito da laminazione   li e calcolando Sum() per ogni riga.

PARTITION BY

Prima di andare a partizione, esaminiamo la clausola OVER:

Secondo la definizione di MSDN:

  

SOPRA clausola definisce un insieme finestra o specificato dall'utente di righe di un   risultato della query. Una funzione finestra quindi calcola un valore per ogni riga   nella finestra. È possibile utilizzare la clausola OVER con funzioni per calcolare   valori aggregati come medie mobili, aggregati cumulativi,   totali parziali, o una N in alto per i risultati del gruppo.

PARTITION BY non ridurrà il numero di righe restituite.

Possiamo applicare PARTITION BY nella nostra tabella di esempio:

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

Risultato:

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

guardare i risultati - che si ripartisce le righe e ritorna tutti le righe, a differenza GROUP BY

.

partition by in realtà non rotolare il backup dei dati. Esso consente di ripristinare qualcosa su una base per gruppo. Ad esempio, è possibile ottenere una colonna ordinale all'interno di un gruppo suddividendo il campo di raggruppamento e utilizzando rownum() sopra le righe all'interno di quel gruppo. Questo ti dà qualcosa che si comporta un po 'come una colonna di identità che azzera all'inizio di ogni gruppo.

  

PARTITION BY   Divide il set di risultati in partizioni. La funzione finestra viene applicata a ogni partizione separatamente e riavvia calcolo per ogni partizione.

Trovato a questo link: OLTRE Clausola

Fornisce dati arrotolati senza arrotolamento

cioè.Supponiamo di voler restituire la posizione relativa della regione di vendita

Utilizzando PARTITION BY, posso restituire l'importo delle vendite per una determinata regione E l'importo MAX in tutte le regioni di vendita nella stessa riga.

Ciò significa che avrai dati ripetuti, ma potrebbe essere adatto al consumatore finale nel senso che i dati sono stati aggregati ma nessun dato è andato perso, come nel caso di GROUP BY.

PARTITION BY è analitica, mentre GROUP BY è aggregato. Per poter utilizzare PARTITION BY, è necessario contenerlo con una OLTRE clausola .

Come la mia comprensione partizione è quasi identico al Gruppo A, ma con le seguenti differenze:

Tale gruppo dalla realtà gruppi risultato set restituzione di una riga per gruppo, che si traduce quindi in SQL Server permettendo solo nelle funzioni di aggregazione nell'elenco SELECT o colonne che fanno parte del gruppo dalla clausola (nel qual caso SQL Server può garantire che ci sono risultati unici per ciascun gruppo).

Si consideri ad esempio MySQL che permette di avere nelle colonne elenco SELECT non definiti nella clausola Group By, nel qual caso una riga viene ancora restituito per gruppo, se la colonna non ha risultati unici poi ci è alcuna garanzia quale sarà l'uscita!

Ma con partizione, anche se i risultati della funzione sono identici ai risultati di una funzione di aggregazione con gruppo By, ancora si stanno ottenendo il normale set di risultati, il che significa che si sta ottenendo una riga per riga sottostante, e non una riga per gruppo, e per questo si può avere colonne che non sono unici per ogni gruppo nella lista SELECT.

Quindi, come una sintesi, Gruppo Di sarebbe meglio quando si ha bisogno di una potenza di una riga per gruppo, e partizione sarebbe meglio quando si ha la necessità di tutte le righe, ma vuole ancora la funzione di aggregazione sulla base di un gruppo.

Naturalmente ci potrebbe anche essere problemi di prestazioni, vedere http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .

Supponiamo di avere 14 record di name colonna nella tabella

In group by

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

darà il conteggio in una singola riga, ovvero 14

ma in partition by

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

ci saranno 14 righe di aumento nel conteggio

Piccolo osservazione. meccanismo di automazione per generare dinamicamente SQL utilizzando la 'partizione' è molto più semplice da implementare in relazione al 'gruppo da'. Nel caso di 'gruppo da', dobbiamo prendere cura del contenuto della colonna 'select'.

Ci dispiace per il mio inglese.

Si ha davvero diversi scenari di utilizzo. Quando si utilizza GROUP BY si fondono alcuni dei record per le colonne che sono uguali e si dispone di un'aggregazione del set di risultati.

Tuttavia, quando si utilizza PARTITION dal vostro set di risultati è lo stesso, ma è sufficiente un'aggregazione le funzioni delle finestre e non si uniscono i record, si avrà ancora lo stesso numero di record.

Ecco un raduno utile articolo che spiega la differenza: 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top