SQL给定日期的当前状态(FOR循环)

时间:2014-04-08 02:46:38

标签: sql sql-server-2008-r2

为简单起见,假设我有一个包含三个字段的视图

date_in (date)
Container (varchar)
date_out (date)

现在,如果date_in小于或等于给定日期且date_out为null或大于给定日期,则容器为IN。现在我试图计算给定时间段内的容器。在两个值STARTDATE和ENDDATE之间的伪代码中,它将类似于

FOR X =STARTDATE, X<= ENDDADE, X++ {
if date_in <=X and date_out>x
count (container) 
}

或更接近SQL:

declare  @startdate date,
@d date;
set  @startdate = '1/01/2014'
set @d = @startdate
"FOR on the @d variable would go here" {



select @d as SNAP_DATE, count (container) where date_in <@d 
and (date_out is null or   date_out> @d)

}

这可能很简单 - 我想我可以创建一个新表并手动执行多个SELECT INTO(以及稍后从这个新表中查询)但它不是非常优雅的解决方案。

编辑:只是为了精确 - 最后我希望有类似的东西:

DATE      Count
1/02/2014   10
2/02/2014   15
 ...
7/03/2014   19

2 个答案:

答案 0 :(得分:0)

您可以按程序执行此操作:

  1. 使用while循环从开始日期结束日期结束日期。
  2. 使用表变量存储每个日期计数对。
  3. 从表变量中选择以获取汇总结果。

    declare @start date = '1/01/2014'
    declare @end date = '7/03/2014'
    declare @tbl table(Date date, Count int)
    
    while(@start < @end)
     begin
      insert into @tbl
      select @start, count(*)
      from your_view
      where (in_date < @start) 
      and ((out_date is null) or (out_date > @start))
    
      set @start = dateadd(day, 1, @start)
     end
    
    select * from @tbl
    

答案 1 :(得分:0)

您可以执行以下操作。它使用数字表,可以是真实的或派生的表。它包含整数行。您需要一个以0开头的表,并且有足够的值来覆盖您的日期范围。有关数字表的更多信息,请查看here

DECLARE @StartDate DATE = '1/2/2014'
DECLARE @EndDate DATE = '1/4/2014'

SELECT DATEADD(d, n.num, @StartDate) AS DATE, COUNT(*) AS COUNT
FROM Numbers n
JOIN MyView mv ON mv.date_in < DATEADD(d, n.num, @StartDate)
    AND (mv.date_out IS NULL OR mv.date_out > DATEADD(d, n.num, @StartDate))
WHERE DATEADD(d, n.num, @StartDate) BETWEEN @StartDate AND @EndDate
GROUP BY DATEADD(d, n.num, @StartDate)
ORDER BY DATEADD(d, n.num, @StartDate)

数字表中的数字将转换为日期范围之间的日期列表。每个日期都会根据您需要的条件加入您的视图。