2011-11-03 109 views
1

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列。

+0

「請注意,有一些人在表格中記錄DOB ......」你缺少一個字句子? –

+0

它應該是「有些人沒有DOB記錄」。是的,我沒有輸入「不」字。謝謝。 – Narazana

+0

對於初學者來說有幾個問題:'.Age = DateTime.Now.Year - CDate(ppl.DOB).Year'將會在很多時候得到錯誤的年齡(考慮一年中出生日期的位置)。你也沒有聚合在那裏。 –

回答

0

我寧願:

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查詢時,記住這種情況仍然很好。

0
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) 

我認爲這個查詢將用於您的目的。

0

假設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因爲語法是相似的。

+0

如果兩個人在一月和十二月出生,他們的年齡與您的查詢不同嗎? –

+0

的確,這只是一個不好的近似,但遵循OP所使用的邏輯。他的問題是關於分組,所以我想保持它像他的:) – edvaldig

0

這應該工作(也應該多一點準確地計算年齡):

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() } 
2

更準確的解決方案:

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()})