我有一个测量表如下:
SourceId:int
TimeStamp:日期/时间
测量:int
示例数据如下所示(更多关于下面的星号):
SID | TimeStamp |测量
10 | 02-01-2011 12:00:00 | 30 *
10 | 02-01-2011 12:10:00 | 30个
10 | 02-01-2011 12:17:00 | 32 *
10 | 02-01-2011 12:29:00 | 30 *
10 | 02-01-2011 12:34:00 | 30个
10 | 02-01-2011 12:39:00 | 35 *
10 | 02-01-2011 12:46:00 | 36 *
10 | 02-01-2011 12:39:00 | 36个
10 | 02-01-2011 12:54:00 | 36个
11 | 02-01-2011 12:00:00 | 36 *
11 | 02-01-2011 12:10:00 | 36个
11 | 02-01-2011 12:17:00 | 37 *
11 | 02-01-2011 12:29:00 | 38 *
11 | 02-01-2011 12:34:00 | 38个
11 | 02-01-2011 12:39:00 | 37 *
11 | 02-01-2011 12:46:00 | 36 *
11 | 02-01-2011 12:39:00 | 36个
11 | 02-01-2011 12:54:00 | 36
我需要一个LINQ查询,当Measurement值与具有相同SourceId的前一行(即每行标有星号)不同时,它只返回行。该表应按SourceId排序,然后按TimeStamp排序。
查询中的数据将用于绘制每个SourceId是一个系列的图形。源表有几百万行,重复测量数以千计。由于这些重复测量值对结果图没有任何影响,我想在将数据传递给我的图形控件进行渲染之前消除它们。
我尝试过以各种方式使用Distinct(),并在这里查看了聚合查询http://msdn.microsoft.com/en-us/vcsharp/aa336746,但没有看到明显的解决方案。
答案 0 :(得分:0)
就个人而言,我喜欢Rx扩展库中包含的DistinctUntilChanged
扩展方法。这非常方便。顺便说一下,图书馆的其他部分也是如此。
但我明白,你可能不想为此添加一个全新的依赖。在这种情况下,我建议Zip
:
sequence.Take(1).Concat(
sequence.Zip( sequence.Skip(1), (prev,next) => new { item = next, sameAsPrevious = prev == next } )
.Where( (x,index) => !x.sameAsPrevious )
.Select( x => x.item )
)
答案 1 :(得分:0)
有时一个普通的旧foreach循环就足够了。
var finalList = new List<MyRowObject>();
MyRowObject prevRow = null;
foreach (var row in myCollection)
{
if (prevRow == null || (row.SID != prevRow.SID || row.Measurement != prevRow.Measurement))
{
finalList.Add(row);
}
prevRow = row;
}
答案 2 :(得分:0)
在sql中的单个查询中无法执行此操作。因此,在linq to sql中的单个查询中无法执行此操作。
问题是您需要将每一行与“下一行”进行比较。这根本不是sql做得好的事情。
查看前五行:
10 | 02-01-2011 12:00:00 | 30 *
10 | 02-01-2011 12:10:00 | 30
10 | 02-01-2011 12:17:00 | 32 *
10 | 02-01-2011 12:29:00 | 30 *
10 | 02-01-2011 12:34:00 | 30
您希望将30条记录与30条记录相同,并删除2条记录,其中包含30条。这排除了分组。