2011-11-12 41 views
0

我正在寫一個統計報告,我正在處理大量的數據,所以我們只得到一些數據。例如,我們正在輸出日期時間/數據對象並跟蹤從開始日期到結束日期的幾個月的時間間隔。如何獲取stat數據中的缺失點值?

問題是數據只顯示有數據的月份,例如它只會給2010年12月的2011年2月和2011年8月。我需要知道我將如何構建它,所以我可以把0放在2011年1月,2011年3月等。

有人可以給我一個如何構建這個沒有大量開銷的想法嗎?我正在考慮首先得到一個循環,然後獲得必要的時間間隔(例如分鐘,幾個月,幾年)並將其放入列表中,然後當我檢查DateTime/Data對象時,檢查它是否大於0代替它。這也是爲了在圖表上創建點。

+0

從你在哪裏得到的數據?數據庫?網絡服務?其他一些數據源? – PiRX

+0

數據來自存儲過程的數據庫。 – Darren

回答

1

加載數據到一個鏈表,並插入丟失的數據點:

using System; 
using System.Collections.Generic; 

namespace Whatever 
{ 
    public struct DataPoint 
    { 
    private DateTime time; 
    private int value; 

    public DataPoint(DateTime time, int value) 
    { 
     this.time = time; 
     this.value = value; 
    } 

    public DateTime Time 
    { 
     get { return this.time; } 
    } 

    public int Value 
    { 
     get { return this.value; } 
    } 

    public override string ToString() 
    { 
     return string.Format("{0:D2}/{1}: {2}", this.time.Month, this.time.Year, this.value); 
    } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     // List of the datapoints, e.g. loaded from a database 
     var dataPoints = new List<DataPoint>(); 
     dataPoints.Add(new DataPoint(new DateTime(2010, 11, 1), 10)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 2, 1), 20)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 3, 1), 30)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 6, 1), 40)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 9, 1), 50)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 12, 1), 60)); 
     dataPoints.Add(new DataPoint(new DateTime(2012, 2, 1), 70)); 

     // Endpoints of the measurement interval 
     var begin = new DateTime(2010, 9, 1); 
     var end = new DateTime(2012, 4, 1); 

     // Check each month and insert missing datapoints 
     var time = begin; 
     var i = 0; 
     while (time <= end) 
     { 
     if (i < dataPoints.Count) 
     { 
      if (time < dataPoints[i].Time) 
      { 
      var dataPoint = new DataPoint(time, 0); 
      dataPoints.Insert(i, dataPoint); 
      } 
     } 
     else 
     { 
      var dataPoint = new DataPoint(time, 0); 
      dataPoints.Add(dataPoint); 
     } 
     ++i; 
     time = time.AddMonths(1); 
     } 

     // Print list 
     foreach (var dataPoint in dataPoints) 
     Console.WriteLine(dataPoint); 
    } 
    } 
} 

編輯: 如果您只需要描繪出這些數據,那麼就沒有必要插入丟失的數據點。我只是在現有的點之間進行插值,我的意思是將它們連接起來。如果現有點用實心圓表示,那麼缺失點可以用空圓圈表示,坐在這些連接線上(這樣的圖形控制可以寫入通過插值給出的繪圖點而不存儲它們)。

+0

嗨,圖表是一個折線圖,標籤是幾個月,缺少的是沒有數據的月份是0 ...可以通過插值完成嗎?非常感謝 – Darren

+0

PiRX的解決方案爲您提供了在數據庫端插入缺失數據點的方法。我的解決方案在客戶端插入缺少的數據點。我對圖表和插值的評論是指當你是圖形控件開發人員的情況。 – kol

+0

我明白了,是的,您的解決方案效果更好,因爲它是一大組數據。此外,如果我想將間隔時間改爲幾天,我將如何表示?測量結果將是秒,分,日,月和年。再次感謝您的幫助。 – Darren

1

如果可能,我建議修改此過程的存儲過程和/或SQL調用,並在部分聯接(LEFT/RIGHT JOIN)和COALESCE/ISNULL函數的幫助下插入缺失的數據。

事情是這樣的:

DECLARE @range AS TABLE (datePoint DATETIME); 
DECLARE @data AS TABLE (datePoint DATETIME, value INT); 

-- setup date range 
DECLARE @currentDatePoint AS DATETIME; 
SET @currentDatePoint = '01/01/2011' 
WHILE @currentDatePoint < '01/01/2012' 
BEGIN 
    INSERT INTO @range VALUES (@currentDatePoint); 
    SET @currentDatePoint = DATEADD(MONTH, 1, @currentDatePoint); 
END 

-- setup test data 
SET @currentDatePoint = '01/01/2011' 
WHILE @currentDatePoint < '01/01/2012' 
BEGIN 
    INSERT INTO @data VALUES (@currentDatePoint, DATEPART(MONTH, @currentDatePoint)); 
    SET @currentDatePoint = DATEADD(MONTH, 2, @currentDatePoint); 
END 
--end setup 

-- actual select 
SELECT 
    r.datePoint, 
    ISNULL(d.value, 0) 
FROM 
    @range r 
LEFT JOIN 
    @data d ON r.datePoint = d.datePoint