2012-08-16 36 views
5

我有一個簡單的用一些虛擬的數據設置如表:T-SQL中使用SUM正在運行的總

|id|user|value| 
--------------- 
1 John 2 
2 Ted 1 
3 John 4 
4 Ted 2 

我可以選擇通過執行以下SQL運行總數(2008 MSSQL)聲明:

SELECT a.id, a.user, a.value, SUM(b.value) AS total 
FROM table a INNER JOIN table b 
ON a.id >= b.id 
AND a.user = b.user 
GROUP BY a.id, a.user, a.value 
ORDER BY a.id 

這會給我造成這樣的:

|id|user|value|total| 
--------------------- 
1 John 2  2 
3 John 4  6 
2 Ted 1  1 
4 Ted 2  3 

現在是有可能只檢索最新的EA行ch用戶?所以結果將是:

|id|user|value|total| 
--------------------- 
3 John 4  6 
4 Ted 2  3 

我該怎麼做這個正確的方式?任何建議或新的路徑將是偉大的!

+3

您只對最終結果感興趣,還是需要運行總計?你是否已經在某個地方存儲了該運行總數,還是正在使用它僅用於生成最終結果? * [您的最終結果可以更有效地創建,而無需使用運行總數。但是,如果您已將運行總量存儲在某處,則出於其他原因,當然可以使用該運行總量。] * – MatBailie 2012-08-16 07:14:34

+0

您改變了接受的答案以提高性能,但是您尚未對上述查詢做出響應。請注意,您可以使用運行總計方法,通過*** not ***來提高性能。你會感興趣嗎?還是你需要運行總數中的所有結果?*? – MatBailie 2012-08-16 09:14:30

+0

嗨Dems,我忙於工作,錯過了你的評論。我只是在總計和相關用戶之後,所以是的,我對提高性能感興趣。 – luke2012 2012-08-16 09:47:11

回答

5

試試這個:

;with cte as 
    (SELECT a.id, a.[user], a.value, SUM(b.value) AS total 
    FROM users a INNER JOIN users b 
    ON a.id >= b.id 
    AND a.[user] = b.[user] 
    GROUP BY a.id, a.[user], a.value 
    ), 
cte1 as (select *,ROW_NUMBER() over (partition by [user] 
         order by total desc) as row_num 
     from cte) 
select id,[user],value,total from cte1 where row_num=1 

SQL Fiddle Demo

+0

謝謝,這也有更好的表現! – luke2012 2012-08-16 07:26:12

+0

@Joe G Joseph,它看起來像是SQL小提琴的鏈接被破壞了。 – rstackhouse 2013-09-06 17:15:23

+0

這也將無法在SQL Server 2008上工作。 – rstackhouse 2013-09-06 17:16:33

1

地方添加聲明:

select * from 
(
your select statement 
) t 

where t.id in (select max(id) from table group by user) 

你也可以使用此查詢:

SELECT a.id, a.user, a.value, 

(select max(b.value) from table b where b.user=a.user) AS total 

FROM table a 

where a.id in (select max(id) from table group by user) 

ORDER BY a.id 
+0

非常感謝,效果很好! – luke2012 2012-08-16 07:11:29

0

添加右連接將有更好的表現比嵌套查詢。

或者更簡單:

​​
+0

但是max(id)和max(value)可以來自不同的原始表格行。 – valex 2012-08-16 07:05:52

+0

-1:這是一種過度簡化的方法,無法正常工作。你不能假設MAX(id)和MAX(value)給出來自同一輸入行的結果。 – MatBailie 2012-08-16 07:18:07

+0

你是對的,我發佈後意識到。但是,一個聰明的正確連接會比嵌套選擇表現更好。 – 2012-08-16 07:24:32

9

沒有加入是必要的,可以加快查詢是這樣的:

select id, [user], value, total 
from 
(
    select id, [user], value, 
    row_number() over (partition by [user] order by id desc) rn, 
    sum(value) over (partition by [user]) total 
from users 
) a 
where rn = 1 
+3

+1:完全避免使用運行總數的奇怪建議... – MatBailie 2012-08-16 10:53:22

+0

這可以通過顯式聲明'SUM OVER'的over子句的附加參數來進一步加速 – whytheq 2013-11-18 15:02:42

0

Compati使用SQL Server 2008或更高版本

DECLARE @AnotherTbl TABLE 
    (
     id   INT 
     , somedate  DATE 
     , somevalue DECIMAL(18, 4) 
     , runningtotal DECIMAL(18, 4) 
    ) 

INSERT INTO @AnotherTbl 
    (
     id 
     , somedate 
     , somevalue 
     , runningtotal 
    ) 
SELECT LEDGER_ID 
     , LL.LEDGER_DocDate 
     , LL.LEDGER_Amount 
     , NULL 
FROM ACC_Ledger LL 
ORDER BY LL.LEDGER_DocDate 

DECLARE @RunningTotal DECIMAL(18, 4) 
SET @RunningTotal = 0 

UPDATE @AnotherTbl 
SET @RunningTotal=runningtotal = @RunningTotal + somevalue 
FROM @AnotherTbl 

SELECT * 
FROM @AnotherTbl