Linq - 通过标准获得前2名记录

时间:2010-08-05 02:32:56

标签: sql linq

我有以下格式的数据:

colA                colB
2010                10
2010                20
2010                30
1999                99

我需要使用Linq / Lambda表达式获取如下输出:

colA                colB
2010                10
1999                99

colB可以是任何非99值,但前2个应始终列出99和任何非99值的1个实例。 我在colA中的值之后。

TIA

2 个答案:

答案 0 :(得分:1)

您需要了解如何使用GroupBy()进行分组;转到101 LINQ Samples: Grouping Operators

public class Record
{
    public int colA; { get; }
    public int colB; { get; }
}

...
// this extension method will clean up our searching within the group clause
public static Record Select99OrFirst(this IEnumerable<Record> source)
{
    var item = source.FirstOrDefault(r => r.colB == 99);
    return (null != item) ? item : source.First();
}

...

IEnumerable<Record> data;
var query = data.GroupBy(r => r.colA)
  .Select(g => new { Year = g.Key, Value = g.Select99OrFirst().colB })
  .OrderByDescending(x => x.Year);

Console.WriteLine("colA/tcolB");
foreach (var item in query)
    Console.WriteLine(item.Year + "/t" + item.Value);

这将为您提供具有Year属性的匿名对象和分别为colA和colB的Value属性。如果首先在组中找不到99条记录,则每条记录将代表一年组内的第一条记录。

答案 1 :(得分:1)

你想要这样的东西吗?

var value1 = data.FirstOrDefault(x => x.colB != 99).Select(x => x.colA);
var value2 = data.FirstOrDefault(x => x.colB == 99).Select(x => x.colA);

可以使用实用程序方法将其合并到IEnumerable中,例如以下扩展名:

public static void CreateEnumerable<TResult>(this TResult obj)
{
    yield return obj;
}

以这样的方式:

var results = value1.CreateEnumerable().Concat(value2.CreateEnumerable());