如何在bigquery中转换年周字段

时间:2018-06-21 17:43:17

标签: sql google-bigquery

这个问题是关于在bigquery中移动年-周字段的值。

run_id    year_week    value
 0001       201451       13
 0001       201452       6
 0001       201503       3
 0003       201351       8
 0003       201352       5
 0003       201403       1

每周在这里的范围可以从01到53。例如,2014年的上周为201452,而2015年的上周为201553。

现在,我想将每个year_week中每个run_id的值移动5周。对于星期,没有值,则假定它们的值为0。例如,上面示例表的输出应如下所示:

run_id    year_week    value
 0001       201504       13
 0001       201505       6
 0001       201506       0
 0001       201507       0
 0001       201508       3
 0003       201404       8
 0003       201405       5
 0003       201406       0
 0003       201407       0
 0003       201408       1

输出的解释:在上表run_id 0001中,year_week 201504的值为13,因为在输入表中,year_week 201451的值为13是201504之前的5周。

我可以通过创建从year_week到转换后的year_week的映射,然后进行联接以获取输出的方式以编程方式创建表,但是我想知道是否还有其他方法可以执行只需使用sql即可。

2 个答案:

答案 0 :(得分:3)

#standardSQL
WITH `project.dataset.table` AS (
  SELECT '001' run_id, 201451 year_week, 13 value UNION ALL
  SELECT '001', 201452, 6 UNION ALL
  SELECT '001', 201503, 3 
), weeks AS (
  SELECT 100 * year + week year_week
  FROM UNNEST([2013, 2014, 2015, 2016, 2017]) year, 
  UNNEST(GENERATE_ARRAY(1, IF(EXTRACT(ISOWEEK FROM DATE(1+year,1,1)) = 1, 52, 53))) week
), temp AS (
  SELECT i.run_id, w.year_week, d.year_week week2, value
  FROM  weeks w 
  CROSS JOIN (SELECT DISTINCT run_id FROM `project.dataset.table`) i
  LEFT JOIN `project.dataset.table` d
  USING(year_week, run_id)
)
SELECT * FROM (
  SELECT run_id, year_week, 
    SUM(value) OVER(win) value
  FROM temp
  WINDOW win AS (
    PARTITION BY run_id ORDER BY year_week ROWS BETWEEN 5 PRECEDING AND 5 PRECEDING
  )
)
WHERE NOT value IS NULL
ORDER BY run_id, year_week

结果为

Row     run_id      year_week       value    
1       001         201504          13   
2       001         201505          6    
3       001         201508          3    

如果您需要“保留”零行-只需更改下面的部分

  SELECT i.run_id, w.year_week, d.year_week week2, value
  FROM  weeks w 

  SELECT i.run_id, w.year_week, d.year_week week2, IFNULL(value, 0) value
  FROM  weeks w 

    SUM(value) OVER(win) value
  FROM temp

    SUM(IFNULL(value, 0)) OVER(win) value
  FROM temp

答案 1 :(得分:2)

如果表中所有年份-星期都有数据,则可以执行以下操作:

-f

如果您没有年份表,那么我建议您创建一个这样的表,以便您可以进行此类操作-或更通用的日历表。