2014-09-30 26 views
1

我想知道是否可以創建一個查詢,只有在前一行中的某個字段有一個值時纔會選擇行小於實際行中的值。只有當前一行的字段小於活動行的字段時才選擇一行

如果選中該截圖:

enter image description here

不會被選中,等於7的ID,因爲之後的行具有值是小於實際值。所以我想知道是否有一個LINQ to Entities命令可以幫助我從選擇結果中排除諸如id爲7的行。

+0

這看起來像通常的數據模型。也許如果你解釋更高級別的問題,可能會有更好的模型來解決你的問題 – 2014-09-30 23:55:00

回答

1

如果你的IDS保證是連續的,可以通過ID加入表本身到ID -1

var q = from x in test 
     join y in test on x.ID equals y.ID - 1 
     where y.StopOrder >= y.ID 
     select x; 

你不得不考慮邊界條件,你可能想的等效左加入。

如果你的ID不連續的,你可以這樣做:

var q = from x in test 
     from y in test 
     where y.ID > x.ID 
     group y by x into g 
     where g.Min().ID <= g.Min().StopOrder 
     select g.Key; 

對於這個工作,你需要定義的表類型IComparable的。在我的測試中,我使用:

struct X: IComparable<X> { 
    public int ID; 
    public int StopOrder; 
    public int CompareTo (X other) { 
     return ID.CompareTo(other.ID); 
    } 
} 

這將仍然不會返回最後一行。

如果您使用SQL2012或更高版本並希望下拉到SQL,則可以使用lead函數。這將只掃描表一次(假設ID索引):

with x as (
    select 
    t.ID, 
    t.StopOrder, 
    lead(id, 1) over (order by id) as NextID, 
    lead(StopOrder, 1) over (order by id) as NextStopOrder 
    from 
    test t 
) select 
    x.ID, 
    x.StopOrder 
from 
    x 
where 
    x.NextId <= x.NextStopOrder; 

另外,如果你想在最後一排,你可以再補充or x.NextID is null到底

Example SQLFiddle

+0

@Silvermind如果ID之間存在差距,它就不起作用。如果是我,我可能會下降到在SQL中使用'row_number()',而不是試圖在這種情況下將其用於linq。 – Laurence 2014-09-30 22:52:17

+0

@Laurence我該如何解決row_number()thx – Laziale 2014-09-30 22:55:33

+0

@Laurence你是對的,我專注於代碼,很抱歉 – Silvermind 2014-09-30 23:05:51

0

由於SQL是聲明式的,數據庫管理系統可以做出很多關於如何檢索結果的決定,這可能涉及多線程。

發生這種情況時,如果您定義了主鍵,則不能保證線程完成的順序,因此也不能保證返回結果的順序 - ,甚至This article是一個很好的解釋。

因此,我建議獲取按數據庫排序的連續編號,但要確保結果從數據庫返回後再進行排序,然後對C#中的有序結果集執行篩選。

0

如果表是不是太大拉的所有記錄,它可能是更容易編寫,做濾波擴展方法(對不起,我不太明白你的意思)的條件:

public static class MyTypeExtensions 
{ 
    public static IEnumerable<MyType> FilterOnStopOrder(this IEnumerable<MyType> source) 
    { 
     MyType previous = null; 
     foreach (var item in source.OrderBy(s => s.ID)) 
     { 
      // or whatever condition... 
      if (previous != null && previous.StopOrder < item.StopOrder) 
      { 
       yield return item; 
      } 

      previous = item; 
     } 
    } 
} 
相關問題