2011-11-21 27 views
7

可能重複:
How do I calculate a running total in SQL without using a cursor?獲得之前所有值的總和? - 到目前爲止?

這是一個有點難以解釋,所以我會展示我想用一個例子:

假設我們有如下表命名爲MonthProfit

[MonthId][Profit] 
1, 10 -- January 
2, 20 -- February 
3, 30 
4, 40 
5, 50 
6, 60 
7, 70 
8, 80 
9, 90 
10, 100 
11, 110 
12, 120 -- December 

profit代表該月的利潤。

但是,如果我們在1月10日的利潤,並在2月20日,2月份我們有一個利潤總額的30

,所以我想創建一個視圖,顯示如下:

[MonthId][Profit][ProfitTotal] 
1, 10, 10 -- January 
2, 20, 30 -- February 
3, 30, 60 
4, 40, 100 
5, 50, 150 
6, 60, 210 
7, 70, 280 
8, 80, 360 
9, 90, 450 
10, 100, 550 
11, 110, 660 
12, 120, 780 -- December 

我現在做了什麼來解決這個問題,是這樣的一個觀點:

SELECT [MonthId] 
     ,[Profit] 
     , (SELECT SUM([Profit]) 
     FROM MonthProfit 
     WHERE [MonthId] <= outer.[MonthId]) as ProfitTotal 
FROM MonthProfit as outer 

不過,我認爲這是相當緩慢的,因爲它有述說一切的時候,它似乎並不五個對我優雅。有沒有「好」的方法來做到這一點?

+2

也http://stackoverflow.com/questions/814054/complicated-sql-query-for-a-running-total-column – JNK

+2

只要搜索 「運行總SQL」 和你會在這方面得到很多點擊。 – JNK

回答

3

我在這裏嘗試了一個小例子,供大家參考此產生的結果按要求

CREATE TABLE [dbo].[tbl_TotalPrevious](
[id] [int] IDENTITY(1,1) NOT NULL, 
[name] [varchar](50) NOT NULL, 
[values] [bigint] NOT NULL) 

將數據插入到表

insert into tbl_TotalPrevious values ('A', 10) 
insert into tbl_TotalPrevious values ('B', 20) 
insert into tbl_TotalPrevious values ('C', 10) 
insert into tbl_TotalPrevious values ('D', 10) 
insert into tbl_TotalPrevious values ('E', 10) 
insert into tbl_TotalPrevious values ('F', 10) 
insert into tbl_TotalPrevious values ('G', 10) 
insert into tbl_TotalPrevious values ('H', 10) 
insert into tbl_TotalPrevious values ('I', 10) 
insert into tbl_TotalPrevious values ('J', 10) 
insert into tbl_TotalPrevious values ('K', 10) 
insert into tbl_TotalPrevious values ('L', 10) 
insert into tbl_TotalPrevious values ('M', 10) 
insert into tbl_TotalPrevious values ('N', 10) 
insert into tbl_TotalPrevious values ('O', 10) 
insert into tbl_TotalPrevious values ('P', 10) 
insert into tbl_TotalPrevious values ('Q', 10) 
insert into tbl_TotalPrevious values ('R', 10) 
insert into tbl_TotalPrevious values ('S', 10) 
insert into tbl_TotalPrevious values ('T', 10) 
insert into tbl_TotalPrevious values ('U', 10) 
insert into tbl_TotalPrevious values ('V', 10) 
insert into tbl_TotalPrevious values ('W', 10) 
insert into tbl_TotalPrevious values ('X', 10) 
insert into tbl_TotalPrevious values ('Y', 10) 

創建的功能,例如。

ALTER FUNCTION testtotal 
(
    @id int 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @Result int 
    SELECT @Result = (SELECT SUM([values]) 
     FROM tbl_TotalPrevious 
     WHERE [id] <= @id) 

    RETURN @Result 

END 
GO 

結果來生成從單個查詢

SELECT [id],[values], (dbo.testtotal(id)) as TotalVals FROM tbl_TotalPrevious 

希望以上解決您與時機的問題目的,並生成數據的速度快的要求。

RESULTS IMAGE

+1

這不正是我的子查詢相同嗎?只能封裝成一個函數? –

+0

但是,這樣做仍然會減少由於某個功能而導致的時間和表格掃描。但我認爲你應該實施並測試你的實時數據執行計劃。 – Murtaza

-1

這似乎是一個不是很優雅的選擇,但它工作正常。

如果你想提高,你有幾種選擇:

  1. 使該表(ProfitTotal)將被更新(觸發)第三列的插入/更新的值或者如果你想使它選擇;
  2. 創建索引使其更快;
  3. 更新表格統計信息。
0

嘗試下面的內容,乍一看看起來很好:-)。

create table #tab ([MonthId] int, [Profit] int) 

insert into #tab select 1, 10 -- January 
insert into #tab select 2, 20 -- February 
insert into #tab select 3, 30 
insert into #tab select 4, 40 
insert into #tab select 5, 50 
insert into #tab select 6, 60 
insert into #tab select 7, 70 
insert into #tab select 8, 80 
insert into #tab select 9, 90 
insert into #tab select 10, 100 
insert into #tab select 11, 110 
insert into #tab select 12, 120 -- December 

select t.*, t3.total 
from #tab t 
join (
    select t1.monthId, 
     sum(t2.profit) as total 
    from #tab t1 
    join #tab t2 on t1.monthId >= t2.monthId 
    group by t1.monthId 
) t3 on t.monthId = t3.monthId 
0
declare @MonthProfit table 
(
    [MonthId] int, 
    [Profit] int 
) 

insert into @MonthProfit values 
(1, 10),(2, 20),(3, 30),(4, 40), 
(5, 50),(6, 60),(7, 70),(8, 80), 
(9, 90),(10, 100),(11, 110),(12, 120) 

;with C as 
(
    select M.MonthId, 
     M.Profit 
    from @MonthProfit as M 
    where M.MonthId = 1 
    union all 
    select M.MonthId, 
     C.Profit + M.Profit 
    from @MonthProfit as M 
    inner join C 
     on M.MonthId = C.MonthId + 1 
) 
select C.MonthId, 
     C.Profit 
from C 
order by C.MonthId 
相關問題