LINQ to SQL按年龄分组的人
C#和VB.NET中的示例都可以。LINQ to SQL按年龄分组的人
我有一个表 “人” 与下列:
-FullName(nvarchar的不是null) -DOB(日期时间为空)
我想写一个LINQ to SQL来组人的年龄,像下面的结果:
年龄19:4 PPL
年龄20:5 PPL
年龄21:6个PPL
等等...
这里是我的尝试:
Dim query = From ppl In db.People _
Select New With {.Age = DateTime.Now.Year - CDate(ppl.DOB).Year, .CountAge = ppl.Count}
注意,有一些人在表中没有DOB记录,所以这些不得被包括在内。 DOB列有这样的记录1982-10-24 10:12:45 AM因为它是一个DateTime列。
我宁愿:
var result = db.People
.Where(p => p.DOB != null) // exclude null DOB's from stats
.GroupBy(p => p.DOB.Value.Year)
.Select(g => new { Age = DateTime.Now.Year - g.Key, Count = g.Count() });
我们在这里分组对抗的出生年份。这应该转化为SQL中的GROUP BY YEAR(dob)
,与GROUP BY YEAR(GETDATE()) - YEAR(dob)
相比,该性能或优化可能会稍微好一些。将行表达式映射到索引几乎是不可能的,但像YEAR()
这样的特定结构可以被优化为部分使用日期时间索引。我在这里做了许多假设,就像datetime
结构以年份开始,SQL服务器关心YEAR(x)
以进行优化等。在构建LINQ查询时,记住这种情况仍然很好。
From ppl In db.People
Select New With {.Age = DateTime.Now.Year - CDate(ppl.DOB).Year,
.CountAge = ppl.Count()}
Group By (DateTime.Now.Year - CDate(ppl.DOB).Year)
我认为这个查询将用于您的目的。
假设DOB是一个可空的日期时间(日期时间?),所以没有DOB记录意味着零有:
from ppl in db.People
where ppl.DOB.HasValue
let age = DateTime.Today.Year - ppl.DOB.Value.Year
group ppl by age into ages
select new { Age=ages.Key, Persons = ages }
这是在C#中,但应该很好的转化为VB因为语法是相似的。
如果两个人在一月和十二月出生,他们的年龄与您的查询不同吗? –
的确,这只是一个不好的近似,但遵循OP所使用的逻辑。他的问题是关于分组,所以我想保持它像他的:) – edvaldig
这应该工作(也应该多一点准确地计算年龄):
var query = from person in db.People
where person.DOB.HasValue
let age = (DateTime.Now - username.UpdateDateTime.Value).Days % 365
group person by age into ages
select new { Age =ages.Key, People = ages.Count() }
更准确的解决方案:
db.People.Where(p => p.DOB != null).GroupBy(p => ((DbFunctions.DiffDays(p.DOB, DateTime.Today)/365)))
.Select(g => new {Age=g.Key, Count = g.Count()})
分组为区间:
var interval = 5; //years
db.People.Where(p => p.DOB != null).GroupBy(p => ((DbFunctions.DiffDays(p.DOB, DateTime.Today)/365)/interval))
.Select(g => new {GroupIndex=g.Key, Count = g.Count()})
“请注意,有一些人在表格中记录DOB ......”你缺少一个字句子? –
它应该是“有些人没有DOB记录”。是的,我没有输入“不”字。谢谢。 – Narazana
对于初学者来说有几个问题:'.Age = DateTime.Now.Year - CDate(ppl.DOB).Year'将会在很多时候得到错误的年龄(考虑一年中出生日期的位置)。你也没有聚合在那里。 –