MS Access SQL - 一个工作周内当前打开的记录数

MS Access SQL - Count of Records that are Currently Open During a Workweek

我有一个记录集包含

 unique ID
 open date
 closed date

我想要一个查询来查找在每个工作周(每年 52 个工作周)期间处于活动状态的记录数。数据跨越数年,因此工作周不会是唯一的,每年从 1-52 重复。

一些伪代码如下所示:

 CountIf( ((OpenDate >= Workweek) & (ClosedDate >= WorkWeek)) 
         OR ((OpenDate >= Workweek) & IsNull(ClosedDate)) )

最终结果将是 table,其中包含 year/workweek 的年份、工作周数和活动记录数。

我有一个查询让我在一个工作周内打开:

SELECT Year([TABLE].[OpenedDate]) AS [Year], DatePart('ww',TABLE.[OpenedDate])
AS [Work Week], Count(TABLE.[ID]) AS [Count Of IDs Opened]
FROM TABLE
GROUP BY Year([TABLE].[OpenedDate]), DatePart('ww',TABLE.[OpenedDate])
ORDER BY Year([TABLE].[OpenedDate]), DatePart('ww',TABLE.[OpenedDate]);

对于 Closed 也有类似的,但我只是想不通如何在每个工作周内保持活跃。

编辑添加:

示例数据:

No  Opened Date Closed Date
1   20-Apr-15   23-Apr-15
2   22-Apr-15   04-May-15
3   27-Apr-15   01-May-15
4   29-Apr-15   04-May-15
5   29-Apr-15   05-Jun-15
6   04-May-15   20-May-15
7   04-May-15   07-May-15
8   05-May-15   20-May-15
9   05-May-15   20-May-15
10  06-May-15   20-May-15
11  06-May-15   20-May-15
12  06-May-15   20-May-15
13  07-May-15   20-May-15
14  11-May-15   26-May-15
15  11-May-15   26-May-15
16  13-May-15   26-May-15
17  18-May-15   26-May-15
18  20-May-15   01-Jun-15
19  21-May-15   03-Jun-15
20  12-Oct-15   07-Jul-16
21  02-Nov-15   26-Jul-17
22  06-Nov-15   30-Nov-15
23  09-Nov-15   26-Jul-17
24  08-Feb-17   05-May-17
25  13-Feb-17   
26  13-Feb-17   14-Aug-17
27  07-Mar-17   17-Mar-17

你需要一个包含所有年份和周数的 table,我们称它为 allYears: {Year, Week}

另外我猜你有一个主要的 table 作为你的记录,我们称它为 stores 来给它一些背景信息。否则你会:

SELECT DISTINCT ID FROM `active_stores`

最终您的活动记录将是 active_stores

那么您的查询是:

SELECT allYears.Year,
       stores.ID,
       COUNT([active_stores].ID) as total_active_weeks
FROM allYears, stores
LEFT JOIN active_stores
  ON allYears.Year = Year([active_stores].[OpenedDate])
 AND allYears.Week >= DatePart('ww',[active_stores].[OpenedDate])
 AND allYears.Week <= DatePart('ww',[active_stores].[ClosedDate])
 AND stores.ID = [active_stores].ID
GROUP BY allYears.Year,
         stores.ID

考虑按 OpenedDateClosedDate 同一周计算 active 条记录的条件聚合.为了便于阅读,下面夸大了缩进。

SELECT Year(t.[OpenedDate]) AS [Year], 
       DatePart('ww', t.[OpenedDate]) AS [Work Week], 

       SUM(IIF(((
                DatePart('ww', t.[OpenedDate]) = [Work Week] AND
                DatePart('ww', t.[ClosedDate]) = [Work Week])
               ) OR
               (
                DatePart('ww', t.[OpenedDate]) = [Work Week] AND
                t.[ClosedDate] IS NULL
               ),
           1,
           0)) AS [Count Of Active IDs]

FROM myTable t
GROUP BY Year(t.[OpenedDate]), DatePart('ww', t.[OpenedDate])
ORDER BY Year(t.[OpenedDate]), DatePart('ww', t.[OpenedDate]);

为了测试上面的内容,这里是单元级(非聚合)查询:

SELECT Year(t.[OpenedDate]) AS [Year], 
       DatePart('ww', t.[OpenedDate]) AS [Work Week], 

       t.[OpenedDate],     
       t.[ClosedDate],

       IIF(((
             DatePart('ww', t.[OpenedDate]) = [Work Week] AND
             DatePart('ww', t.[ClosedDate]) = [Work Week])
            ) OR
            (
             DatePart('ww', t.[OpenedDate]) = [Work Week] AND
             t.[ClosedDate] IS NULL
            ),
           1,
           0) AS [Active ID]

FROM myTable t

所以花了一些时间,但我结合此处发布的解决方案解决了我自己的问题。 我用 4 列制作了 table:

tbl_WorkWeeks
 cYear
 cWorkWeek
 FirstDay
 LastDay

我用 2010-2030 年、工作周 1-52(或 53,根据需要)、给定工作周的第一天和给定工作周的最后一天填充它。

然后我运行这个查询:

SELECT tbl_WorkWeeks.cYear, tbl_WorkWeeks.cWorkweek,
    tbl_WorkWeeks.FirstDay, tbl_WorkWeeks.LastDay,
    Sum(
        IIf(
            (
                ([tbl_MyDataTable].[OpenedDate] <= [tbl_WorkWeeks].[LastDay])
            AND (
                (([tbl_MyDataTable].[ClosedDate] >= [tbl_WorkWeeks].[FirstDay])
                 OR
                 ([tbl_MyDataTable].[ClosedDate] Is Null))
                )
            )
        ,1,0)
    ) AS [Active RecordID]
 FROM tbl_WorkWeeks, tbl_MyDataTable
 WHERE [tbl_MyDataTable].[RecordID] Is Not Null AND [tbl_WorkWeeks].[FirstDay] <= Now()
 GROUP BY tbl_WorkWeeks.cYear, tbl_WorkWeeks.cWorkweek, tbl_WorkWeeks.FirstDay, tbl_WorkWeeks.LastDay
 ORDER BY tbl_WorkWeeks.cYear, tbl_WorkWeeks.cWorkweek;

感谢大家的帮助。