将事件日志汇总到每周概览

Aggregate event log to weekly overview

假设我有以下 table:

Table A: Event Log

ID        Step        WeekArrived        WeekCompleted
-------------------------------------------------------
1         A           1                  1
1         B           1                  3
2         B           3                  3

所以在第 1 周,案例 1 出现了。对于这种情况,步骤 A 在第 1 周完成,但步骤 B 未完成。步骤 B 在第 3 周完成。案例 2 也在第 3 周到达,步骤 B 在同一周完成(此案例不需要步骤 A)。

我想将此事件日志汇总到每周每步概览中,如下所示:

Table B: Weekly Overview

Week      Step        In                 Backlog               Out
------------------------------------------------------------------
1         A           1                  0                     1
1         B           1                  1                     0
2         A           0                  0                     0
2         B           0                  1                     0
3         A           0                  0                     0
3         B           1                  0                     2

对于每周 X 和步骤 Y,此 table 显示:

如何从 table A 到 table B?

您需要一个周列表,以便评估该周是否有数据。

在 sql 服务器中,例如像这样的东西 How to generate a range of numbers between two numbers?

然后你加入你的脚步。如果你也有单独的 table 作为步骤,效果会更好。

SELECT weeks.week_id, steps.step, 
       CASE WHEN s_in.WeekArrived IS NULL THEN 0 ELSE 1 END as step_in,
       CASE WHEN s_completed.WeekCompleted IS NULL THEN 0 ELSE 1 END as step_out,
       CASE WHEN s_pending.WeekArrived IS NULL THEN 0 ELSE 1 END as step_pending
FROM weeks
CROSS JOIN (SELECT DISTINCT step
            FROM event_log) as steps

LEFT JOIN event_Log as s_in
  ON weeeks.week_id = e.WeekArrived
 AND steps.step = e.step

LEFT JOIN event_Log as s_completed
  ON weeeks.week_id = e.WeekCompleted
 AND steps.step = e.step

LEFT JOIN event_Log as s_pending
  ON weeeks.week_id > e.WeekArrived
 AND weeeks.week_id < e.WeekCompleted
 AND steps.step = e.step

注意:不知道 back log 是什么。

首先,你需要一种获取week_ids列表的方法,我用的是Teradata的系统日历。然后是 Cross Join 加上一些条件聚合:

SELECT week_id, step,
   Sum(CASE WHEN week_id = WeekArrived THEN 1 ELSE 0 END) AS "in",
   Sum(CASE WHEN week_id >= WeekArrived AND week_id < WeekCompleted THEN 1 ELSE 0 END) as "backlog",
   Sum(CASE WHEN week_id = WeekCompleted THEN 1 ELSE 0 END) AS "out"
FROM
 ( -- get a lsit of week ids
   SELECT day_of_calendar AS week_id
   FROM sys_calendar.CALENDAR
   WHERE week_id
   -- calculate the range of week ids
   BETWEEN (SELECT Min(WeekArrived) FROM event_log)
       AND (SELECT Max(WeekCompleted) FROM event_log)
 ) AS weeks
CROSS JOIN
 (
   SELECT  *
   FROM event_log
 ) AS steps
GROUP BY week_id, step
ORDER BY week_id, step