2013-03-04 109 views
7

我有一張表記錄訪問期間車輛發生的情況。對於每次訪問,都有多行來表示已完成的操作。該表看起來像這樣計算不同行中不同列之間的差異

VisitID | ActionID | StartTime | EndTime 
    0 | 0  | 1/1/2013 | 1/2/2013 
    1 | 0  | 1/2/2013 | 1/4/2013 
    1 | 1  | 1/4/2013 | 1/7/2013 
    2 | 0  | 1/4/2013 | 1/5/2013 
    2 | 1  | 1/5/2013 | 1/6/2013 
    2 | 2  | 1/6/2013 | 1/7/2013 

我希望構建一個能夠獲取訪問時間的LINQ查詢。 TotalTime通過首先找到第一個和最後(最低和最高)ActionID,然後last.EndTime - first.StartTime來計算。預期結果:

VisitID | TotalTime 
    0 | 1 
    1 | 5 
    2 | 3 

我可以通過做

var first = db.Visits.Where(v => v.ActionID == 0) 
var last = db.Visits.GroupBy(x => x.VisitID).Select(g => g.OrderByDescending(x => x.ActionID).First()) 

first.Join(last, f => f.VisitID, l => l.VisitID, (f, l) new{ VisitID = Key, TotalTime = l.EndTime - f.StartTime}); 

我產生預期的結果我真的不喜歡我以前獲得最後ActionID的黑客,我真的希望能夠在1條LINQ語句中執行此操作。我需要做些什麼才能做到這一點?

回答

4

我認爲這應該工作...

var result = db.Visits.GroupBy(v => v.VisitID) 
      .Select(g => new 
        { 
         VisitId = g.Key, 
         TotalTime = g.Max(v => v.EndTime).Subtract(g.Min(v => v.StartTime)).Days 
        }); 

編輯:這是假設actionid不要緊這麼多的最大值和最小值開始日期。這裏有一個不同的解決方案,其中actionid被排序,第一個和最後一個訪問被用來計算時間差。

var result2 = db.Visits.GroupBy(v => v.VisitID) 
      .Select(g => new 
        { 
         VisitId = g.Key, 
         TotalTime = 
        g.OrderBy(v => v.ActionID).Last().EndTime.Subtract(g.OrderBy(v => v.ActionID).First().StartTime).Days 
        }); 
+1

+1另外,我認爲他想要總日數,而不是整個時間跨度 – 2013-03-04 22:48:54

+1

@lazyberezovsky良好的捕獲。我已更新答案以返回天數。但是,我不確定此查詢是否可以與實體框架一起使用,因爲這看起來像是一個EF查詢。 – 2013-03-04 22:55:23

+1

當然!通過VisitID分組並使用'min'&'max'。布朗尼指出,對於可能含糊不清的問題提供了答案 – Jeff 2013-03-04 23:14:56

0
db.Visits.GroupBy(v => v.VisitID) 
    .Select(g => new { VisitId = g.Key, 
      Days = g.Select(x => x.EndTime.ToOADate()).Sum() 
      -g.Select(x => x.StartTime.ToOADate()).Sum() }); 

用一點點黑客添加的所有天開始和結束天每次訪問,並獲得差異。

相關問題