我有一张包含以下相关列的表格:
结构
Machine - Sample - Experiment - Completed - ...
m1 - s1 - e1 - <date> - ...
m1 - s1 - e2 - <date> - ...
m1 - s2 - e1 - <date> - ...
....
m2 - s3 - e1 - <date> - ...
....
在每台机器上,可以对单个样品执行多个实验。
我的目标是识别每台机器的 5个最新-distinct-样本,并获得所有相关条目(整行,包括此示例中的所有实验)。< / p>
一旦我按照机器分组并按DateCompleted降序排序,我似乎无法找到下一步。
我想某种“DistinctBy(x =&gt; x.Sample)”是必需的,但是无法解决这个问题。
实施例: (按日期顺序递减)
Machine - Sample - Experiment
m1 - s1 - e1 *
m1 - s1 - e2 *
m1 - s2 - e1 *
m1 - s2 - e2 *
m1 - s3 - e1 *
m1 - s4 - e1 *
m1 - s4 - e2 *
m1 - s5 - e1 *
m1 - s6 - e1
m1 - s6 - e2
...
我需要标记为“*”的所有行作为我的查询的输出 - 对于每台机器都是如此。
我正在努力为此编写SQL语句。 如果你知道如何在SQL中编写它,发布它,我也可能会得到一些东西。
编辑:
好的,我尝试自下而上,我的第一次尝试是确定最新的5个样本。
以下具有固定值的查询有效
var samples = (from c in db.Experiments
where c.Machine == "m1"
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
我需要添加“ToList()”,因为Distinct()会混淆它。
现在,当我将此包含到另一个查询中时,我想要每台机器的结果 - 它不起作用 - 它不会通过降序完成日期来排序,而是保持“随机”顺序。
为什么会这样?
var last5samples = (from t in db.Experiments
group t by new { t.Machine } into g
select new
{
Machine = g.Key.Machine,
Samples = (from c in db.Experiments
where c.Machine == g.Key.Machine
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
});
编辑2:
尝试了另一种方法,确实要求我需要的东西 - 包含最后5个样本的所有行。 这很慢,但“有效”,除了命令降序不起作用。
我首先使用“IN”方法,但后来看到LINQ我需要反转逻辑,这就是我想出的:
var last5samples = from t in db.Experiments
where (from c in db.Experiments
where c.Machine == t.Machine
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
.Contains(t.Sample)
select t;
我现在的主要问题是如何按预期降序工作。
我不明白为什么它在单独查询时有效,而在子查询时则不然。
答案 0 :(得分:0)
LINQ没有DistinctBy
功能,但幸运的是,有一个名为morelinq的库允许你这样做。
var results = query.DistinctBy(x => x.Sample).ToList();
答案 1 :(得分:0)
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public void Main()
{
var list = new List<Test>();
list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) });
list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) });
list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now });
list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) });
list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) });
list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddHours(-1) });
var q = from s in list
group s by new { s.Machine, s.Sample }
into gs
select new
{
Machine = gs.Key.Machine
,
Sample = gs.Key.Sample
,
Rows = gs.OrderByDescending(f => f.DateCompleted).Take(5)
};
foreach (var p in q.ToList())
{
Console.WriteLine("{0} {1} {2}", p.Machine, p.Sample, p.Rows.Count());
}
}
}
public class Test
{
public string Machine { get; set; }
public string Sample { get; set; }
public string Experiment { get; set; }
public DateTime DateCompleted { get; set; }
}
答案 2 :(得分:0)
好的,这就是我解决它的方法。
在尝试了我能找到的任何东西之后,并且不理解为什么distinct + orderby在一个案例中工作(&#34; solo&#34;查询)而不是另一个(子查询),我接着去做了#34; my方式&#34;
它的工作速度也足够快(比我在编辑2中最新写的LINQ更快)。
这是:
对于每台机器,我都会获取包含最新5个样本的行
foreach (var m in machines)
{
var last5Samples = (from t in db.Experiments
where t.Machine = m.Machine
orderby t.Completed descending
select t.Sample).ToList().Distinct().Take(5);
var expsForLast5Samples = from t in db.Experiments
where last5Samples.Contains(t.Sample)
select t;
}