2013-12-09 103 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