LINQ(和 SQL)按不同属性获取最新条目
本文关键字:获取 属性 最新 SQL LINQ | 更新日期: 2023-09-27 18:32:59
我有一个包含以下相关列的表格:
- 机器 [键]
- 样本
- 实验
- 完成日期
- 。我对其执行一些计算的一些测试值
结构
Machine - Sample - Experiment - Completed - ...
m1 - s1 - e1 - <date> - ...
m1 - s1 - e2 - <date> - ...
m1 - s2 - e1 - <date> - ...
....
m2 - s3 - e1 - <date> - ...
....
在每台机器上,可以对单个样品进行多个实验。
我的目标是确定每台机器的 5 个最新不同样本,并获取所有相关条目(整行,包括每个样本的所有实验(。
一旦我按机器分组并按完成日期降序排序,我似乎找不到下一步。
我想需要某种"DistinctBy (x => 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;
我现在的主要问题是如何按预期按降序工作进行排序。
我不明白为什么它是单独查询时有效,而当它是子查询时,它不起作用。
LINQ 没有DistinctBy
功能,但幸运的是,有一个名为 morelinq 的库可以让你做到这一点。
var results = query.DistinctBy(x => x.Sample).ToList();
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; }
}
这就是我解决它的方式。
在尝试了我能找到的任何内容之后,并且不明白为什么 distinct + orderby 在一种情况下("独奏"查询(而不是另一种情况(子查询(有效,我继续"以我的方式"这样做。
它的工作速度也足够快(比我在 EDIT 2 中编写的最新 LINQ 更快(。
在这里:
- 我得到所有不同的机器
- 对于每台机器,我获取最新的 5 个样品
对于每台机器,我获取包含最新 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; }