2012-02-16 16 views
20

Sto cercando di ottenere l'over e la partizione in base alla funzionalità racchiusa nella mia testa. Ecco un esempio che non capisco.Tentativo di comprendere over() e partizione di

Ecco i dati che ho:

SALESORDERID  ORDERDATE 
43894    08/01/2001 
43664    07/01/2001 
43911    08/01/2001 
43867    08/01/2001 
43877    08/01/2001 
44285    10/01/2001 
44501    11/01/2001 
43866    08/01/2001 
43895    08/01/2001 
43860    08/01/2001 

Quando faccio funzionare questa domanda:

select Row_Number() over(partition by orderdate order by orderdate asc) 
    as Rownumber, salesorderid, orderdate 
from test2 
order by rownumber 

Ecco i risultati che ottengo:

ROWNUMBER  SALESORDERID  ORDERDATE 
1    43664    07/01/2001 
1    43911    08/01/2001 
1    44109    09/01/2001 
1    44483    11/01/2001 
1    44285    10/01/2001 
2    43867    08/01/2001 
2    44501    11/01/2001 
3    43895    08/01/2001 
4    43894    08/01/2001 
5    43877    08/01/2001 

qualcuno può spiegare questa query per me. Non sono nuovo di SQL ma le finestre con cui ho avuto problemi e non riesco a farmi girare la testa.

risposta

26

Prova ordinamento per data ordine, vedrete i risultati più facilmente

select Row_Number() over(partition by orderdate order by orderdate asc) 
    as Rownumber, salesorderid, orderdate 
from test2 
order by orderdate; 

dovrebbero dare (ho aggiunto righe vuote per chiarezza)

ROWNUMBER  SALESORDERID  ORDERDATE 
1    43664    07/01/2001 

1    43911    08/01/2001 
2    43867    08/01/2001 
3    43895    08/01/2001 
4    43894    08/01/2001 
5    43877    08/01/2001 

1    44109    09/01/2001 

1    44285    10/01/2001 

1    44483    11/01/2001 
2    44501    11/01/2001 

Si noterà che il risultato è diviso in 'partizioni', ogni partizione è l'insieme di righe con gli stessi ordini. Questo è ciò che significa "partizione per data".

All'interno di una partizione, le righe sono ordinate per ordine, secondo la seconda clausola di '(partizione per ordine di data ordine per ordine asc)'. Questo non è molto utile, poiché tutte le righe all'interno di una partizione avranno lo stesso ordine. Per questo motivo, l'ordine delle righe all'interno di una partizione è casuale. Provare a ordinare da salesorderid all'interno della partizione per clausola per avere un risultato più riproducibile.

row_number() restituisce giusto ordine della riga all'interno di ogni partizione

+1

provare anche SELECT COUNT (*) OVER (partizione ....) potrebbe essere ancora più chiaro a voi quello che sta facendo . –

+0

Grazie per la risposta. La clausola di partizione è molto potente – Luke101

+0

Bello e chiaro grazie! –

9

Il partition by orderdate significa che si stanno confrontando solo record con altri record con lo stesso orderdate. Ad esempio, dei cinque record con orderdate = '08/01/2001', uno avrà row_number() = 1, uno avrà row_number() = 2 e così via.

Il order by orderdate asc significa che, all'interno di una partizione, i numeri di riga devono essere assegnati nell'ordine orderdate. Nel tuo esempio non ha alcun effetto, perché stai già partizionando per orderdate, quindi tutti i record all'interno di una partizione avranno lo stesso orderdate. (Sarebbe come scrivere SELECT ... FROM t WHERE c = 6 ORDER BY c: tutti i record selezionati hanno lo stesso valore di c, quindi lo ORDER BY c non fa nulla.) Quindi, all'interno di una partizione, l'assegnazione di row_number() è arbitraria: ogni riga avrà un numero diverso, ma non ci sono garanzie su quale riga avrà quale numero.

+0

Questa risposta avrebbe dovuto essere accettata invece – Avi

Problemi correlati