2011-09-06 19 views
5

tengo la siguiente tabla:SQL suma progresiva

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

datos:

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

Me gustaría encontrar un buen método para agregar una nueva columna a la tabla que representa la suma de las valores anteriores

Resultado:

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

me encontré con el siguiente método:

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 

En mi mesa de los datos se clasifican descendente por el proc. Además, la columna del suscriptor es única.

Este método que encontré es un poco demasiado caro (mis tablas son grandes). Debido a razones de rendimiento, no consideré la solución tipo cursor.

¿Alguna sugerencia?


Actualización:

Googled el problema un poco más y me encontré con la "Actualización a una variable local" solución en esta página:

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

Por lo como lo probé, esta es la mejor solución hasta ahora.

declare @runningTotal flotar = 0

ACTUALIZACIÓN tbl_proc SET @RunningTotal = new_col = @RunningTotal + [proc] DE tbl_proc

+0

Tal vez debería tratar * * la solución cursor y comparar los resultados, te sorprenderías. Además, ¿ha buscado soluciones a su problema? Busqué en Google "sql running total" y encontré un montón de respuestas. – Tony

+1

@Martin Corregí mi error. Sry –

+0

Este tipo de consulta será mucho * mucho *, mucho más fácil en Denali debido a [mejoras en la cláusula 'OVER'] (http://www.geniiius.com/blog/t-sql-enhancements-over-clause/) , pero está de acuerdo con otros en que necesita un atributo adicional para determinar el orden. – onedaywhen

Respuesta

9

Esto se conoce generalmente como el cálculo de totales acumulados.

Hay un método muy rápido para hacer lo que usted quiere hacer llamado "quirky update", pero se basa en un comportamiento no documentado.

Aparte de eso, los cursores son la manera más rápida para conjuntos grandes ya que la carga de trabajo para estos crece linealmente mientras que su carga de trabajo de combinación triangular crece exponencialmente (hasta la próxima versión y the improved OVER clause).

Ver this document por Itzik Ben Gan para obtener más información sobre el problema.

1

también tenga en cuenta - no es una buena práctica. esto ciertamente no está normalizado.
El orden por es ambiguo.

yo evitaría esto si fuera usted. en su lugar, escriba una vista o consulta que devuelva esto dinámicamente.

+0

+1 para el punto 'ORDER BY'. Menos convencido por el otro punto sin embargo. Esto es bastante costoso para seguir recalculando. –

2

Un cursor puede ser una buena opción para usted. No siempre son malas, de hecho, con grandes conjuntos de datos en ciertas situaciones (como la suya, creo) pueden superar las operaciones basadas en conjuntos.

miré en esto un tiempo atrás - algunas buenas respuestas & comentarios publicados gente que podría ser relavent a lo que se está trabajando en: When are TSQL Cursors the best or only option?

Cuestiones relacionadas