仅当前一行中的字段距活动行中的字段较少时才选择行

时间:2014-09-30 22:25:39

标签: c# linq entity-framework tsql linq-to-entities

我想知道是否可以创建一个查询,只有当前一行中的字段的值小于实际行中的值时才会选择行。

如果查看此屏幕截图:

enter image description here

不会选择等于7的ID,因为它之后的行的值小于实际值。所以我想知道是否有一个LINQ to Entities命令可以帮助我从select结果中排除id为7的行等行。

3 个答案:

答案 0 :(得分:1)

如果您的ID保证是连续的,您可以通过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

答案 1 :(得分:0)

由于SQL是声明性的,DBMS可以就如何检索结果做出大量决定,这可能涉及多线程。

发生这种情况时,无法保证线程的完成顺序,因此,如果您定义了主键,则返回结果的顺序 - 甚至This article可以很好地解释那里发生的事情。

因此,我建议获取按数据库排序的连续编号,但确保结果在从数据库返回后再进行排序,然后对有序结果集执行过滤在C#。

答案 2 :(得分: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;
        }
    }
}