使用LinqToSql,我需要为连接表(CL)中的最新modDate返回单个(L)。
表:
L(Lid,meta1,meta2,...)
CL(Cid,Lid,ModDate)
这是产生预期结果的sql
SELECT l.*
FROM L l
INNER JOIN (
SELECT TOP 1 cl.Lid, MAX(cl.ModDate) as ModDate
FROM CL cl
INNER JOIN L l ON cl.Lid = l.Lid AND l.meta1 = 5
GROUP BY cl.Lid
ORDER BY MAX(cl.ModDate) DESC
) As m ON l.Lid = m.Lid
答案 0 :(得分:2)
足够简单。子查询向我们展示了ID。查询将使用匹配的ID获取这些记录。
var subquery = db.L
.Where(L => L.meta1 = 5)
.SelectMany(L => L.CLs)
.GroupBy(CL => CL.Lid)
.OrderByDescending(g => g.Max(CL => CL.ModDate))
.Select(g => g.Key)
.Take(1)
var query = db.L
.Where(L => subquery.Any(id => L.Lid == id))
进一步反思,你可以远离子查询:
var query = db.L
.Where(L => L.meta1 = 5)
.SelectMany(L => L.CLs)
.GroupBy(CL => CL.Lid)
.OrderByDescending(g => g.Max(CL => CL.ModDate))
.Select(g => g.First().L);
答案 1 :(得分:1)
我的SQL-fu并不神奇,而且是在我的第一杯咖啡之前,所以我假设外部查询中的“l”最终与子查询中的“l”完全不同?
我认为会这样做,但你必须要确保:)这将非常值得检查生成的SQL是什么样的。如果你不介意它作为两个查询执行,当然,它会更简单。
// Can't do the "Take(1)" here or it will be executed separately
var subquery = from cl in context.CL
join l in context.L on cl.Lid = l.Lid
where l.meta1 = 5 // could put this in join clause
group cl.ModDate by cl.lid into grouped
order by grouped.Max() descending
select grouped.Key;
// But can take the first result of the join
// This may be simpler using dot notation instead of a query expression
var query = (from l in context.L
join lid in subquery
select l).Take(1);
(编辑:我之前没有采用最大的ModDate。Doh。还使用ID作为键(它已经是)来简化分组,因此我们只需要将ModDate作为组值。)
答案 2 :(得分:1)
作为您提供的查询,我可以解释为此Linq。
var query = from l in Context.L
join m in (from cl in Context.CL
join l in Context.L on cl.Lid equals l.Lid
where l.meta1 == 5
group new { l.Lid, cl.ModDate } by cl.Lid into grp
select new { Lid = grp.Key, ModDate = grp.Max(g => g.ModDate) } into grp
order by grp.ModDate descending
select grp).Take(1) on l.Lid equals m.Lid
select l;