Как выполнить ETL на BigQuery, избегая дублирования? - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть таблица продуктов: id createdOn UpdatedOn и еще 76 столбцов.

createdOn UpdatedOn являются TIMESTAMP. createdOn - это поле раздела.

Каждый ETL загружает записи из хранилища в таблицу продуктов (приложение).

После окончания ETL у меня есть дубликаты в таблице продуктов.

Пример:

id  createdOn,                    updatedOn,                stock, status
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10    5
3   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10     5
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10     5
3   2018-09-14 14:14:24.305676   2018-09-15 10:00:00.000000  7     5

Я хочу удалить дубликаты id s. Запись с самой последней updatedOn должна остаться, остальные должны быть удалены.

Я действовал согласно предложению здесь: Google BQ - как сохранить существующие данные в таблицах? Это мой запрос:

   DELETE FROM `storage.prodcuts` AS d
   WHERE (SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id ORDER BY updatedOn DESC)
           FROM `storage.prodcuts` AS d2
           WHERE d.id = d2.id ) > 1;  

Это не работает:

Ошибка: коррелированные подзапросы, которые ссылаются на другие таблицы, не являются поддерживается, если они не могут быть декоррелированы, например, путем преобразования их в эффективное объединение.

Также пробовал:

 delete FROM `storage.prodcuts` as p
  ( SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id  order by updatedOn DESC) as rn , id FROM `storage.prodcuts` ) as t
WHERE t.rn> 1 and p.id=t.id;  

Дает:

Синтаксическая ошибка: неожиданно "(" в [3: 7]

Я полагаю, что BigQuery хочет, чтобы я присоединился между delete table и row_number таблицей (хотя она такая же)? как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Если у вас нет строк с дублирующимися парами (id, updatedOn) или вы можете разрешить такие дубликаты другими способами, вы можете сделать что-то простое, как показано ниже:

DELETE FROM `storage.prodcuts` AS d
WHERE EXISTS (SELECT 1 FROM `storage.prodcuts` p2 
              WHERE p2.id = d.id AND p2.updatedOn > d.updatedOn)

Но изС точки зрения удобства обслуживания, решение Pentium10 с использованием двух таблиц, я думаю, намного лучше.

0 голосов
/ 17 сентября 2018

Ведение двух таблиц, одна из которых у вас есть сейчас: все внутри, есть другая таблица, которая является версией очистки, вы можете MERGE из 1-й в 2-ю таблицу только на основе столбца id.Таким образом, последняя строка будет во второй таблице, и с помощью оператора MERGE она будет постоянно перезаписываться.

Теперь вы можете даже Запланировать запросы , чтобы ваши операторы MERGE могли выполняться автоматически каждые X раз.

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