使用Calendar表生成数据的历史视图

时间:2016-08-24 14:02:23

标签: sql sql-server sql-server-2012

我的一个表上有一个created_date(时间戳),它还有一个项目的duration列,我需要加入另一个只有first_day_of_month的表具有每月第一天的列以及其他相关信息。

表1

id    project_id    created_date    duration
1       12345        01/01/2015       10
2       12345        20/10/2015       11
3       12345        10/04/2016       13
4       12345        10/08/2016       15

表2

project_id    month_start_date
12345        01/01/2015       
12345        01/02/2015       
12345        01/03/2015       
12345        01/04/2015       
...
12345        01/08/2016       

预期结果

project_id    month_start_date  duration
12345        01/01/2015          10
12345        01/02/2015          10
...
12345        01/10/2015          11
12345        01/11/2015          11
...
12345        01/04/2016          13 
12345        01/05/2016          13
12345        01/06/2016          13  
...
12345        01/08/2016          15  

我希望能够历史地显示我的第二个表中列出的数据。所以,基本上我希望查询返回与duration相关的相同month_start_date,这样价值就会重复,直到满足另一个dateadd(month,datediff(month,0,created_date),0) = first_day_of_month ......等等。

这是我的疑问:

select table2.project_name,
       table2.month_start_date,
       table1.duration,
       table1.created_date
from table1 left outer join table2
   on table1.project_id=table2.project_id
where dateadd(month,datediff(month,0,table1.created_date),0)<=table2.month_start_date
group by table2.project_name,table2.month_start_date,table1.duration,table1.created_date
order by table2.month_start_date asc

但我在此重复记录:

结果我

project_id    month_start_date  duration
12345        01/01/2015          10
12345        01/02/2015          10
...
12345        01/10/2015          10
12345        01/10/2015          11
...
12345        01/04/2016          10
12345        01/04/2016          11 
12345        01/04/2016          13 
...
12345        01/08/2016          10
12345        01/08/2016          11
12345        01/08/2016          13
12345        01/08/2016          15

有人可以帮忙吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我会使用CROSS/OUTER APPLY运算符。

这是一种可能的变体。对于日历表Table2中的每一行(每个月),CROSS APPLY内的内部相关子查询会从Table1中找到一行。在project_id加1个月之前,它将是具有相同created_date的行和第month_start_date行。

SELECT
    Table2.project_id
    ,Table2.month_start_date
    ,Durations.duration
FROM
    Table2
    CROSS APPLY
    (
        SELECT TOP(1) Table1.duration
        FROM Table1
        WHERE 
            Table1.project_id = Table2.project_id
            AND Table1.created_date < DATEADD(month, 1, Table2.month_start_date)
        ORDER BY Table1.created_date DESC
    ) AS Durations
;

确保Table1(project_id, created_date) include (duration)上有索引。否则,表现会很差。