2013-08-06 121 views
3

我有我需要从例如不同月份的信息,我有一个EmployeeHistory表中的SQL Server数据库的表History,该表中有,我做任何更新的纪录每个员工。在一个月内我可以有很多更新,但我只有最新的一个。例如,我在一个月内不做任何更新,我展示了我获得该月份的最新更新。获取历史数据

例如

ID Name Email   Date 
1 A [email protected] 2013-01-10 
1 A [email protected] 2013-01-20 
1 A [email protected] 2013-03-15 

在这种情况下,我没有在二月份的任何变化,但我需要使用相同的数据,一月带上它,在这种情况下,从一月最新的一个应该被重复二月所以查询应该带来这样的结果:

ID Name Email   Date 
1 A [email protected] 2013-01-20 
1 A [email protected] 2013-01-20 
1 A [email protected] 2013-03-15 

我该如何构建查询这些情况?

谢谢。

回答

1

要创建的几个月里,你既可以使用系统表master..spt_values或你自己的序列表的序列。所以,你可以找到值的所有月份,无论是否有变化或不

SELECT DATENAME(mm, DATEADD(mm, v.number-1, '20010101')) AS mName, 
     o.Id, o.Email, o.[Date] 
FROM master..spt_values v 
    OUTER APPLY(
       SELECT h3.Id, h3.NAME, h3.Email, h3.Date 
       FROM (
        SELECT h.Id, MAX(h.[Date]) AS [Date] 
        FROM dbo.EmployeeHistory h 
        WHERE MONTH(h.[Date]) <= v.number 
        GROUP BY h.Id 
        ) h2 JOIN dbo.EmployeeHistory h3 
         ON h2.Id = h3.Id AND h2.Date = h3.Date 
      ) o 
WHERE v.[type] = 'P' AND v.number BETWEEN 1 AND 12 

为了获得更好的性能,你可以使用这个指标:

CREATE INDEX x ON dbo.EmployeeHistory(Id, [Date]) INCLUDE(Name, Email) 

enter image description here

观看演示上SQLFiddle

+0

不错!谢谢! – rgx71

+0

没问题。我还添加了一个更好的性能指标;) –

1

首先创建一个表格变量,该表格指定您想要查看最近的历史记录的月份。

DECLARE @MonthsOfInterest AS TABLE (FirstOfMonth DATE) 

接下来,确定要报告的日期。你可以在这里像这样硬编码日期:

INSERT INTO @MonthsOfInterest (FirstOfMonth) VALUES('2013-08-01') 
INSERT INTO @MonthsOfInterest (FirstOfMonth) VALUES('2013-07-01') 
INSERT INTO @MonthsOfInterest (FirstOfMonth) VALUES('2013-06-01') 
... 

或者你可以更倜傥,并在过去12个月,或任何编程方式加载。

但是,一旦你有这个表变量创建和填充,你的比赛。现在,它只是一个左派的事情JOIN:

SELECT FirstOfMonth, Email, Date 
FROM @MonthsOfInterest 
    LEFT JOIN HistoryTable ON 
     HistoryTable.ID = (
      SELECT TOP 1 ID 
      FROM HistoryTable 
      WHERE Date < @MonthsOfInterest.FirstOfMonth 
      ORDER BY Date DESC 
     ) 

在英语中,在@MonthsOfInterest每条记录​​,我们一起在HistoryTable记录,其Date值小于谁拥有最大的Date的开始和值。

(注:如果有多个记录与同一Date值,它会选择最有可能有至少ID值一个你可以,如果你想打破平局一些其他的方式附加列添加到ORDER BY条款。 。)

感谢

+0

我会用它来看看工作。非常感谢! – rgx71

+0

我正在检查,但它不起作用,当我添加另一个ID,例如2 – rgx71

+0

我(可能错误地)认为'ID'是'HistoryTable'的主键 - 是不正确的?你有一个唯一标识'HistoryTable'中每一行的列吗? –