在范围列表中选择日期

时间:2013-12-09 10:06:51

标签: sql tsql

我有记录表,每行包含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

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

例如,它应该如下所示:

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)

但实际上我不知道如何只获得第一个日期。

1 个答案:

答案 0 :(得分: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