计算每个星期日(或一周的任何一天)的项目

时间:2013-10-14 13:21:29

标签: sql sql-server sql-server-2008

我有一个我想设置的查询,它基本上会列出第1列中的所有星期日,然后在第2列中列出每个日期,它会计算在该星期日(列)中“打开”的所有项目1个日期,实际上可能是一周中的某一天,重要的是获取每周打开项目的快照)。 e.g。

Date               open items
------------       ---------------
2013-10-13         1650
2013-10-06         1554
2013-09-29         1788
(cont down)

我的数据库记录每个项目的openDate和closedDate。因此,第2列需要以下内容:计算具有开放日期< =第1列日期的总项目,并且在关闭日期中具有NULL(项目仍然打开)或closedDate> =第1列日期。

我希望你能提供帮助。我认为这个查询超出了我目前有限的SQL权限。

非常感谢 ROBO-泰德

1 个答案:

答案 0 :(得分:0)

在SQL Server中,您可以执行以下操作

create procedure dbo.DoSummary(@startdate datetime, @enddate datetime, @dow int)
as 
set DateFIRST @dow;

with cte (date) as (
    select case
            when datepart(dw, @startdate) = 1 then @startdate
            else dateadd(d,8-datepart(dw, @startdate), @startdate)
            end as date
    union all
    select dateadd(d,7, date)
    from cte where dateadd(d,7,date) < @enddate
)
select 
    cte.date, count(items.opened) as [Open]
from 
    cte left outer join items on cte.date >= items.opened and cte.date < coalesce(items.closed, dateadd(d,1,cte.date))
    group by cte.date

然后你执行

dbo.DoSummary '2001-01-01','2001-07-01', 7 

执行。

最后一个参数@dow控制使用星期几,7是星期日

UPDATE 由于OP无权创建存储过程,因此您只需将函数体用作原始Sql即可。我将举一个使用c#中的ADO的例子。

using (var conn = new SqlConnection(connectionString)) {
   using (var cmd = conn.CreateCommand()) {
     cmd.CommandText = "set DateFIRST @dow; " +
                       "with cte (date) as ( " +
                       "select case " +
                       "when datepart(dw, @startdate) = 1 then @startdate "+
                       "else dateadd(d,8-datepart(dw, @startdate), @startdate) " +
                       "end as date " +
                       "union all " +
                       "select dateadd(d,7, date) " +
                       "from cte where dateadd(d,7,date) < @enddate " +
                       ") " +
                       "select cte.date, count(items.opened) as [Open] " +
                       "from cte " +
                       "left outer join items " +
                       "on cte.date >= items.opened " +
                       "and cte.date < coalesce(items.closed, dateadd(d,1,cte.date)) "+
                       "group by cte.date ";
    cmd.Parameters.AddWithValue("@startdate", new DateTime(2001,01,01));
    cmd.Parameters.AddWithValue("@enddate", new DateTime(2001,04,01));
    cmd.Parameters.AddWithValue("@dow", 7);
    using (var reader = cmd.ExecuteReader()) {
      while (reader.Read()) {
         // do somthing with data
      }
    }
  }
}