LINQ中的多个Row_number

时间:2016-06-08 13:43:51

标签: linq row-number partition

我试图翻译

select * 
from (
  select *, rng = row_number() over (partition by grp order by id)
  from (
    select *, grp = row_number() over (order by id) - row_number() over (partition by Name, Status, DateFinished order by id)
    from tooling ) g
  ) gn
where rng = 1
order by id

来自之前的问题(Grouping with partition and over in TSql

Row_number over (Partition by xxx) in Linq?的帮助下 我得到了解决其中一个row_number的解决方案,但似乎我不幸成功翻译了整个问题?
我的尝试:

Tooling.OrderBy( x => x.Id)
    .GroupBy( x => new {x.Name,x.Status,x.DateFinished} )
    .Select( group => new { Group = group, Count = group.Count() } )
    .SelectMany( groupWithCount =>
        groupWithCount.Group.Select( b => b)
        .Zip(
            Enumerable.Range( 1, groupWithCount.Count ),
            ( j, i ) => new { j.Name,j.Status, j.DateFinished, RowNumber = i }
        )
    )

1 个答案:

答案 0 :(得分:0)

尝试使用其他方法通过LINQ获取结果。获取ID<的前一条记录当前的Id并检查所有字段是否相同:

  var Res = Tooling.Where(x=>{ var r = Tooling.Where(y=>y.Id<x.Id).OrderByDescending(y=>y.Id).FirstOrDefault();
                                     if (r==null) return true;
                                     return !((r.Name==x.Name) && (r.Status==x.Status) && (r.DateFinished==x.DateFinished));
                                    })
                         .OrderBy( x => x.Id)
                         .Select(x=>x);

UPD:以下是测试例程:

public class TollingRecord
{

    public int Id;
    public String Name;
    public int Status;
    public DateTime? DateFinished;

}

...

private static void TestT1()
        {
            TollingRecord[] Tooling = new TollingRecord[]{ new TollingRecord() {Id=1, Name="Large", Status=0, DateFinished=null },
                            new TollingRecord()  {Id=2, Name="Large", Status=1, DateFinished=null},
                            new TollingRecord()  {Id=3, Name="Small", Status=0, DateFinished=null},
                            new TollingRecord()  {Id=4, Name="Large", Status=2, DateFinished=null},
                            new TollingRecord()  {Id=5, Name="Large", Status=2, DateFinished=null},
                            new TollingRecord()  {Id=6, Name="Large", Status=1, DateFinished=null},
                            new TollingRecord()  {Id=7, Name="Large", Status=1, DateFinished=null},
                            new TollingRecord()  {Id=8, Name="Small", Status=1, DateFinished=DateTime.Now},
                          };



            var Res = Tooling.Where(x=>{ var r = Tooling.Where(y=>y.Id<x.Id).OrderByDescending(y=>y.Id).FirstOrDefault();
                                         if (r==null) return true;
                                         return !((r.Name==x.Name) && (r.Status==x.Status) && (r.DateFinished==x.DateFinished));
                                        })
                             .OrderBy( x => x.Id)
                             .Select(x=>x);


            foreach (var a in Res)
            {
                Console.WriteLine("{0}/{1}/{2}", a.Id,a.Name,a.Status);
            }

        }

输出:

1/Large/0
2/Large/1
3/Small/0
4/Large/2
6/Large/1
8/Small/1