下面的LINQ查询工作正常,但我需要稍微调整一下。
我希望文件中的所有记录按记录ID(客户编号)分组,然后按降序排列日期。我正在进行分组,日期按降序排列。现在,进行调整。
我希望通过recordId按升序对组进行排序。目前,这些组按日期排序,或者看起来如此。我尝试在.GroupBy之后添加.OrderBy,但根本无法使用。
最后,我想要.take(x)记录,其中x依赖于其他一些因素。基本上,.take(x)将返回最近的x记录。我尝试在各个地方放置一个.take(x),但我得不到正确的结果。
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderByDescending (m => m.date)
.GroupBy (m => m.recordId)
.Dump();
编辑#1 - recordId不是唯一的。可能/可能会有多个记录具有相同的recordId。 recordId实际上是一个客户编号。
输出将是带有名字,姓氏,日期和recordId的结果集。根据几个因素,每个recordId返回的记录多为1到5个。
编辑#2 - .Take(x)用于recordId。每个recordId可能有多行。现在,让我们假设我想要每个recordId的最新日期。 (按日期降序排序时选择顶部(1))
编辑#3 -
以下查询生成以下结果。注意每个recordId只在输出中产生1行(这没关系),看起来它是最近的日期。我还没有彻底检查过这个。
现在,我如何按升序排序,由recordId?
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = Convert.ToInt32(tokens[13]),
date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy (m => m.recordId)
.OrderByDescending (m => m.Max (x => x.date ) )
.Select (m => m.First () )
.Dump();
FirstName LastName recordId date
X X 2531334 3/11/2011 12:00:00 AM
X X 1443809 10/18/2001 12:00:00 AM
X X 2570897 3/10/2011 12:00:00 AM
X X 1960526 3/10/2011 12:00:00 AM
X X 2475293 3/10/2011 12:00:00 AM
X X 2601783 3/10/2011 12:00:00 AM
X X 2581844 3/6/2011 12:00:00 AM
X X 1773430 3/3/2011 12:00:00 AM
X X 1723271 2/4/2003 12:00:00 AM
X X 1341886 2/28/2011 12:00:00 AM
X X 1427818 11/15/1986 12:00:00 AM
答案 0 :(得分:1)
您不能轻易地通过不属于分组字段的字段进行排序。您将获得每个组的列表。这意味着,每个date
都会获得recordId
的列表。
按最近的日期排序:
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
.SelectMany(x => x.First
Take
部分是另一个问题。您只需将Take(x)
添加到表达式中,然后就可以获得此组数。
修改强>
对于某种select top(1)
:
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
// take the first of each group, which is the most recent
.Select(x => x.First())
// you got the most recent record of each recordId
// and you can take a certain number of it.
.Take(x);
// create a separate group for each unique date and recordId
.GroupBy (m => m.date, m => m.recordId)
.OrderByDescending (m => m.Key)
答案 1 :(得分:0)
只需添加
.OrderBy( g=> g.Key);
分组后。这将按RecordId升序订购groupings
。
最后,我想.take(x)记录在哪里 x取决于其他一些因素。 基本上,.take(x)将返回 最新的x记录。
如果您的日期是“最近的”,那么您为什么要首先按RecordId进行分组 - 只按日期降序排序:
..
.OrderByDescending (m => m.date)
.Take(x)
.Dump();
如果您只想按照分组建立的顺序获取前x个记录,但您可以执行以下操作:
...
.GroupBy (m => m.recordId)
.SelectMany(s => s)
.Take(x)
.Dump();
答案 2 :(得分:0)
这似乎与您的其他问题非常相似 - Reading a delimted file using LINQ
我不相信你想在这里使用Group--我相信你想要使用OrderBy和ThenBy - 比如:
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderBy (m => m.recordId)
.ThenByDescending (m => m.date)
.Dump();
对于一个简单的Take ...你可以在.Take(N)
之前添加Dump()
但是,我不确定这是你在寻找什么?你能澄清一下你的问题吗?
答案 3 :(得分:0)
如果你想要每个组的前3个,那么我认为你需要使用嵌套查询,如:
var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => new
{
Id = grouped.Key,
First3 = grouped.OrderByDescending(x => x.Date).Take(3)
}
.Dump();
如果您希望将其展平为记录列表,则可以使用SelectMany:
var recipients = var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => grouped.OrderByDescending(x => x.Date).Take(3))
.SelectMany(item => item)
.Dump();