2011-03-24 108 views
3

考慮到與模式的表是這樣的:填充缺失的天行

id1 id2 day number 

我怎麼能拒絕這樣的:

a b day1 2 
a b day5 4 
a b day9 8 
c d day2 1 
c d day3 2 
c d day5 4 
c d day8 3 

進入這個?:

a b day1 2 
a b day2 2 
a b day3 2 
a b day4 2 
a b day5 4 
a b day6 4 
a b day7 4 
a b day8 4 
a b day9 8 
c d day2 1 
c d day3 2 
c d day4 2 
c d day5 4 
c d day6 4 
c d day7 4 
c d day8 3 

澄清,對於每組id1和id2,我需要填寫缺失的行 ,日期範圍從該分組的最短日期到格言嗯 日期。此外,填入的行必須使用先前條目的 號碼列作爲號碼列。

我需要這個以儘可能快的速度運行。

獎勵積分如果你可以在LINQ to SQL中完成(假設該表存在該類的 表)。

編輯:日欄實際上是一個int代表一天,但爲了爭論,它可能是一個日期。

我已經完成了對每個組進行迭代並添加缺失日子的幼稚方法,但它看起來非常低效。我必須認爲有更快的事情或者有人遇到過這種情況。

+0

你試過什麼嗎? – JNK 2011-03-24 15:27:07

+0

你的'天'列真的是格式爲day1,day2等,還是實際上是日期? – 2011-03-24 15:29:00

回答

4
WITH dates (id1, id2, ds, de) AS 
     (
     SELECT id1, id2, MIN(d), MAX(d) 
     FROM mytable m 
     GROUP BY 
       id1, id2 
     UNION ALL 
     SELECT d.id1, d.id2, DATEADD(d, 1, ds), de 
     FROM dates d 
     WHERE ds < de 
     ) 
SELECT id1, id2, ds, m.number 
FROM dates d 
CROSS APPLY 
     (
     SELECT TOP 1 number 
     FROM mytable m 
     WHERE m.id1 = d.id1 
       AND m.id2 = d.id2 
       AND m.d <= d.ds 
     ORDER BY 
       m.d DESC 
     ) m 
OPTION (MAXRECURSION 0) 
+0

您介意在查詢的內容中添加一些解釋嗎? – 2011-03-24 15:43:45

+1

@Jeremy:它爲每一對(使用遞歸'CTE')建立'MIN'和'MAX'之間的所有日期列表,然後使用'CROSS APPLY'在列表中的每個日期之前查找最新記錄。 – Quassnoi 2011-03-24 15:45:28

+0

@Quassnoi:與「最大遞歸100在語句完成之前已耗盡」失敗 – 2011-03-24 17:23:42

1

我開始跟Quassnoi一樣,只在LINQ中,但我一直有問題。我必須創建一個解決方案,否則它會整天煩我(我真的需要完成一些工作)。這個解決方案並不像Quassnoi的答案那樣光鮮(他得到我的投票),但我花時間搞清楚了,所以我想我會分享。這可能不會比你現有的解決方案更好,但我很開心使它:)

// This selects each id group with their min and max dates into a collection 
var query = (from m in MissingDaysTables 
group m by new {Id1 = m.Id1, Id2 = m.Id2, } into myGroup 
select new 
{ 
    Id1=myGroup.Key.Id1, 
    Id2=myGroup.Key.Id2, 
    StartDay=(from g in myGroup select g.Day).Min(), 
    EndDay=(from g in myGroup select g.Day).Max() 
}); 

var myList = new List<MissingDaysTable>(); 

// Loop through each group and create the records 
foreach (var row in query) 
{ 
    DateTime curDate = row.StartDay; //used to track the current date 
    while (curDate <= row.EndDay) 
    { 
     myList.Add(new MissingDaysTable() 
     { 
      Id1 = row.Id1, 
      Id2 = row.Id2, 
      Day=startDate, 
      Number=MissingDaysTables.Where(m => m.Id1==row.Id1 && m.Id2==row.Id2 && m.Day<=curDate).OrderByDescending (t => t.Day).First().Number 
     }); 
     curDate = curDate.AddDays(1); 
    } 
} 
+0

Upvote for「分享是關懷」的心態:) – 2011-03-24 17:47:09