【问题标题】:how to show every open item by weeks如何按周显示每个未清项目
【发布时间】:2019-02-21 02:59:32
【问题描述】:

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

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

Item ID|   Opening_date | Closed_date

我需要的请求是:一年中按周分组的每个正在进行的项目。 答案应该是这样的

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

所以我尝试了'with cte as',但我无法得到我想要的东西

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

用示例编辑:

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

确定我使用 select datepart(ww, date) 的星期 正在进行的项目是项目打开而不是关闭。 有了这些值,我想要的结果是

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

【问题讨论】:

  • 你能分享一下你已经尝试过的吗?
  • 请发布更多示例数据以及相应的预期结果

标签: sql sql-server


【解决方案1】:

这可以通过参考涵盖您的数据集的适当周的列表来实现。这最容易通过使用日期表来实现,但如果不可用,通过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】:

您是否需要考虑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])

【讨论】:

  • 对不起,也许我不够清楚,但根据您的要求,我只能得到我打开仍然打开的项目的那一周。例如在 2 月(可能是第 5、6、7、8 周),我每周都会看到 3 件商品
【解决方案3】:

我会按周扩展数据,然后聚合:

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);

【讨论】:

  • 这看起来更容易,但我有一个错误:消息 530,级别 16,状态 1,第 1 行语句终止。在语句完成之前,最大递归 100 已用完。
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多