我有两张桌子。父表具有单个日期列,子表具有2个日期列(From / To)。我需要从父级到子级进行左连接,其中父级的日期列在子级中的一个之间。在sql中,这看起来像这样:
select p.cob, count(*) from parent p
left join child c on p.cob between c.effective and c.expiry
group by p.cob
如何在linq中写这个 - 我有点卡在这里......
答案 0 :(得分:4)
这应该是你要找的东西
var query = from p in context.Parent
from c in context.Child.Where(x => p.cob >= x.effective)
.Where(x => p.cob <= x.expiry)
.DefaultIfEmpty()
group p by p.cob into pg
select new
{
cob = pg.Key,
count = pg.Count()
};
答案 1 :(得分:1)
旧但也许对其他人有帮助。它使我的查询在特定数量的测试数据上快了7倍!
我有(28秒)
from st in subtable
join t in table on st.IdTable equals t.Id
Where t.date >= myStartDate
&& t.date <= myEndDate
&& st == some_other_conditions
select st
我把它改成了这个(4秒)
from st in subtable
join t in table on new { parent = st.IdTable, from = 1, to = 1 } equals new { parent = t.Id, from = (t.date >= myStartDate ? 1 : 0), to = (t.date <= myEndDate ? 1 : 0 )
Where st == some_other_conditions
select st
它在创建连接结果后检查其他条件,因此所有其余条件都适用于较少量的数据。
希望有所帮助
答案 2 :(得分:0)
如果我正确地阅读了您的问题,部分之间的就会像这样处理。
where p.cob >= c.effective and p.cob <= c.expiry
答案 3 :(得分:0)
我需要从父母到孩子进行左连接
在SQL中总是有多种表达需求的方式,我确信linq也是如此。
SELECT p.cob, COUNT(*)
FROM parent p
WHERE EXISTS (
SELECT *
FROM child c
WHERE p.cob BETWEEN c.effective AND c.expiry
)
GROUP
BY p.cob
UNION
SELECT p.cob, 0
FROM parent p
WHERE NOT EXISTS (
SELECT *
FROM child c
WHERE p.cob BETWEEN c.effective AND c.expiry
);
一个好的优化器会发现重复的派生表,两个联合表是互斥的,等等。