заполнить данные, вставив записи даты в Big Query - PullRequest
2 голосов
/ 25 апреля 2020

У меня есть таблица с отсутствующими записями даты в большом запросе, и я хотел бы сначала вставить отсутствующие записи даты в таблицу и вставить оценку из предыдущей записи даты, как этого можно достичь в большом запросе?

Текущий образец таблицы:

Row   date      timeStamp   score   
1   2018-01-21  1516492800  0.44013312375
2   2018-01-22  1516579200  0.3821605743
3   2018-01-24  1516752000  0.3397971282666667

Ожидаемый вид таблицы:

Row   date      timeStamp   score   
1   2018-01-21  1516492800  0.44013312375
2   2018-01-22  1516579200  0.3821605743
3   2018-01-23  1516665600  0.3821605743
4   2018-01-24  1516752000  0.3397971282666667

В основном, поскольку на дату 2018-01-23 запись отсутствовала, мы вставляем запись и выбираем значение оценки из предыдущая дата.

Ответы [ 2 ]

2 голосов
/ 25 апреля 2020

Ниже для BigQuery Standard SQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2018-01-21' date, 1516492800 timeStamp, 0.44013312375 score UNION ALL
  SELECT '2018-01-22', 1516579200, 0.3821605743 UNION ALL
  SELECT '2018-01-24', 1516752000, 0.3397971282666667 
)
SELECT date, 
  UNIX_SECONDS(TIMESTAMP(date)) AS timeStamp,
  LAST_VALUE(score IGNORE NULLS) OVER(ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS score
FROM (
  SELECT MIN(date) min_date, MAX(date) max_date
  FROM `project.dataset.table`
), UNNEST(GENERATE_date_ARRAY(min_date, max_date)) date
LEFT JOIN `project.dataset.table`
USING(date)
ORDER BY date   

с результатом

Row date        timeStamp   score    
1   2018-01-21  1516492800  0.44013312375    
2   2018-01-22  1516579200  0.3821605743     
3   2018-01-23  1516665600  0.3821605743     
4   2018-01-24  1516752000  0.3397971282666667   
1 голос
/ 25 апреля 2020

Я бы подошел к этому только путем генерации массива даты для необходимых значений на строку :

WITH t AS (
       SELECT DATE '2018-01-21' date, 1516492800 timeStamp, 0.44013312375 score UNION ALL
       SELECT '2018-01-22', 1516579200, 0.3821605743 UNION ALL
       SELECT '2018-01-24', 1516752000, 0.3397971282666667 
      )
SELECT dte, 
       UNIX_SECONDS(TIMESTAMP(dte)) AS timeStamp,
       t.score
FROM (SELECT t.*, DATE_ADD(LEAD(date) OVER (ORDER BY date), INTERVAL -1 day) as to_date
      FROM t
     ) t CROSS JOIN
     UNNEST(GENERATE_date_ARRAY(date, COALESCE(to_date, date))) dte
ORDER BY dte  ;

Я почти уверен, что это имеет лучшие характеристики производительности при больших объемах данных , На самом деле я вчера предложил такой подход коллеге, пытающейся ускорить один из ее запросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...