2011-09-06 17 views
5

Ho la seguente tabella:Sql somma progressiva

CREATE TABLE tbl_proc(
    [proc] float, 
    subscriber bigint 
) 

dati:

proc | subscriber 
-----|----------- 
0.7 | 123456 
0.5 | 1234567 
0.3 | 12345  
0.3 | 45678  
0.3 | 1234 
0.2 | 123455 
0.1 | 894562 

mi piacerebbe trovare un bel metodo per aggiungere una nuova colonna alla tabella che rappresenta la somma del sopra i valori.

Risultato:

proc | subscriber | col3 
-----|------------|------------ 
0.7 | 123456  | 0.7 
0.5 | 1234567 | 1.2 -- 0.7 + proc 
0.3 | 12345  | 1.5 
... 

ho trovato il seguente metodo:

Select a.[proc],SUM(b.[proc]) 
from tbl_proc a, tbl_proc b 
where a.[proc] <= b.[proc] and (a.[proc] <> b.[proc] or a.subscriber >= b.subscriber) 
group by a.[proc],a.subscriber 
order by a.[proc] desc 

Nel mio tavolo i dati vengono ordinati decrescente per proc. Anche la colonna dell'abbonato è unica.

Questo metodo che ho trovato è un po 'troppo costoso (i miei tavoli sono grandi). Per motivi di prestazioni non ho considerato la soluzione simile a un cursore.

Qualche suggerimento?


Aggiornamento:

Ho cercato su google il problema un po 'di più e ho trovato il "Aggiornamento a una variabile locale" soluzione in questa pagina:

http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal.aspx

Per quanto come ho provato questo dimostra di essere la soluzione migliore finora.

dichiarare @runningTotal float = 0

UPDATE tbl_proc SET @RunningTotal = new_col = @RunningTotal + [proc] DA tbl_proc

+0

Forse si dovrebbe provare * * la soluzione cursore e confrontare i risultati, potresti essere sorpreso. Inoltre, hai cercato soluzioni al tuo problema? Ho cercato su google "sql running total" e ho trovato un carico di risposte. – Tony

+1

@ Martin ho corretto il mio errore. Sry –

+0

Questo tipo di query sarà molto * molto *, molto più facile in Denali a causa di [miglioramenti della clausola 'OVER'] (http://www.geniiius.com/blog/t-sql-enhancements-over-clause/) , ma concorda con gli altri che hai bisogno di un ulteriore attributo per determinare l'ordine. – onedaywhen

risposta

9

Questo è generalmente noto come calcolare i totali correnti.

C'è un metodo molto veloce per fare ciò che si vuole chiamare "quirky update" ma si basa su un comportamento non documentato.

diverso da quello cursori sono il modo più veloce per grandi insiemi di come il carico di lavoro per questi cresce linearmente mentre il vostro triangolare unirsi carico di lavoro cresce in modo esponenziale (fino alla versione successiva e the improved OVER clause).

Vedere this document di Itzik Ben Gan per ulteriori informazioni sul problema.

1

Nota anche: non una buona pratica. questo non è certamente normalizzato.
L'ordine è ambiguo.

vorrei evitare questo se fossi in te. scrivi invece una vista o una query che restituisce questo in modo dinamico.

+0

+1 per il punto 'ORDER BY'. Meno convinto dall'altra parte però. Questa è una cosa abbastanza costosa da continuare a ricalcolare. –

2

Un cursore può essere una buona opzione per voi. Non sono sempre male - in effetti, con grandi set di dati in determinate situazioni (come la tua, penso) possono superare le operazioni basate su set.

Ho guardato in questo un po 'indietro - alcune buone risposte & commenti pubblicati persone che potrebbe essere relavent a quello che si sta lavorando: When are TSQL Cursors the best or only option?

Problemi correlati