如何按周显示每个未清项目

时间:2018-09-17 08:16:31

标签: sql sql-server

大家好,如果我的英语不正确,请对不起。

我有一个3列多行的表>>

Item ID|   Opening_date | Closed_date

我需要的是:在一年中,每个进行中的项目都按周进行分组。 答案看起来应该是

week 1     45 ongoing item
week 2     32 ongoing item
...  
Week 37    64 ongoing item

所以我尝试了“使用cte as”,但是我无法获得想要的东西

谢谢您的帮助 最好的祝福 安托万

使用示例进行编辑:

414   |  2018-01-01  |  2018-05-01
416   |  2018-01-08  |  2018-05-01
417   |  2018-01-08  |  2018-04-01

确定我使用选择的星期几datepart(ww,date) 进行中的项目是未打开的项目。 有了这些值,我想要的结果就是

1   |  1  
2   |  3  
3   |  3  
...
27  |  3
28  |  2

3 个答案:

答案 0 :(得分:0)

您是否需要将Closed_date与一周结束日期进行比较?

SELECT DATEPART(week, [DATE]) as Week,
       SUM (CASE WHEN Closed_date IS NULL THEN 1 ELSE 0 END) as OnGoingItem
FROM   yourtable
GROUP BY DATEPART(week, [DATE])

答案 1 :(得分:0)

这可以通过参考涵盖您的数据集的适当周列表来实现。这可以通过使用日期表来最容易地实现,尽管如果不可用,则可以通过cte来生成一个:

declare @t table(id int, OpeningDate date, ClosingDate date);
insert into @t values
 (414,  '20180101',  '20180501')
,(416,  '20180108',  '20180501')
,(417,  '20180108',  '20180401')
;

declare @StartWeek date = (select dateadd(week,datediff(week,0,min(OpeningDate)),0) from @t);
declare @EndWeek date = (select dateadd(week,datediff(week,0,max(ClosingDate)),0) from @t);

with n(n) as (select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1)
    ,d(d) as (select top(datediff(week,@StartWeek,@EndWeek)+1) dateadd(week,row_number() over (order by (select null))-1,@StartWeek) from n n1,n n2,n n3,n n4,n n5)
select d.d as WeekStart
    ,count(t.id) as OpenItems
from d
    left join @t as t
        on t.OpeningDate <= d.d
            and (t.ClosingDate > d.d
                 or t.ClosingDate is null
                 )
group by d.d
order by d.d;

输出:

+---------------------+-----------+
|      WeekStart      | OpenItems |
+---------------------+-----------+
| 01.01.2018 00:00:00 |         1 |
| 08.01.2018 00:00:00 |         3 |
| 15.01.2018 00:00:00 |         3 |
| 22.01.2018 00:00:00 |         3 |
| 29.01.2018 00:00:00 |         3 |
| 05.02.2018 00:00:00 |         3 |
| 12.02.2018 00:00:00 |         3 |
| 19.02.2018 00:00:00 |         3 |
| 26.02.2018 00:00:00 |         3 |
| 05.03.2018 00:00:00 |         3 |
| 12.03.2018 00:00:00 |         3 |
| 19.03.2018 00:00:00 |         3 |
| 26.03.2018 00:00:00 |         3 |
| 02.04.2018 00:00:00 |         2 |
| 09.04.2018 00:00:00 |         2 |
| 16.04.2018 00:00:00 |         2 |
| 23.04.2018 00:00:00 |         2 |
| 30.04.2018 00:00:00 |         2 |
+---------------------+-----------+

如果数据集太大而无法快速执行,则可以使用其他稍微复杂的设计模式来提高查询效率。您可以在这里看到各种选项的精彩讨论:Aggregate for each day over time series, without using non-equijoin logic

答案 2 :(得分:0)

我将按周扩展数据,然后进行汇总:

with cte as (
      select opening_date, closed_date, opening_date as dte
      from yourtable
      union all
      select opening_date, closed_date, dateadd(week, 1, opening_date)
      from cte
      where dte < closed_date
     )
select datepart(week, dte), count(*)
from cte
where dte >= '2018-01-01' and dte < '2019-01-01'
group by datepart(week, dte)
order by min(dte)
option (maxrecursion 0);