SQL:如何通过重新索引日期进行查询以计算通用的每日预测

SQL: How to Query by Reindexing Dates to Calculate Generic Daily Prognosis

我试图了解我的观察结果相对于预期时间的及时进展,无论它们的预期日期如何。因此,我想重新索引每个观察值并生成一个从第 0 天(在 expected 天)开始的列表,然后再向前计算 10 天(任意)。

我正在 BigQuery 中对此进行测试:

CREATE TABLE `db.tbl` (
  id INTEGER,
  expected DATE,
  actual DATE
)
INSERT INTO `db.tbl`
( id , expected , actual )
VALUES
( 1 , '2022-01-01' , '2022-01-02' ),
( 2 , '2022-01-11' , '2022-01-20' ),
( 3 , '2022-01-21' , '2022-01-20' )

因此,第一行表示第 0 天(2022-01-01)“缺失”/“迟到”/“未准时”的观察结果,然后是第 1 天“准时”的观察结果(2022-01-02) 直到我的 window 兴趣结束(第 10 天)。

第二行表示从第 0 天 (2022-01-11) 到第 8 天 (2022-01-19)“迟到”并且此后“准时”的观察结果。

第三行表示早期观察到的观察结果,因此从第 0 天到第 10 天应该“准时”。

我希望结果是:

day  count fraction
  0      1     0.33
  1      2     0.67
  2      2     0.67
  3      2     0.67
  4      2     0.67
  5      2     0.67
  6      2     0.67
  7      2     0.67
  8      2     0.67
  9      3     1.00
 10      3     1.00

这可以用 SELECT 语句实现吗?

考虑以下

select day, sum(ontime) cnt, round(avg(ontime),2) fraction
from (
  select day, if(dt < actual, 0, 1) ontime
  from your_table, 
  unnest(generate_array(0,10)) day
  left join unnest(generate_date_array(expected, actual)) dt with offset as day 
  using(day)
)
group by day

如果应用于您问题中的样本数据

with your_table as (
  select 1 id, date '2022-01-01' expected, date '2022-01-02' actual union all
  select 2, '2022-01-11' , '2022-01-20' union all
  select 3, '2022-01-21' , '2022-01-20' 
)

输出是

CREATE TEMP TABLE sample (
  id INTEGER,
  expected DATE,
  actual DATE
);
INSERT INTO sample
( id , expected , actual )
VALUES
( 1 , '2022-01-01' , '2022-01-02' ),
( 2 , '2022-01-11' , '2022-01-20' ),
( 3 , '2022-01-21' , '2022-01-20' );


WITH observations AS (
  SELECT day, COUNTIF(v = '1') AS count, (SELECT COUNT(id) FROM sample) AS total
    FROM sample,
         UNNEST([IF(DATE_DIFF(actual, expected, DAY) < 0, 0, DATE_DIFF(actual, expected, DAY))]) diff,
         UNNEST(SPLIT(REPEAT('0', diff) || REPEAT('1', 10 - diff), '')) v WITH OFFSET day
   GROUP BY 1
)
SELECT day, count, ROUND(count / total, 2) AS fraction
  FROM observations;

输出: