Задача удаления дубликатов из таблицы BigQuery может быть решена разными способами. Рассмотрим несколько из них.
Используем ROW_NUMBER
Один из вариантов предполагает использование оконной функции ROW_NUMBER для удаления дубликатов.
Функция ROW_NUMBER присваивает каждой строке таблицы уникальный номер, который можно использовать для выборки только уникальных записей. Вот как выглядит код для удаления дубликатов с использованием ROW_NUMBER:
WITH cte AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY column1, column2, column3 ORDER BY column4) row_num
FROM
`mydataset.mytable`
)
DELETE FROM cte WHERE row_num > 1;
В этом коде используется Обобщенные табличные выражения (CTE), чтобы сначала присвоить каждой строке таблицы уникальный номер через функцию ROW_NUMBER. А затем удаляются все строки, у которых значение row_num больше 1, то есть все дубликаты.
В данном случае идет перезапись исходной таблицы. Но в случае, если в запрос закралась ошибка, вы рискуете потерять данные. Поэтому я рекомендую записывать результат скрипта в новую таблицу, а не удалять из исходной. После проверки новой таблицы, вы можете удалить данные в старой таблице и перенести уникализированные данные из новой.
Запрос с оператором DISTINCT
Другой вариант — это применение оператора DISTINCT, с помощью которого выбираются только уникальные записи из таблицы. Это проще, чем использование оконной функции ROW_NUMBER, но может быть менее эффективно для больших таблиц.
Кроме того, этот вариант не подойдет, если ваша таблица разбита на партиции.
Пример удаления дубликатов с использованием DISTINCT выглядит следующим образом:
CREATE OR REPLACE TABLE `mydataset.mytable_unique` AS
SELECT DISTINCT *
FROM `mydataset.mytable`;
В этом коде создается новая таблица mytable_unique которая содержит только уникальные записи из исходной таблицы mytable.
С функцией ARRAY_AGG
Еще один способ удаления дубликатов из таблицы BigQuery — это использование функции агрегирования ARRAY_AGG.
Предположим у нас есть таблица mydataset.mytable, и нам необходимо уникализировать ее по колонкам column1 и column2. Выполним следующий запрос:
SELECT a.* FROM (
SELECT ARRAY_AGG(
t ORDER BY t.column3 DESC LIMIT 1
)[OFFSET(0)] a
FROM `mydataset.mytable` t
GROUP BY column1, column2
);
В этом запросе выполняется агрегация данных в таблице mytable, используя функцию ARRAY_AGG. При этом создается массив значений из столбцов таблицы t.
Затем эти массивы группируются по значениям в колонках column1 и column2 и выбирается один элемент из каждой группы, имеющий наибольшее значение в колонке column3. Это происходит с помощью комбинации ORDER BY t.column3 DESC LIMIT 1 и [OFFSET(0)].
Наконец, результаты этой группировки и выбора наибольшего значения в column3 объединяются в выходные данные, которые возвращаются в качестве результата запроса. В этом случае выбираются все столбцы из таблицы t и возвращаются в результате запроса с помощью SELECT a.*.
Остаётся только сохранить результаты запроса в новую таблицу.