2013-12-09 104 views
0

我有记录表,每行包含DATETIME列,它描述了何时将行装载到表中。我有CTE创建范围(计数是不同的)如下。在范围列表中选择日期

first_day_of_month    last_day_of_moth 
    ------------------------------------------------------- 
    2013-12-01 00:00:00.000  2013-12-31 23:59:59.000 
    2013-11-01 00:00:00.000  2013-12-31 23:59:59.000 
    2013-10-01 00:00:00.000  2013-12-31 23:59:59.000 
    2013-09-01 00:00:00.000  2013-12-31 23:59:59.000 
    2013-08-01 00:00:00.000  2013-12-31 23:59:59.000 

问:现在我想选择第一个表中最小DATETIME值在CTE创建的每个范围。我绝对不知道该怎么做。任何想法/链接表示赞赏。

例如,它应该是这样的:

2013-12-10 
2013-11-20 
2013-10-05 
2013-09-13 
2013-08-06 

UPD:日期或日期时间 - 不管它是

UPD2:我发现我可以使用情况一样加入我的表:

INNER JOIN source_monthes_dates ON 
    (load_timestamp >= first_day_of_month AND load_timestamp <= last_day_of_moth) 

但实际上我不知道如何才能获得peri的第一个日期OD。

+0

为什么范围重叠? – Szymon

+0

@Szymon这是我的错误。我修好了它。 –

回答

1

您可以使用此查询使用ROW_NUMBER()来获取最小值。 ranges是您的CTE的结果,table1是您有日期的其他表。

select x.somedate 
from 
    (select t.somedate, 
    ROW_NUMBER() OVER (PARTITION BY r.first_day_of_month, r.last_day_of_moth ORDER BY t.somedate) rownumber 
    from ranges r 
    inner join table1 t 
    on r.first_day_of_month <= t.somedate and r.last_day_of_moth >= t.somedate) x 
where x.rownumber = 1 

SQL Fiddle demo


如果你想获得的所有范围,包括只有那些符合范围和他人显示空天那,你可以加入ranges一次:

select ranges.first_day_of_month, ranges.last_day_of_moth, x.somedate 
from 
    ranges 
left join 
    (select t.somedate, r.first_day_of_month, r.last_day_of_moth, 
    ROW_NUMBER() OVER (PARTITION BY r.first_day_of_month, r.last_day_of_moth ORDER BY t.somedate) rownumber 
    from ranges r 
    inner join table1 t 
    on r.first_day_of_month <= t.somedate and r.last_day_of_moth >= t.somedate) x 
on x.first_day_of_month = ranges.first_day_of_month and x.last_day_of_moth = ranges.last_day_of_moth 
where isnull(x.rownumber, 1) = 1 

SQL Fiddle demo

+1

这有点神奇。谢谢,它按预期工作。 –

+0

有没有办法做到这一点,除了保留NULL值代替缺席值?即如果row_number = 1没有找到,则将NULL置于非空。我试图玩不同的JOIN类型,但没有任何运气。 –

+1

你可以留下连接范围表和这个查询,并且应该给你你需要的东西。我会在稍后回来。 – Szymon