2015-11-14 145 views
0

我使用AVERAGE和Cumulative作爲搜索條件篩選了各種sql-server標記的線程。各種絕望的答案,但我無法將它們拼湊在一起以滿足我的需求。使用案例是查找當累計天數大於60且小於90時的初始平均值(累計值/累計天數)。平均值取決於來自其他列的累計值(又名運行總數)

下面是一個表,其中ID標識對象VALUE是按月報告的金額,DAYSON是對象運行時產生該值的月份天數。 YEARMONTH是可以分類的日期值。

ID VALUE DASYON YEARMONTH 
1 166  27 201502 
1  1  2 201505 
1 569  19 201507 
1 312  19 201508 
2 364  27 201502 
2 328  31 201503 
2 242  29 201504 
2 273  31 201505 
2 174  30 201506 
2 188  25 201507 
2 203  25 201508 
3 474  28 201502 
3 521  31 201503 
3 465  30 201504 
3 473  31 201505 
3 434  30 201506 
3 404  31 201507 

我想創建摘要表平均值由累積天的每個ID,其中累積天大於60且小於90.以下分割唯一的累積值是一個表,與累積值。 (我在Excel中生成此)

ID VALUE cumValue DASYON cumDaysOn YEARMONTH 
1 166  166   27  27  201502 
1  1  167   2  29  201505 
1 569  736   19  48  201507 
1 312  1048   19  67  201508 
2 364  364   27  27  201502 
2 328  692   31  58  201503 
2 242  934   29  87  201504 
2 273  1207   31  118  201505 
2 174  1381   30  148  201506 
2 188  1569   25  173  201507 
2 203  1772   25  198  201508 
3 474  474   28  28  201502 
3 521  505   31  59  201503 
3 465  535   30  89  201504 
3 473  566   31  120  201505 
3 434  596   30  150  201506 
3 404  627   31  181  201507 

我嘗試此基礎上其他線程:

SELECT 
     ID, 
     Value, 
     SUM(Value) OVER (ORDER BY ID, YearMonth) [cumValue], 
     DaysOn, 
     SUM (DaysOn) OVER (Order by ID, YearMonth) as cumDaysOn, 
     YearMonth 
    FROM table 

WHERE DAYSON > 0 and Liquid > 0 and YearMonth > 201501 
GROUP BY ID, YearMonth, Value, DaysOn 
ORDER BY ID, yearmonth 

我不能讓它來遍歷ID;它只是不斷總結列。如果我能創建一個如上所述的表或視圖,那麼我總是可以使用select語句並通過cumdayson劃分cumvalue。

下面是一個表格,顯示在那裏我會根據該標準獲得初始平均值(InititalAverageValue):

ID VALUE cumValue DASYON cumDaysOn YEARMONTH InitalAvgValue 
1 166  166   27  27  201502 
1  1  167   2  29  201505 
1 569  736   19  48  201507 
1 312  1048   19  67  201508   55 
2 364  364   27  27  201502 
2 328  692   31  58  201503 
2 242  934   29  87  201504   32 
2 273  1207   31  118  201505 
2 174  1381   30  148  201506 
2 188  1569   25  173  201507 
2 203  1772   25  198  201508 
3 474  474   28  28  201502 
3 521  505   31  59  201503 
3 465  535   30  89  201504   18 
3 473  566   31  120  201505 
3 434  596   30  150  201506 
3 404  627   31  181  201507 

最終,我的願望是什麼表作爲這樣的:

ID InitalAvgValue 
1  55 
2  32 
3  18 

謝謝提前尋求幫助。

+0

你的結果不符合您的要求描述。你說你想得到'cumValue/cumDaysOn'的平均值,但看起來你的最終結果是基於'cumValue/DAYSON'(例如,1048/67 = 16,而不是55)。 – cbranch

回答

0

問題的關鍵是你需要一個跑步總數。計算運行總數有幾種方法,但它們在簡單性和性能之間有各種折衷。 「最佳」方法取決於數據集的預期大小以及是否使用SQL Server 2012或更早版本。下面的文章描述了一些不同的選擇的利弊沿:

http://sqlperformance.com/2012/07/t-sql-queries/running-totals

這裏有一個簡單的例子使用相關子查詢,這可能是合理的小數據集,但可能不會很好地擴展到更大的數據:

SELECT 
    ID, 
    ROUND(AVG(CAST(CumulativeValue AS FLOAT)/CAST(CumulativeDaysOn AS FLOAT)), 1) AS Average 
FROM 
    (
     SELECT 
      ID, 
      Value, 
      DaysOn, 
      (SELECT SUM(Value) FROM ExampleTable t2 WHERE t1.ID = t2.ID and t2.YearMonth <= t1.YearMonth) AS CumulativeValue, 
      (SELECT SUM(DaysOn) FROM ExampleTable t2 WHERE t1.ID = t2.ID and t2.YearMonth <= t1.YearMonth) AS CumulativeDaysOn 
     FROM 
      ExampleTable t1 
    ) AS ExampleWithTotals 
WHERE 
    CumulativeDaysOn > 60 AND CumulativeDaysOn < 90 
GROUP BY 
    ID 
ORDER BY 
    ID 
; 

輸出:

ID Average 
1 15.6 
2 10.7 
3 16.4 
+0

cbranch在他提供的SQL中是正確的。在超過一百萬行上,查詢運行花費了一點點時間 – jmg80525

+0

在我提供的SQL示例中,重點是提供一個工作示例,同時保持簡單。爲了獲得更好的性能,請考慮文章I中討論的一些替代方案。特別是,如果您使用的是SQL Server 2012或更高版本,請查看「OVER」子句的增強功能(性能卓越,而且非常簡單)。否則,請考慮使用遊標(性能良好,但會使代碼更復雜)。 – cbranch