【发布时间】:2014-12-03 11:07:24
【问题描述】:
我有一个包含以下相关列的表格:
- 机器 [钥匙]
- 示例
- 实验
- 完成日期
- ...我执行一些计算的一些测试值
结构
Machine - Sample - Experiment - Completed - ...
m1 - s1 - e1 - <date> - ...
m1 - s1 - e2 - <date> - ...
m1 - s2 - e1 - <date> - ...
....
m2 - s3 - e1 - <date> - ...
....
在每台机器上,可以对单个样本执行多个实验。
我的目标是识别 每台机器的 5 个最新 -distinct- 样本,并获得 所有相关条目(整行,包括每个样本的所有实验)。
一旦我按 Machine 分组并按 DateCompleted 降序排序,我似乎找不到下一步。
我猜想某种“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 个样本。 这很慢,但是“工作”,有点,除了 orderby descending 不起作用。
我首先使用“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;
我现在的主要问题是如何按预期进行降序排序。
我不明白为什么它在单独查询时有效,而在子查询时无效。
【问题讨论】:
-
您需要为 distinctBy 包含 morelinq。你可以参考这个帖子:stackoverflow.com/questions/998066/linq-distinct-values
-
用sql,需要用到windowing函数
-
@IsThatSo,在这里 (stackoverflow.com/questions/2537823/…) Jon Skeet 提到它仅适用于类,它不适用于 LINQ to SQL。
-
作为@hazimdikenli——你需要纯SQL中的窗口函数——这通常被称为greatest-n-per-group问题。
-
@dbu 没有粗线