复制记录以填补 Google BigQuery 中日期之间的空白

Posted

技术标签:

【中文标题】复制记录以填补 Google BigQuery 中日期之间的空白【英文标题】:Duplicating records to fill gap between dates in Google BigQuery 【发布时间】:2016-08-13 04:15:00 【问题描述】:

所以我找到了类似的资源来解决如何在 SQL 中执行此操作,如下所示: Duplicating records to fill gap between dates

我知道 BigQuery 可能不是执行此操作的最佳位置,因此我正在尝试看看是否可行。当尝试运行上面链接中的某些方法时,我遇到了困难,因为 BigQuery 不支持某些功能。

如果存在数据结构如下的表:

    MODIFY_DATE             SKU         STORE   STOCK_ON_HAND
    08/01/2016 00:00:00     1120010     21      100
    08/05/2016 00:00:00     1120010     21      75
    08/07/2016 00:00:00     1120010     21      40

如何在 Google BigQuery 中构建一个查询,生成如下所示的输出?重复给定日期的值,直到其间日期的下一次更改:

    MODIFY_DATE             SKU         STORE   STOCK_ON_HAND
    08/01/2016 00:00:00     1120010     21      100
    08/02/2016 00:00:00     1120010     21      100
    08/03/2016 00:00:00     1120010     21      100
    08/04/2016 00:00:00     1120010     21      100
    08/05/2016 00:00:00     1120010     21      75
    08/06/2016 00:00:00     1120010     21      75
    08/07/2016 00:00:00     1120010     21      40

我知道我需要生成一个包含给定范围内所有日期的表格,但我很难理解是否可以这样做。有什么想法吗?

【问题讨论】:

【参考方案1】:

如何在 Google BigQuery 中构建一个查询,生成如下所示的输出?重复给定日期的值,直到两者之间的日期的下一次更改

见下例

SELECT
  MODIFY_DATE, 
  MAX(SKU_TEMP) OVER(PARTITION BY grp) AS SKU,
  MAX(STORE_TEMP) OVER(PARTITION BY grp) AS STORE,
  MAX(STOCK_ON_HAND_TEMP) OVER(PARTITION BY grp) AS STOCK_ON_HAND,
FROM (
  SELECT
    DAY AS MODIFY_DATE, SKU AS SKU_TEMP, STORE AS STORE_TEMP, STOCK_ON_HAND AS STOCK_ON_HAND_TEMP,
    COUNT(SKU) OVER(ORDER BY DAY ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS grp,
  FROM (
    SELECT DATE(DATE_ADD(TIMESTAMP("2016-08-01"), pos - 1, "DAY")) AS DAY
    FROM (
         SELECT ROW_NUMBER() OVER() AS pos, *
         FROM (FLATTEN((
         SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP("2016-08-07"), TIMESTAMP("2016-08-01")), '.'),'') AS h
         FROM (SELECT NULL)),h
    )))
  ) AS DATES
  LEFT JOIN (
    SELECT DATE(MODIFY_DATE) AS MODIFY_DATE, SKU, STORE, STOCK_ON_HAND 
    FROM 
      (SELECT "2016-08-01" AS MODIFY_DATE, "1120010" AS SKU, 21 AS STORE, 75 AS STOCK_ON_HAND),
      (SELECT "2016-08-05" AS MODIFY_DATE, "1120010" AS SKU, 22 AS STORE, 100 AS STOCK_ON_HAND),
      (SELECT "2016-08-07" AS MODIFY_DATE, "1120011" AS SKU, 23 AS STORE, 40 AS STOCK_ON_HAND),
  ) AS TABLE_WITH_GAPS
  ON TABLE_WITH_GAPS.MODIFY_DATE = DATES.DAY
)
ORDER BY MODIFY_DATE

【讨论】:

感谢 Mikhail,这可以作为示例,但需要针对日期和 SKU 的动态范围进行一些调整。伟大的工作人员,欣赏对它的洞察力。 嘿@Mikhail,我的问题与原始发帖人完全相同,当我的表中只有一个 SKU 时,您的回答工作正常,但是当我有多个 SKU 和商店时,需要要填写每个日期,您的查询实际上不起作用。另外,我想看看标准 SQL 中的解决方案。你会更新你的答案吗?谢谢! @GustavoDaniloMachado - 我的回答是针对特定问题“量身定制”的,并不适合所有情况。如果您发布新问题 - 我将非常乐意回答您的问题 :o) 我看到了@MikhailBerlyant,这是我发布的:***.com/questions/42097764/…【参考方案2】:

我需要生成一个表格,其中包含给定范围内的所有日期,但我很难理解是否可以这样做。有任何想法吗?

SELECT DATE(DATE_ADD(TIMESTAMP("2016-08-01"), pos - 1, "DAY")) AS DAY
FROM (
     SELECT ROW_NUMBER() OVER() AS pos, *
     FROM (FLATTEN((
     SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP("2016-08-07"), TIMESTAMP("2016-08-01")), '.'),'') AS h
     FROM (SELECT NULL)),h
)))

【讨论】:

以上是关于复制记录以填补 Google BigQuery 中日期之间的空白的主要内容,如果未能解决你的问题,请参考以下文章

复制记录以填补日期之间的空白

Google BigQuery:将 ExecuteQuery 结果以 json 格式上传到 Google Cloud Storage

标准 sql 查询以获取与另一个表匹配的记录字段(Google BigQuery)

Google BigQuery 选择记录中所有嵌套字段的总和

在bigquery中以编程方式更新/插入数据

使用交易复制 BigQuery 中的内部促销报告