Sto usando GROUP BY
per tutti i tipi di query aggregate nel corso degli anni. Recentemente, ho eseguito il reverse engineering del codice che utilizza PARTITION BY
per eseguire aggregazioni. Leggendo tutta la documentazione che posso trovare su PARTITION BY
, suona molto come GROUP BY
, forse con un po 'di funzionalità extra aggiunta? Sono due versioni della stessa funzionalità generale o sono qualcosa di completamente diverso?SQL Server: Differenza tra PARTITION BY e GROUP BY
risposta
Sono utilizzati in luoghi diversi. group by
modifica la intera query, come:
select customerId, count(*) as orderCount
from Orders
group by customerId
Ma partition by
solo funziona su a window function, come row_number
:
select row_number() over (partition by customerId order by orderId)
as OrderNumberForThisCustomer
from Orders
Un 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 modifica il modo in cui viene calcolato il risultato di una funzione della finestra.
partition by
non esegue il rollup dei dati. Ti permette di resettare qualcosa per gruppo. Ad esempio, è possibile ottenere una colonna ordinale all'interno di un gruppo mediante partizionamento sul campo di raggruppamento e utilizzando rownum()
sulle righe all'interno di quel gruppo. Questo ti dà qualcosa che si comporta un po 'come una colonna di identità che si resetta all'inizio di ogni gruppo.
PARTITION BY
è analitico, mentre GROUP BY
è aggregato. Per utilizzare PARTITION BY
, è necessario contenerlo con un OVER clause.
'PARTITION BY is analytic' Questa semplice dichiarazione mi ha chiarito molto. +1. –
PARTITION BY Divide il set di risultati in partizioni. La funzione finestra viene applicata separatamente a ogni partizione e il calcolo ricomincia per ogni partizione.
trovate a questo link: OVER Clause
Fornisce dati raggruppati senza arrotolando
cioè Supponiamo che io voglio tornare la posizione relativa della regione di vendita
Utilizzando PARTITION BY, ho può restituire l'importo delle vendite per una data regione e l'importo MAX in tutte le aree di vendita nella stessa riga.
Ciò significa che i dati verranno ripetuti, ma potrebbero essere adatti al consumatore finale nel senso che i dati sono stati aggregati ma nessun dato è stato perso, come nel caso di GROUP BY.
La migliore, la risposta più semplice. – tmthyjames
Al mia comprensione partizione è quasi identico al gruppo By, ma con le seguenti differenze:
Quel gruppo dalla realtà gruppi risultato impostato restituzione di una riga per gruppo, che si traduce quindi in SQL Server consentendo solo in l'elenco SELECT aggrega funzioni o colonne che fanno parte della clausola group by (nel qual caso SQL Server può garantire che vi siano risultati univoci per ciascun gruppo).
Consideriamo ad esempio MySQL che consente di avere nelle colonne dell'elenco SELECT non definite nella clausola Group By, nel qual caso una riga viene ancora restituita per gruppo, tuttavia se la colonna non ha risultati univoci, allora non c'è garanzia su quale sarà l'output!
Ma con Partition By, sebbene i risultati della funzione siano identici ai risultati di una funzione di aggregazione con Group By, si ottiene comunque il set di risultati normale, il che significa che si ottiene una riga per riga sottostante e non una riga per gruppo, e per questo motivo possono avere colonne che non sono univoche per gruppo nell'elenco SELECT.
Quindi, come riepilogo, Group By sarebbe il migliore quando è necessario un output di una riga per gruppo e Partition By sarebbe il migliore quando uno ha bisogno di tutte le righe ma vuole comunque la funzione di aggregazione basata su un gruppo.
Naturalmente potrebbero esserci problemi di prestazioni, vedere http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba.
possiamo prendere un semplice esempio
abbiamo 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
Raggruppa per
GROUP BY SQL può essere utilizzato in un'istruzione SELECT per raccogliere dati su più dischi e raggruppare i risultati di una o più colonne .
In parole più semplici l'istruzione GROUP BY viene utilizzata in combinazione con le funzioni di aggregazione per raggruppare il set di risultati mediante una o più colonne .
sintassi:
SELECT expression1, expression2, ... expression_n,
aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;
Possiamo applicare GroupBy 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 righe e quando applichiamo il gruppo per id , Il gruppo di server i risultati in base id
In parole semplici
qui gruppo dal normalmente riduce il numero di righe restituite rotolando loro e calcolando Sum per ogni riga.
partizione
prima di andare a partizionare da
guardiamo clausola OVER
Come da definizione MSDN
OLTRE clausola definisce una finestra o set di righe specificato dall'utente wi thin set di risultati della query . Una finestra funzione calcola quindi un valore per ogni riga nella finestra. È possibile utilizzare la clausola OVER con funzioni per calcolare valori aggregati come medie mobili, aggregati cumulativi, totali totali o N superiori per risultati di gruppo.
partizione non ridurrà il numero di righe restituite
possiamo applicare partizione 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
sguardo al risultati partiziona le righe e risulta tutte le righe non come gruppo per.
-- 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
Supponiamo di avere 14 dischi di name
colonna in tabella
in group by
select name,count(*) as totalcount from person where name='Please fill out' group BY name;
darà conteggio in singola fila cioè 14
ma in partition by
select row_number() over (partition by name) as total from person where name = 'Please fill out';
ci saranno 14 file di incremento nel conteggio
Piccola osservazione. Il meccanismo di automazione per generare dinamicamente SQL usando la 'partition by' è molto più semplice da implementare in relazione al 'group by'. Nel caso di "raggruppa per", dobbiamo occuparci del contenuto della colonna "seleziona".
Siamo spiacenti per il mio inglese.
bella risposta, potresti scrivere un campione di risultati restituiti per ognuno di essi? –
@AshkanMobayenKhiabani è possibile eseguire entrambe le query su Northwind, che può essere installata o meno in base alla versione del server sql. Altrimenti puoi cercarlo nella pagina dei download di s. –
@AshkanMobayenKhiabani La risposta di Arunprasanth qui sotto mostra risultati restituiti che possono farti risparmiare tempo invece di saltare più anelli di apprendimento e tempo per imparare Northwind – Praxiteles