Как удалить дублированную строку по метке времени в BigQuery? - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть таблица продуктов со следующей схемой:

id  createdOn, updatedOn, stock, status

createdOn & updatedOn являются TimeStamp.

createdOn - поле для паратирования.

Скажите, что у меня есть данные:

id  createdOn,                    updatedOn,                stock, status
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10    5
2   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  5     12
3   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10     5

У меня есть ETL, который добавляет новые строки в эту таблицу. когда ETL закончен, у меня может возникнуть ситуация, когда один и тот же id имеет более 1 строки.

Например:

id  createdOn,                    updatedOn,                stock, status
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10    5
2   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  5     12
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

Я хочу получить запрос, который будет выполняться по таблице, и убедиться, что у каждого идентификатора есть только 1 строка - строка с MAX(updatedOn) должна остаться. Для MAX(updatedOn) для идентификатора может быть более 1 строки - в этом случае это гарантирует, что они идентичны, потому что, если бы они не были такими, поле updatedOn было бы изменено.

После выполнения запроса таблица будет выглядеть так:

id  createdOn,                    updatedOn,                stock, status
2   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  5     12
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

Как мне написать запрос, который эффективно выполняет это?

Я знаю, это должно быть что-то вроде:

DELETE FROM products
WHERE id NOT IN
(
    SELECT MAX(id)
    FROM products
    GROUP BY id
)

Однако это не сработает ... У меня нет поля автоинкремента, чтобы различать строки.

Как я могу решить это?

Ответы [ 3 ]

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

Я настоятельно рекомендую вам просто создать новую таблицу:

create table correct_table as
    select distinct id, createdOn, updatedOn
    from etl_table;

Сила BigQuery заключается в обработке данных.Я пытаюсь найти другие решения (например, копирование таблиц), когда обновления или удаления кажутся необходимыми.

Возможно, вы захотите переосмыслить свою обработку.Просто пусть ETL загрузит таблицу с новыми строками.Затем используйте BigQuery, чтобы вставить новые строки, которые еще не существуют.Другими словами, вставка строк, а затем их удаление - не самый лучший способ.

0 голосов
/ 04 ноября 2018

Я думаю, что Гордон Линофф прав, вариант использования BigQuery не в том, чтобы манипулировать данными и постоянно обновлять уже существующие строки. Это очень много, чтобы заполнить, а затем проанализировать эти данные .

В любом случае, этот запрос вернет только нужные вам строки:

SELECT DISTINCT id, createdOn,  updatedOn,  stock,  status
FROM `project.dataset.maxtimestamp` AS t1
INNER JOIN (SELECT id AS i2, MAX(updatedOn) AS up
FROM `project.dataset.maxtimestamp`
GROUP BY id) AS t2
ON t1.id = t2.i2 AND t1.updatedOn = t2.up

Как и этот, который вы уже нашли:

SELECT id,  createdOn,  updatedOn,  stock,  status
FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY createdOn, id ORDER BY updatedOn desc) AS rn
       FROM `training-wave-12-vmarin.asdf.duplicated_timestamp` AS t2)
WHERE rn>1

Во всяком случае, не уверен, насколько он оптимизирован ...

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

использование row_number функция

DELETE FROM products
WHERE STRUCT(id,createdOn,stock) IN (
        select id,createdOn,stock from
        (SELECT id,createdOn,stock,
          ROW_NUMBER()
                  OVER (PARTITION BY createdOn,stock,updatedOn order by id) as rn from products
                  ) t where rn>1
         ) 

Другой способ, которым вы можете следовать, скорее удалить, вы можете заменить свою таблицу

CREATE OR REPLACE TABLE products AS
SELECT * EXCEPT(rn)
FROM (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY createdOn,stock,updatedOn order by id) rn
  FROM products
) 
WHERE rn> 1 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...